public void CanHandleGetMediaInformationExceptionalCases() { MockForGetMediaInformationFaultyTest mock = new MockForGetMediaInformationFaultyTest(); YoutubeDl dl = new YoutubeDl(mock); dl.GetMediaInformation(new Uri("http://something.com")); }
private void PerformTest(IAudioDownloadOutputSample sample) { const string DownloadDirectory = "fakepath"; MockForAudioDownloadTest processMock = this.CreateProcessFactory(sample, DownloadDirectory); YoutubeDl downloader = new YoutubeDl(processMock); Dictionary <double, bool> ExpectedPercentsToBeReported = new Dictionary <double, bool>(sample.ExpectedPercents.Distinct().Select(x => new KeyValuePair <double, bool>(x, false))); Dictionary <DownloadState, bool> ExpectedStatusesToBeReported = new Dictionary <DownloadState, bool>(sample.ExpectedDownloadStatuses.Distinct().Select(x => new KeyValuePair <DownloadState, bool>(x, false))); using (IDownload progress = downloader.PrepareDownload(new Uri(sample.MediaUri), MediaFormat.MP3Audio, DownloadDirectory)) { RunDownload(processMock, ExpectedPercentsToBeReported, ExpectedStatusesToBeReported, progress); } foreach (var item in ExpectedStatusesToBeReported) { Assert.IsTrue(item.Value, $"Expected download status {item.Key} was not reported by event {nameof(IDownload.DownloadStatusChanged)}."); } foreach (var item in ExpectedPercentsToBeReported) { Assert.IsTrue(item.Value, $"Expected download percentage {item.Key} was not reported by event {nameof(IDownload.PercentageChanged)}."); } }
/// <summary> /// Initializes a new instance of the <see cref="PlaylistReader"/> class. /// </summary> /// <param name="url">The url<see cref="string"/></param> /// <param name="videos">The videos<see cref="int[]"/></param> /// <param name="reverse">The reverse<see cref="bool"/></param> public PlaylistReader(string url, int[] videos, bool reverse) { var json_dir = AppEnvironment.GetJsonDirectory(); _playlist_id = YoutubeHelper.GetPlaylistId(url); var range = string.Empty; if (videos != null && videos.Length > 0) { // Make sure the video indexes is sorted, otherwise reversing wont do anything Array.Sort(videos); range = string.Format(CmdPlaylistRange, string.Join(",", videos)); } var reverseS = reverse ? CmdPlaylistReverse : string.Empty; _arguments = string.Format(CmdPlaylistInfo, json_dir, _playlist_id, range, reverseS, url); _url = url; YoutubeDl.LogHeader(_arguments); _youtubeDl = ProcessHelper.StartProcess(YoutubeDl.YouTubeDlPath, _arguments, OutputReadLine, ErrorReadLine, null); _youtubeDl.Exited += delegate { _processFinished = true; YoutubeDl.LogFooter(); }; }
public async Task <Song> Download(string url) { using (var ytDownloader = new YoutubeDl()) { var data = (await ytDownloader.GetDataAsync(url)).Split('\n'); if (data.Length < 6) { return(null); } if (!TimeSpan.TryParseExact(data[4], new[] { "ss", "m\\:ss", "mm\\:ss", "h\\:mm\\:ss", "hh\\:mm\\:ss", "hhh\\:mm\\:ss" }, CultureInfo.InvariantCulture, out var time)) { time = TimeSpan.FromHours(24); } if (time.TotalMinutes > 10) { return(null); } return(new Song { Title = data[0], Duration = time, Url = data[2], }); } }
/// <summary> /// Gets an instance asynchronously of the <see cref="YoutubeSongInfo"/> class. /// </summary> /// <param name="Source">The URL of the video</param> /// <returns>A <see cref="YoutubeSongInfo"/> instance.</returns> public static async Task <YoutubeSongInfo> GetVideoInfoAsync(string Source) { YoutubeDl d = new YoutubeDl("youtube-dl.exe", App.Path) { VideoID = YoutubeUri.GetVideoID(Source) }; YoutubeMediaInfo r = await d.GetVideoInfo(); var Result = new YoutubeSongInfo( Source: Source, Title: r.RecognizedMedia?.Title ?? r.Title, Artist: r.RecognizedMedia?.Artist, DurationInSeconds: r.Duration.TotalSeconds ) { Formats = r.MediaFormats }; if (App.Config.YoutubeDownloadThumbnail) { Result.AlbumImage = await r.Thumbnails.FirstOrDefault()?.DownloadAsImageAsync(); } return(Result); }
public void CanGetYoutubeMediaInformation() { string ExpectedVideoTitle = "sample-title"; string ExpectedVideoID = "hW9tIK5pcl8"; string ExpectedUploaderID = "sample-uploader"; string ExpectedDescription = "sample-description"; int ExpectedLikes = 51; int ExpectedDislikes = 12; int ExpectedViews = 314; double ExpectedDuration = 312.54; string ExpectedVideoUri = $"https://www.youtube.com/watch?v={ExpectedVideoID}"; string ExpectedIdentifiedArtist = "sample-artist"; string ExpectedIdentifiedSong = "sample-song"; string ExpectedUploadDate = "20181216"; MockForGetMediaInformationWithYoutubeTest processMock = new MockForGetMediaInformationWithYoutubeTest( ExpectedVideoTitle, ExpectedVideoID, ExpectedUploaderID, ExpectedDescription, ExpectedLikes, ExpectedDislikes, ExpectedViews, ExpectedDuration, ExpectedVideoUri, ExpectedIdentifiedArtist, ExpectedIdentifiedSong, ExpectedUploadDate ); YoutubeDl downloader = new YoutubeDl(processMock); IMediaInformation actual = downloader.GetMediaInformation(new Uri(ExpectedVideoUri)); Assert.IsTrue(processMock.ProcessStarted, "Youtube-dl was not started."); Assert.IsTrue(processMock.ParametersPassedCorrectly, "Command-line arguments were passed incorrectly to youtube-dl."); Assert.IsNotNull(actual); Assert.IsInstanceOfType(actual, typeof(ILikeableMedia)); Assert.IsInstanceOfType(actual, typeof(IIdentifiedSong)); Assert.AreEqual(ExpectedVideoUri, actual.MediaUri); Assert.AreEqual(ExpectedDuration, actual.Duration); Assert.AreEqual(ExpectedVideoTitle, actual.Title); Assert.AreEqual(ExpectedDescription, actual.Description); Assert.AreEqual(ExpectedVideoID, actual.VideoId); ILikeableMedia actual2 = (ILikeableMedia)actual; Assert.AreEqual(ExpectedLikes, actual2.Likes); Assert.AreEqual(ExpectedDislikes, actual2.Dislikes); IIdentifiedSong actual3 = (IIdentifiedSong)actual; Assert.AreEqual(ExpectedIdentifiedArtist, actual3.Artist); Assert.AreEqual(ExpectedIdentifiedSong, actual3.TrackTitle); }
public void CanGetVersion() { string expectedVersion = "2018.12.11."; MockForGetVersionTest processMock = new MockForGetVersionTest(expectedVersion); YoutubeDl downloader = new YoutubeDl(processMock); string actual = downloader.GetVersion(); Assert.IsTrue(processMock.ParametersPassedCorrectly); Assert.IsTrue(processMock.ExitedSuccessfully); Assert.AreEqual(expectedVersion, actual); }
/// <summary> /// Downloads a video asynchronously with youtube-dl. /// </summary> /// <param name="SongInfo">A <see cref="ISongInfo"/> instance that holds the URI of the media to download</param> /// <returns> /// A <see cref="Task"/> for an <see cref="IPlaybackManager"/> instance /// that can play the YouTube media. Null is returned when the download /// fails. /// </returns> /// <exception cref="ArgumentNullException">when <paramref name="SongInfo"/> is null</exception> /// <exception cref="ArgumentException">when <see cref="ISongInfo.Source"/> is not a valid YouTube URI</exception> public static async Task <IPlaybackManager> DownloadVideoAsync(ISongInfo SongInfo, IProgress <LongOperationProgress> Progress) { #region Error checking if (SongInfo == null) { throw new ArgumentNullException(nameof(SongInfo)); } if (!YoutubeUri.IsValidYoutubeUri(SongInfo.Source)) { throw new ArgumentException("Not a valid YouTube URI"); } #endregion string MediaFilename = Path.ChangeExtension(Path.GetTempFileName(), "mp3"); #region Cleanup if (File.Exists(MediaFilename)) { File.Delete(MediaFilename); } #endregion MediaFormat Format = (SongInfo as YoutubeSongInfo)?.GetBestAudioFormat(); try { YoutubeDl Downloader = new YoutubeDl("youtube-dl.exe", App.Path) { AudioFileFormat = YoutubeDlAudioFormat.mp3, Filename = MediaFilename, VideoID = YoutubeUri.GetVideoID(SongInfo.Source) }; Progress <YoutubeDownloadProgress> YTProgress = new Progress <YoutubeDownloadProgress>(); YTProgress.ProgressChanged += (po, pe) => Progress?.Report(pe.ToLongOperationProgress()); //When download fails and youtube-dl reports that an update is required, update it and retry. Downloader.UpdateRequired += async(o, e) => { Progress.Report( new YoutubeDownloadProgress(YoutubeDownloadStatus.Updating, 0).ToLongOperationProgress() ); await Downloader.UpdateAsync(); await Downloader.DownloadAudioAsync(YTProgress); }; await Downloader.DownloadAudioAsync(YTProgress, Format); } catch (Exception e) { Trace.WriteLine(e.Message); return(null); } if (File.Exists(MediaFilename)) { using (Stream s = File.OpenRead(MediaFilename)) { Progress <LongOperationProgress> OpenMediaProgress = new Progress <LongOperationProgress>(); OpenMediaProgress.ProgressChanged += (o, e) => Progress?.Report(e); return(new YoutubePlayback( SongInfo, await UnmanagedStream.CreateFromStream(s, OpenMediaProgress), MediaFilename )); } } else { return(null); } }
private void HandleValidSubmit() { YoutubeDl.runYoutubeDl(basic); done = "Done!"; }