/// <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); }
/// <summary> /// This method is executed when the user wants to play a media from an URI source. /// </summary> /// <param name="sender">The sender object's instance</param> /// <param name="e">Event parameters</param> private async void UriOpen_Click(object sender, MouseButtonEventArgs e) { this.viewModel.MenuVisible = false; #region Check requirements if (!YoutubePlayback.ToolsAvailable) { MessageBoxResult DownloadQuestion = MessageBox.Show( messageBoxText: "Első alkalommal le kell tölteni az ffmpeg.exe, az ffprobe.exe és a youtube-dl.exe programokat. Szeretnéd most letölteni?", caption: "Kellene még néhány dolog...", button: MessageBoxButton.YesNo, icon: MessageBoxImage.Question ); if (DownloadQuestion == MessageBoxResult.Yes) { ProgressBarDialog ProgressBar = new ProgressBarDialog("YouTube eszközök letöltése", "Fél perc és kész vagyunk..."); ProgressBar.Show(); await YoutubePlayback.DownloadSoftwareAsync(); ProgressBar.Close(); } else { return; } } #endregion TextInputDialog Dialog = new TextInputDialog("YouTube média letöltése", "Írd ide a videó címét, amit meg szeretnél nyitni:"); Dialog.Owner = this; bool?Result = Dialog.ShowDialog(); if (Result.HasValue && Result.Value == true) { if (!YoutubeUri.IsValidYoutubeUri(Dialog.UserInput)) { PlayerUtils.ErrorMessageBox(App.Name, "Úgy tűnik, hibás linket adtál meg."); return; } await this.OpenFilesAsync(new string[] { Dialog.UserInput }); } }
/// <summary> /// Adds multiple files to the playlist and starts /// playing the first of them. /// </summary> /// <param name="Filenames">An array containing the files' path</param> /// <returns>True if all files are opened successfully, false if not</returns> private async Task <bool> OpenFilesAsync(string[] Filenames) { var SupportedFiles = Filenames.Where(x => PlaybackFactory.IsSupportedMedia(x)); #region Error checking if (SupportedFiles.Count() == 0) { return(false); } #endregion try { this.Playlist.Clear(); foreach (string Filename in SupportedFiles) { if (YoutubeUri.IsValidYoutubeUri(Filename)) { this.viewModel.LyricsReader = null; this.viewModel.Lyrics = "Előkészülünk a letöltéshez..."; this.Playlist.Add(await YoutubeSongInfo.GetVideoInfoAsync(Filename)); } else { this.Playlist.Add(new BassSongInfo(Filename)); } } this.Playlist.MoveTo(0); } catch (Exception e) { Trace.TraceWarning("Could not open file: " + e.Message); new Toast(App.Name) { Title = "Hoppá...", Content = "Valami miatt nem sikerült a fájlokat megnyitni.", Image = TomiSoft.MP3Player.Properties.Resources.AbstractAlbumArt }.Show(); return(false); } return(true); }
/// <summary> /// Determines whether the given media is supported. /// </summary> /// <param name="Source">The source (a file's path or an URI) to check</param> /// <returns>True if the media is supported, false if not</returns> public static bool IsSupportedMedia(string Source) { if (File.Exists(Source)) { if (BassManager.IsSupportedFile(Source)) { return(true); } } else if (Uri.IsWellFormedUriString(Source, UriKind.Absolute)) { if (YoutubeUri.IsValidYoutubeUri(Source)) { return(true); } } return(false); }
/// <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); } }