/// <summary>
        /// Initializes a new instance of the <see cref="YoutubePlayback"/> class.
        /// </summary>
        /// <param name="DownloadedFile">The path of the media file downloaded and converted by youtube-dl.</param>
        private YoutubePlayback(ISongInfo SongInfo, UnmanagedStream DownloadedFile, string Filename)
            : base(DownloadedFile, SongInfo)
        {
            this.songInfo = new SongInfo(SongInfo);

            this.DownloadedFile = Filename;
        }
Exemple #2
0
        /// <summary>
        /// Searches for a matching lyrics file and loads it.
        /// </summary>
        /// <param name="SongInfo">The ISongInfo instance that holds informations about the song.</param>
        private async void OpenLyricsAsync(ISongInfo SongInfo)
        {
            this.viewModel.LyricsReader = null;
            this.viewModel.Lyrics       = "Dalszöveget keresünk...";
            this.viewModel.LyricsReader = await LyricsProvider.FindLyricsAsync(SongInfo);

            this.LyricsServerModule.LyricsReader = this.viewModel.LyricsReader;
        }
Exemple #3
0
 protected override void OnInitialize()
 {
     base.OnInitialize();
     if (Manager.Items.ContainsKey("SongInfo"))
     {
         songInfo = Manager.Items["SongInfo"] as ISongInfo;
     }
 }
        /// <summary>
        /// Finds a lyrics file asynchronously using the informations provided by an
        /// <see cref="ISongInfo"/> instance.
        /// </summary>
        /// <param name="SongInfo">An <see cref="ISongInfo"/> instance that holds informations about a song.</param>
        /// <returns>A Task for an <see cref="ILyricsReader"/> instance if the lyrics is found or null otherwise.</returns>
        public Task <ILyricsReader> FindLyricsAsync(ISongInfo SongInfo)
        {
            #region Error checking
            if (SongInfo == null)
            {
                return(null);
            }
            #endregion

            return(Task.Run(
                       () => this.ScanFileDirectory(SongInfo)
                       ));
        }
        /// <summary>
        /// Finds a lyrics file asynchronously using the informations provided by an
        /// ISongInfo instance.
        /// </summary>
        /// <param name="SongInfo">An ISongInfo instance that holds informations about a song.</param>
        /// <returns>A Task for an ILyricsReader instance if the lyrics is found or null otherwise.</returns>
        public static async Task <ILyricsReader> FindLyricsAsync(ISongInfo SongInfo)
        {
            foreach (ILyricsProvider Provider in Providers)
            {
                ILyricsReader reader = await Provider.FindLyricsAsync(SongInfo);

                if (reader != null)
                {
                    return(reader);
                }
            }

            return(null);
        }
Exemple #6
0
        public SongInfo(ISongInfo SongInfo)
        {
            #region Error checking
            if (SongInfo == null)
            {
                throw new ArgumentNullException(nameof(SongInfo));
            }
            #endregion

            this.Album             = SongInfo.Album;
            this.AlbumImage        = SongInfo.AlbumImage;
            this.Artist            = SongInfo.Artist;
            this.IsLengthInSeconds = SongInfo.IsLengthInSeconds;
            this.Length            = SongInfo.Length;
            this.Source            = SongInfo.Source;
            this.Title             = SongInfo.Title;
        }
        /// <summary>
        /// Performs a scan in the directory that contains the music file for a
        /// matching lyrics file.
        /// </summary>
        /// <param name="SongInfo">An <see cref="ISongInfo"/> instance that holds informations about a song.</param>
        /// <returns>An <see cref="ILyricsReader"/> instance if the lyrics is found or null otherwise.</returns>
        private ILyricsReader ScanFileDirectory(ISongInfo SongInfo)
        {
            string Dir = Path.GetDirectoryName(SongInfo.Source);

            #region Error checking
            if (!Directory.Exists(Dir))
            {
                return(null);
            }
            #endregion

            //Try to find a lyrics file with the same name as in SongInfo.
            //Eg. if we have "test.mp3", try to find "test.lrc".
            foreach (var Ext in LyricsLoader.SupportedExtensions)
            {
                string Filename = Path.ChangeExtension(SongInfo.Source, Ext);

                if (File.Exists(Filename))
                {
                    return(LyricsLoader.LoadFile(Filename));
                }
            }

            //Scan all the lyrics files in the same folder.
            foreach (var File in LyricsLoader.FindAllLyricsFiles(Dir))
            {
                try {
                    ILyricsReader   reader   = LyricsLoader.LoadFile(File);
                    ILyricsMetadata metadata = reader as ILyricsMetadata;

                    if (metadata != null)
                    {
                        if (metadata.Title == SongInfo.Title && metadata.Artist == SongInfo.Artist)
                        {
                            return(reader);
                        }
                    }
                }
                catch {}
            }

            //If lyrics was not found, null is returned.
            return(null);
        }
Exemple #8
0
        /// <summary>
        /// Initializes a new instance of <see cref="BassPlaybackAbstract"/> using the given channel ID.
        /// </summary>
        /// <param name="ChannelID">The channel ID provided by BASS.</param>
        /// <exception cref="IOException">when BASS can't open the file</exception>
        public BassPlaybackAbstract(int ChannelID)
        {
            #region Error checking
            if (ChannelID == 0)
            {
                Trace.TraceWarning($"[BASS] Could not open file (ErrorCode={Bass.BASS_ErrorGetCode()})");
                throw new IOException("Nem sikerült megnyitni a fájlt: " + Bass.BASS_ErrorGetCode());
            }
            #endregion

            this.channelID = ChannelID;

            this.PlaybackTimer = new DispatcherTimer()
            {
                Interval = TimeSpan.FromSeconds(0.02)
            };
            this.PlaybackTimer.Tick += TimerTick;

            this.IsPlaying = false;

            this.songInfo = new BassSongInfo(this.ChannelID);
        }
        /// <summary>
        /// Finds a lyrics file asynchronously using the informations provided by an
        /// ISongInfo instance.
        /// </summary>
        /// <param name="SongInfo">An ISongInfo instance that holds informations about a song.</param>
        /// <returns>A Task for an ILyricsReader instance if the lyrics is found or null otherwise.</returns>
        public async Task <ILyricsReader> FindLyricsAsync(ISongInfo SongInfo)
        {
            #region Error checking
            if (SongInfo == null)
            {
                return(null);
            }
            #endregion

            using (WebClient Client = new WebClient()) {
                Client.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
                Client.Headers[HttpRequestHeader.UserAgent]   = $"{App.Name} (version {App.Version})";

                string Data = $"title={UrlEncode(SongInfo.Title)}&artist={UrlEncode(SongInfo.Artist)}";
                string Response;
                try {
                    Response = await Client.UploadStringTaskAsync(
                        "http://tomisoft.site90.net/lyrics/api.getlrc.php?get_lyrics=true",
                        Data
                        );
                }
                catch (WebException) {
                    return(null);
                }

                if (Response != "NOTFOUND")
                {
                    string Filename = Path.GetTempFileName();

                    if (await CreateFileAsync(Filename, Response))
                    {
                        return(LyricsLoader.LoadFile(Filename));
                    }
                }
            }

            return(null);
        }
        /// <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);
            }
        }
Exemple #11
0
 public LocalMidiFilePlayback(UnmanagedStream MediaStream, ISongInfo SongInfo, string SoundfontFilename)
     : base(MediaStream, SongInfo)
 {
     this.ApplySoundfontToStream(SoundfontFilename);
 }
Exemple #12
0
 /// <summary>
 /// Initializes a new instance of <see cref="LocalAudioFilePlayback"/> using
 /// the given <see cref="UnmanagedStream"/> and its song informations.
 /// </summary>
 /// <param name="MediaStream">An <see cref="UnmanagedStream"/> that represents the file copied to an unmanaged memory location.</param>
 /// <param name="SongInfo">An <see cref="ISongInfo"/> instance that holds informations about the media.</param>
 public LocalAudioFilePlayback(UnmanagedStream MediaStream, ISongInfo SongInfo)
     : base(Bass.BASS_StreamCreateFile(MediaStream.PointerToUnmanagedMemory, 0, MediaStream.Length, BASSFlag.BASS_DEFAULT))
 {
     this.songInfo        = SongInfo;
     this.AllocatedMemory = MediaStream;
 }
        /// <summary>
        /// Loads the given file.
        /// </summary>
        /// <param name="Source">The file's path or an uri to load.</param>
        /// <returns>An <see cref="IPlaybackManager"/> instance that can handle the given file.</returns>
        /// <exception cref="ArgumentNullException">when <paramref name="SongInfo"/> is null</exception>
        /// <exception cref="NotSupportedException">when the media represented by <paramref name="SongInfo"/> is not supported by any playback methods</exception>
        public async static Task <IPlaybackManager> LoadMedia(ISongInfo SongInfo)
        {
            #region Error checking
            if (SongInfo == null)
            {
                throw new ArgumentNullException(nameof(SongInfo));
            }
            #endregion

            //If the Source is file:
            if (File.Exists(SongInfo.Source))
            {
                string Extension = PlayerUtils.GetFileExtension(SongInfo.Source);

                Progress <LongOperationProgress> FileOpenProgress = new Progress <LongOperationProgress>();
                FileOpenProgress.ProgressChanged += OpenFileProgressChanged;

                //In case of any file supported by BASS:
                if (BassManager.GetSupportedExtensions().Contains(Extension))
                {
                    //If Audio CD track:
                    if (Extension == "cda")
                    {
                        return(new AudioCdPlayback(SongInfo.Source));
                    }
                    else
                    {
                        using (Stream SourceStream = File.OpenRead(SongInfo.Source)) {
                            var unmanagedStream = await UnmanagedStream.CreateFromStream(SourceStream, FileOpenProgress);

                            //If Midi file:
                            if (new string[] { "mid", "midi", "kar", "rmi" }.Contains(Extension))
                            {
                                return(new LocalMidiFilePlayback(
                                           unmanagedStream,
                                           SongInfo,
                                           @"C:\SGM-V2.01.sf2"
                                           ));
                            }

                            //Any other stuff...
                            else
                            {
                                return(new LocalAudioFilePlayback(
                                           unmanagedStream,
                                           SongInfo
                                           ));
                            }
                        }
                    }
                }
            }

            //If the Source is an Uri:
            else if (Uri.IsWellFormedUriString(SongInfo.Source, UriKind.Absolute))
            {
                //Youtube link:
                if (SongInfo is YoutubeSongInfo)
                {
                    Progress <LongOperationProgress> Progress = new Progress <LongOperationProgress>();
                    Progress.ProgressChanged += OpenFileProgressChanged;

                    IPlaybackManager Result = await YoutubePlayback.DownloadVideoAsync(SongInfo, Progress);

                    Progress.ProgressChanged -= OpenFileProgressChanged;

                    return(Result);
                }
            }

            Trace.TraceWarning($"[Playback] Unsupported media: {SongInfo.Source}");
            throw new NotSupportedException("Nem támogatott média");
        }