/// <summary>
        /// Upload new text track file asynchronously
        /// </summary>
        /// <param name="fileContent">File content</param>
        /// <param name="videoId">VideoId</param>
        /// <param name="track">Track</param>
        /// <returns>New text track</returns>
        public async Task <TextTrack> UploadTextTrackFileAsync(IBinaryContent fileContent, long videoId, TextTrack track)
        {
            if (!fileContent.Data.CanRead)
            {
                throw new ArgumentException("fileContent should be readable");
            }
            if (fileContent.Data.CanSeek && fileContent.Data.Position > 0)
            {
                fileContent.Data.Position = 0;
            }

            TextTrack ticket = await GetUploadTextTrackTicketAsync(videoId, track);

            IApiRequest request = ApiRequestFactory.GetApiRequest();

            request.Method = Method.PUT;
            request.ExcludeAuthorizationHeader = true;
            request.Path = ticket.link;
            request.Headers.Add(Request.HeaderContentType, fileContent.ContentType);
            request.Headers.Add(Request.HeaderContentLength, fileContent.Data.Length.ToString());
            request.BinaryContent = await fileContent.ReadAllAsync();

            IRestResponse response = await request.ExecuteRequestAsync();

            CheckStatusCodeError(null, response, "Error uploading text track file.", HttpStatusCode.BadRequest);

            return(ticket);
        }
        private IApiRequest GenerateUploadTextTrackTicketRequest(long clipId, TextTrack track)
        {
            ThrowIfUnauthorized();

            IApiRequest request = ApiRequestFactory.GetApiRequest(AccessToken);

            request.Method = Method.POST;
            request.Path   = Endpoints.TextTracks;
            request.UrlSegments.Add("clipId", clipId.ToString());

            if (track != null)
            {
                request.Query.Add("active", track.active.ToString().ToLower());
                if (track.name != null)
                {
                    request.Query.Add("name", track.name);
                }
                if (track.language != null)
                {
                    request.Query.Add("language", track.language);
                }
                if (track.type != null)
                {
                    request.Query.Add("type", track.type);
                }
            }

            return(request);
        }
Esempio n. 3
0
        private async Task <TextTrack> GetUploadTextTrackTicketAsync(long clipId, TextTrack track)
        {
            try
            {
                var request  = GenerateUploadTextTrackTicketRequest(clipId, track);
                var response = await request.ExecuteRequestAsync <TextTrack>();

                UpdateRateLimit(response);
                CheckStatusCodeError(null, response, "Error generating upload text track ticket.");

                return(response.Content);
            }
            catch (Exception ex)
            {
                if (ex is VimeoApiException)
                {
                    throw;
                }
                throw new VimeoUploadException("Error generating upload text track ticket.", null, ex);
            }
        }
Esempio n. 4
0
    public override async Task <HttpResponse <GetUploadLinkTextTrackResponse> > ExecuteAsync(GetUploadLinkTextTrackRequest request, CancellationToken cancellationToken = default)
    {
        var uri = request.Uri;

        try
        {
            var texttack = new TextTrack();
            texttack.Name     = request.Name;
            texttack.Language = request.Language;
            texttack.Type     = request.Type;

            var response = await _httpService.HttpPostAsync <GetUploadLinkTextTrackResponse>(uri, texttack);

            return(response);
        }
        catch (Exception exception)
        {
            _logger.LogError(exception);
            return(HttpResponse <GetUploadLinkTextTrackResponse> .FromException(exception.Message));
        }
    }
Esempio n. 5
0
        private IApiRequest GenerateUploadTextTrackTicketRequest(long clipId, TextTrack track)
        {
            var request = _apiRequestFactory.GetApiRequest(AccessToken);

            request.Method = HttpMethod.Post;
            request.Path   = Endpoints.TextTracks;
            request.UrlSegments.Add("clipId", clipId.ToString());
            if (track == null)
            {
                return(request);
            }
            var parameters = new Dictionary <string, string>
            {
                ["active"]   = track.Active.ToString().ToLower(),
                ["name"]     = track.Name,
                ["language"] = track.Language,
                ["type"]     = track.Type.ToString().ToLowerInvariant()
            };

            request.Body = new FormUrlEncodedContent(parameters);
            return(request);
        }
Esempio n. 6
0
        void OnGUI()
        {
            // NOTE: These this IMGUI is just temporary until we implement the UI using uGUI
            if (!_showOptions)
            {
                return;
            }
            if (!_mediaPlayer || _mediaPlayer.Control == null)
            {
                return;
            }

            GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(2f, 2f, 1f));

            GUI.backgroundColor = Color.red;
            GUILayout.BeginVertical(GUI.skin.box);
            GUI.backgroundColor = Color.white;

            GUILayout.Label("Duration " + _mediaPlayer.Info.GetDuration() + "s");
            GUILayout.BeginHorizontal();
            GUILayout.Label("States: ");
            GUILayout.Toggle(_mediaPlayer.Control.HasMetaData(), "HasMetaData", GUI.skin.button);
            GUILayout.Toggle(_mediaPlayer.Control.IsPaused(), "Paused", GUI.skin.button);
            GUILayout.Toggle(_mediaPlayer.Control.IsPlaying(), "Playing", GUI.skin.button);
            GUILayout.Toggle(_mediaPlayer.Control.IsBuffering(), "Buffering", GUI.skin.button);
            GUILayout.Toggle(_mediaPlayer.Control.IsSeeking(), "Seeking", GUI.skin.button);
            GUILayout.Toggle(_mediaPlayer.Control.IsFinished(), "Finished", GUI.skin.button);
            GUILayout.EndHorizontal();

            {
                TimeRanges times = _mediaPlayer.Control.GetBufferedTimes();
                if (times != null)
                {
                    GUILayout.Label("Buffered Range " + times.MinTime + " - " + times.MaxTime);
                }
            }
            {
                TimeRanges times = _mediaPlayer.Control.GetSeekableTimes();
                if (times != null)
                {
                    GUILayout.Label("Seek Range " + times.MinTime + " - " + times.MaxTime);
                }
            }


            {
                GUILayout.Label("Video Tracks: " + _mediaPlayer.VideoTracks.GetVideoTracks().Count);

                GUILayout.BeginVertical();

                VideoTrack selectedTrack = null;
                foreach (VideoTrack track in _mediaPlayer.VideoTracks.GetVideoTracks())
                {
                    bool isSelected = (track == _mediaPlayer.VideoTracks.GetActiveVideoTrack());
                    if (isSelected)
                    {
                        GUI.color = Color.green;
                    }
                    if (GUILayout.Button(track.DisplayName, GUILayout.ExpandWidth(false)))
                    {
                        selectedTrack = track;
                    }
                    if (isSelected)
                    {
                        GUI.color = Color.white;
                    }
                }
                GUILayout.EndHorizontal();
                if (selectedTrack != null)
                {
                    _mediaPlayer.VideoTracks.SetActiveVideoTrack(selectedTrack);
                }
            }
            {
                GUILayout.Label("Audio Tracks: " + _mediaPlayer.AudioTracks.GetAudioTracks().Count);

                GUILayout.BeginVertical();

                AudioTrack selectedTrack = null;
                foreach (AudioTrack track in _mediaPlayer.AudioTracks.GetAudioTracks())
                {
                    bool isSelected = (track == _mediaPlayer.AudioTracks.GetActiveAudioTrack());
                    if (isSelected)
                    {
                        GUI.color = Color.green;
                    }
                    if (GUILayout.Button(track.DisplayName, GUILayout.ExpandWidth(false)))
                    {
                        selectedTrack = track;
                    }
                    if (isSelected)
                    {
                        GUI.color = Color.white;
                    }
                }
                GUILayout.EndHorizontal();
                if (selectedTrack != null)
                {
                    _mediaPlayer.AudioTracks.SetActiveAudioTrack(selectedTrack);
                }
            }
            {
                GUILayout.Label("Text Tracks: " + _mediaPlayer.TextTracks.GetTextTracks().Count);

                GUILayout.BeginVertical();

                TextTrack selectedTrack = null;
                foreach (TextTrack track in _mediaPlayer.TextTracks.GetTextTracks())
                {
                    bool isSelected = (track == _mediaPlayer.TextTracks.GetActiveTextTrack());
                    if (isSelected)
                    {
                        GUI.color = Color.green;
                    }
                    if (GUILayout.Button(track.DisplayName, GUILayout.ExpandWidth(false)))
                    {
                        selectedTrack = track;
                    }
                    if (isSelected)
                    {
                        GUI.color = Color.white;
                    }
                }
                GUILayout.EndHorizontal();
                if (selectedTrack != null)
                {
                    _mediaPlayer.TextTracks.SetActiveTextTrack(selectedTrack);
                }
            }
            {
                GUILayout.Label("FPS: " + _mediaPlayer.Info.GetVideoDisplayRate().ToString("F2"));
            }
#if (UNITY_STANDALONE_WIN)
            if (_mediaPlayer.PlatformOptionsWindows.bufferedFrameSelection != BufferedFrameSelectionMode.None)
            {
                IBufferedDisplay bufferedDisplay = _mediaPlayer.BufferedDisplay;
                if (bufferedDisplay != null)
                {
                    BufferedFramesState state = bufferedDisplay.GetBufferedFramesState();
                    GUILayout.BeginHorizontal();
                    GUILayout.Label("Buffered Frames: " + state.bufferedFrameCount);
                    GUILayout.HorizontalSlider(state.bufferedFrameCount, 0f, 12f);
                    GUILayout.EndHorizontal();
                    GUILayout.BeginHorizontal();
                    GUILayout.Label("Free Frames: " + state.freeFrameCount);
                    GUILayout.HorizontalSlider(state.freeFrameCount, 0f, 12f);
                    GUILayout.EndHorizontal();
                    GUILayout.Label("Min Timstamp: " + state.minTimeStamp);
                    GUILayout.Label("Max Timstamp: " + state.maxTimeStamp);
                    GUILayout.Label("Display Timstamp: " + _mediaPlayer.TextureProducer.GetTextureTimeStamp());
                }
            }
#endif
            GUILayout.EndVertical();
        }
        static void Main(string[] args)
        {
            // valid formats retrieved from https://github.com/calzoneman/sync/blob/3.0/docs/custom-media.md
            List <string> supportedSourceTypes = new List <string>()
            {
                "mp4", "webm", "ogg", "aac", "ogg", "mpeg"
            };
            List <string> supportedTextTypes = new List <string>()
            {
                "vtt"
            };
            List <int> supportedQualityLevels = new List <int>()
            {
                240, 360, 480, 540, 720, 1080, 1440, 2160
            };

            IConfiguration config  = BuildConfig();
            string         baseUrl = config["baseUrl"].Trim('/') + "/";

            if (args.Length < 1)
            {
                Console.WriteLine($"Drag and drop media files or a folder of media files onto {Process.GetCurrentProcess().ProcessName}.exe");
                Exit();
            }

            // get all files inside a folder
            string subfolder = "";

            if (args.Length == 1)
            {
                var attr = File.GetAttributes(args[0]);
                if (attr.HasFlag(FileAttributes.Directory))
                {
                    subfolder = args[0].Split('\\').Last() + "/";
                    var fileList = Directory.GetFiles(args[0]);
                    args = fileList;
                }
            }

            var              allSupportedTypes = supportedSourceTypes.Concat(supportedTextTypes);
            bool             unsupportedType   = false;
            List <Source>    sources           = new List <Source>();
            List <TextTrack> textTracks        = new List <TextTrack>();

            for (int i = 0; i < args.Length; i++)
            {
                // unsupported file format
                if (!allSupportedTypes.Any(x => args[i].EndsWith(x)))
                {
                    Console.WriteLine($"Unsupported file type: {args[i]}");
                    unsupportedType = true;
                }
                // text tracks
                else if (supportedTextTypes.Any(x => args[i].EndsWith(x)))
                {
                    string    filename  = args[i].Split('\\').Last();
                    string    extension = filename.Split('.').Last();
                    TextTrack tt        = new TextTrack()
                    {
                        url         = baseUrl + subfolder + filename,
                        contentType = "text/" + extension,
                        name        = "Subtitles " + i,
                        isDefault   = !(textTracks.Count > 1)
                    };
                    textTracks.Add(tt);
                }
                // video/audio tracks
                else
                {
                    string   filename  = args[i].Split('\\').Last();
                    string   extension = filename.Split('.').Last();
                    Metadata md        = GetVideoInfo(args[i]);
                    int      quality   = supportedQualityLevels.First();
                    for (int j = 0; j < supportedQualityLevels.Count; j++)
                    {
                        int frameHeight = int.Parse(md.VideoData.FrameSize.Split('x')[1]);
                        if (frameHeight >= supportedQualityLevels[j])
                        {
                            quality = supportedQualityLevels[j];
                        }
                    }

                    int totalBitrate = (md.VideoData.BitRateKbs ?? 0) + md.AudioData.BitRateKbs;

                    Source s = new Source()
                    {
                        url         = baseUrl + subfolder + filename,
                        contentType = "video/" + extension,
                        quality     = quality,
                        bitrate     = totalBitrate,
                        duration    = Convert.ToInt32(md.Duration.TotalSeconds)
                    };
                    sources.Add(s);
                }
            }
            if (unsupportedType)
            {
                Console.WriteLine("Valid file types: " + string.Join(", ", allSupportedTypes));
                Exit();
            }
            // only text tracks provided
            if (sources.Count < 1)
            {
                Console.WriteLine("No source files provided.");
                Console.WriteLine("Valid source file types: " + string.Join(", ", supportedSourceTypes));
                Exit();
            }

            string title = sources.First().url.Split('/').Last().Split('.').First();

            JObject json = new JObject(
                new JProperty("title", title),
                new JProperty("duration", sources.First().duration),
                new JProperty("live", false),
                new JProperty("sources",
                              new JArray(
                                  from s in sources
                                  select new JObject(
                                      new JProperty("url", s.url),
                                      new JProperty("contentType", s.contentType),
                                      new JProperty("quality", s.quality),
                                      new JProperty("bitrate", s.bitrate)
                                      )
                                  )
                              ),
                new JProperty("textTracks",
                              new JArray(
                                  from t in textTracks
                                  select new JObject(
                                      new JProperty("url", t.url),
                                      new JProperty("contentType", t.contentType),
                                      new JProperty("name", t.name),
                                      new JProperty("default", t.isDefault)
                                      )
                                  )
                              )
                );

            File.WriteAllText(subfolder + json["title"] + ".json", json.ToString());

            // By default, browsers block requests for WebVTT tracks hosted on different domains than the current page.
            // In order for text tracks to work cross-origin, the Access-Control-Allow-Origin header needs to be set by the remote server when serving the VTT file.
            if (textTracks.Count > 0)
            {
                File.WriteAllText(subfolder + ".htaccess", "Header set Access-Control-Allow-Origin \"*\"");
            }
        }
Esempio n. 8
0
        /// <inheritdoc />
        public async Task <TextTrack> UpdateTextTrackAsync(long videoId, long trackId, TextTrack track)
        {
            try
            {
                var request  = GenerateUpdateTextTrackRequest(videoId, trackId, track);
                var response = await request.ExecuteRequestAsync <TextTrack>().ConfigureAwait(false);

                UpdateRateLimit(response);
                CheckStatusCodeError(response, "Error updating text track for video.", HttpStatusCode.NotFound);

                return(response.StatusCode == HttpStatusCode.NotFound ? null : response.Content);
            }
            catch (Exception ex)
            {
                if (ex is VimeoApiException)
                {
                    throw;
                }

                throw new VimeoApiException("Error updating text track for video.", ex);
            }
        }
Esempio n. 9
0
        /// <inheritdoc />
        public async Task <TextTrack> UploadTextTrackFileAsync(IBinaryContent fileContent, long videoId, TextTrack track)
        {
            if (!fileContent.Data.CanRead)
            {
                throw new ArgumentException("fileContent should be readable");
            }

            if (fileContent.Data.CanSeek && fileContent.Data.Position > 0)
            {
                fileContent.Data.Position = 0;
            }

            var ticket = await GetUploadTextTrackTicketAsync(videoId, track).ConfigureAwait(false);

            var request = _apiRequestFactory.GetApiRequest();

            request.Method = HttpMethod.Put;
            request.ExcludeAuthorizationHeader = true;
            request.Path = ticket.Link;

            request.Body = new ByteArrayContent(await fileContent.ReadAllAsync().ConfigureAwait(false));

            var response = await request.ExecuteRequestAsync().ConfigureAwait(false);

            CheckStatusCodeError(null, response, "Error uploading text track file.", HttpStatusCode.BadRequest);

            return(ticket);
        }
Esempio n. 10
0
        private IApiRequest GenerateUpdateTextTrackRequest(long clipId, long trackId, [NotNull] TextTrack track)
        {
            ThrowIfUnauthorized();

            var request = _apiRequestFactory.GetApiRequest(AccessToken);

            request.Method = new HttpMethod("PATCH");
            request.Path   = Endpoints.TextTrack;
            request.UrlSegments.Add("clipId", clipId.ToString());
            request.UrlSegments.Add("trackId", trackId.ToString());

            var parameters = new Dictionary <string, string>
            {
                ["active"] = track.Active.ToString().ToLower()
            };

            if (track.Name != null)
            {
                parameters["name"] = track.Name;
            }

            if (track.Language != null)
            {
                parameters["language"] = track.Language;
            }

            parameters["type"] = track.Type.ToString().ToLowerInvariant();
            request.Body       = new FormUrlEncodedContent(parameters);

            return(request);
        }
        /// <summary>
        /// Update text track asynchronously
        /// </summary>
        /// <param name="videoId">VideoId</param>
        /// <param name="trackId">TrackId</param>
        /// <param name="track">TextTrack</param>
        /// <returns>Updated text track</returns>
        public async Task <TextTrack> UpdateTextTrackAsync(long videoId, long trackId, TextTrack track)
        {
            try
            {
                IApiRequest request = GenerateUpdateTextTrackRequest(videoId, trackId, track);
                IRestResponse <TextTrack> response = await request.ExecuteRequestAsync <TextTrack>();

                UpdateRateLimit(response);
                CheckStatusCodeError(response, "Error updating text track for video.", HttpStatusCode.NotFound);

                if (response.StatusCode == HttpStatusCode.NotFound)
                {
                    return(null);
                }
                return(response.Data);
            }
            catch (Exception ex)
            {
                if (ex is VimeoApiException)
                {
                    throw;
                }
                throw new VimeoApiException("Error updating text track for video.", ex);
            }
        }