/// <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); }
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); } }
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)); } }
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); }
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 \"*\""); } }
/// <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); } }
/// <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); }
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); } }