/// <summary> /// Play the youtube video in the attached Video Player component. /// </summary> /// <param name="videoUrl">Youtube url (e.g. https://www.youtube.com/watch?v=VIDEO_ID)</param> /// <param name="options">Options for downloading the raw video</param> /// <param name="cancellationToken">A CancellationToken used to cancel the current async task</param> /// <returns>A Task to await</returns> public async Task PlayVideoAsync(string videoUrl = null, YoutubeDlOptions options = null, CancellationToken cancellationToken = default) { options = options ?? (is360Video ? YoutubeDlOptions.Three60 : YoutubeDlOptions.Default); await PrepareVideoAsync(videoUrl, options, cancellationToken); VideoPlayer.Play(); }
/// <summary> /// Triggers a request to youtube-dl to parse the webpage for the raw video url /// </summary> /// <param name="videoUrl">Youtube url (e.g. https://www.youtube.com/watch?v=VIDEO_ID)</param> /// <param name="options">Options for downloading the raw video</param> /// <param name="cancellationToken">A CancellationToken used to cancel the current async task</param> /// <returns>A Task to await</returns> public static async Task <string> GetRawVideoUrlAsync(string videoUrl, YoutubeDlOptions options = null, CancellationToken cancellationToken = default) { options = options ?? YoutubeDlOptions.Default; var metaData = await YoutubeDl.GetVideoMetaDataAsync(videoUrl, options, cancellationToken); return(metaData.Url); }
public static async Task <T> GetVideoMetaDataAsync <T>(string youtubeUrl, YoutubeDlOptions options, CancellationToken cancellationToken = default) { var schema = GetJsonSchema <T>(); return(await GetVideoMetaDataAsync <T>(youtubeUrl, options, schema, cancellationToken)); }
public static async Task <T> GetVideoMetaDataAsync <T>(string youtubeUrl, YoutubeDlOptions options, CancellationToken cancellationToken = default) { var optionFlags = new List <string>(); if (!string.IsNullOrWhiteSpace(options.Format)) { optionFlags.Add($"-f \"{options.Format}\""); } if (options.UserAgent != null) { optionFlags.Add($"--user-agent \"{options.UserAgent}\""); } if (options.Custom != null) { optionFlags.Add(options.Custom); } var requestUrl = $"{ServerUrl}/v1/video?url={youtubeUrl}"; if (optionFlags.Count > 0) { requestUrl += $"&options={UnityWebRequest.EscapeURL(string.Join(" ", optionFlags))}"; } var request = UnityWebRequest.Get(requestUrl); var tcs = new TaskCompletionSource <T>(); request.SendWebRequest().completed += operation => { if (request.isNetworkError) { tcs.TrySetException(new Exception(request.error)); return; } var text = request.downloadHandler.text; if (request.isHttpError) { tcs.TrySetException(new Exception(request.error + "\nResponseError:" + text)); return; } var video = JsonConvert.DeserializeObject <T>(text); tcs.TrySetResult(video); }; cancellationToken.Register(obj => { ((UnityWebRequest)obj).Abort(); tcs.TrySetCanceled(cancellationToken); }, request); return(await tcs.Task); }
/// <summary> /// Prepare the video for playing. This includes a web request to youtube-dl, as well as preparing/warming up /// the VideoPlayer. /// </summary> /// <param name="videoUrl">Youtube url (e.g. https://www.youtube.com/watch?v=VIDEO_ID)</param> /// <param name="options">Options for downloading the raw video</param> /// <param name="cancellationToken">A CancellationToken used to cancel the current async task</param> /// <returns>A Task to await</returns> public async Task PrepareVideoAsync(string videoUrl = null, YoutubeDlOptions options = null, CancellationToken cancellationToken = default) { videoUrl = videoUrl ?? youtubeUrl; options = options ?? (is360Video ? YoutubeDlOptions.Three60 : YoutubeDlOptions.Default); var rawUrl = await GetRawVideoUrlAsync(videoUrl, options, cancellationToken); VideoPlayer.source = VideoSource.Url; //Resetting the same url restarts the video... if (VideoPlayer.url != rawUrl) { VideoPlayer.url = rawUrl; } youtubeUrl = videoUrl; await VideoPlayer.PrepareAsync(cancellationToken); }
public static async Task <T> GetVideoMetaDataAsync <T>(string youtubeUrl, YoutubeDlOptions options, CancellationToken cancellationToken = default) { var optionFlags = new List <string>(); if (!string.IsNullOrWhiteSpace(options.Format)) { optionFlags.Add($"-f \"{options.Format}\""); } if (options.UserAgent != null) { //optionFlags.Add($"--user-agent \"{options.UserAgent}\""); } if (options.Custom != null) { optionFlags.Add(options.Custom); } var requestUrl = $"{ServerUrl}/v1/video?url={youtubeUrl}"; if (optionFlags.Count > 0) { //requestUrl += $"&options={UnityWebRequest.EscapeURL(string.Join(" ", optionFlags))}"; } using (var client = new HttpClient()) { try { var request = await client.GetAsync(requestUrl, cancellationToken); var tcs = new TaskCompletionSource <T>(); var text = await request.Content.ReadAsStringAsync(); var video = JsonConvert.DeserializeObject <T>(text); tcs.TrySetResult(video); return(await tcs.Task); } catch (Exception e) { Debug.LogError($"Youtube Error: {e}"); return(default);
public static async Task <YoutubeVideoMetaData> GetVideoMetaDataAsync(string youtubeUrl, YoutubeDlOptions options) { var optionFlags = new List <string>(); if (!string.IsNullOrWhiteSpace(options.Format)) { optionFlags.Add($"-f \"{options.Format}\""); } if (options.UserAgent != null) { optionFlags.Add($"--user-agent \"{options.UserAgent}\""); } var requestUrl = $"{ServerUrl}/v1/video?url={youtubeUrl}"; if (optionFlags.Count > 0) { requestUrl += $"&options={HttpUtility.UrlEncode(string.Join(" ", optionFlags))}"; } var request = UnityWebRequest.Get(requestUrl); var tcs = new TaskCompletionSource <YoutubeVideoMetaData>(); request.SendWebRequest().completed += operation => { if (request.isHttpError || request.isNetworkError) { tcs.TrySetException(new Exception(request.error)); return; } var text = request.downloadHandler.text; var video = JsonConvert.DeserializeObject <YoutubeVideoMetaData>(text); tcs.TrySetResult(video); }; return(await tcs.Task); }