コード例 #1
0
 /// <summary>
 /// Add a song to the end of the queue. Handle both youtube and local files.
 /// </summary>
 /// <param name="item"></param>
 public static void PlayLast(Song item)
 {
     if (!item.IsYt)
     {
         LocalManager.PlayLast(item.Path);
     }
     else
     {
         YoutubeManager.PlayLast(item);
     }
 }
コード例 #2
0
        /// <summary>
        /// Method that complete the song you give to make it playable with the player. Used only for youtube songs but you can give local songs here, that won't hurt.
        /// </summary>
        /// <param name="song">The song you want to complete</param>
        /// <param name="position">If the song is in the queue, set this parameter to the song's queue position. It will give display callbacks.</param>
        /// <param name="startPlaybackWhenPosible">Set this to true if you want to start playing the song before the end of this method.</param>
        /// <param name="forceParse">Set this to true if you want this method to retrieve steams info from youtube even if the song said that it is already parsed.</param>
        /// <returns></returns>
        public async Task <Song> ParseSong(Song song, int position = -1, bool startPlaybackWhenPosible = false, bool forceParse = false)
        {
            queuePosition = position;
            if (startPlaybackWhenPosible)
            {
                playPosition = position;
                Queue.instance.RefreshCurrent();
            }

            if ((!forceParse && song.IsParsed == true) || !song.IsYt)
            {
                if (startPlaybackWhenPosible)
                {
                    MusicPlayer.instance.Play(song, -1, queuePosition == -1);
                }

                return(song);
            }

            if (song.IsParsed == null)
            {
                while (song.IsParsed == null)
                {
                    await Task.Delay(10);
                }

                if (canceled)
                {
                    return(song);
                }

                if (playPosition == queuePosition && (await MusicPlayer.GetItem()).YoutubeID != song.YoutubeID)
                {
                    MusicPlayer.instance.Play(song, -1, queuePosition == -1);
                }

                return(song); //Song is a class, the youtube id will be updated with another method
            }

            try
            {
                song.IsParsed = null;
                YoutubeClient client          = new YoutubeClient();
                var           mediaStreamInfo = await client.GetVideoMediaStreamInfosAsync(song.YoutubeID);

                if (mediaStreamInfo.HlsLiveStreamUrl != null)
                {
                    song.Path         = mediaStreamInfo.HlsLiveStreamUrl;
                    song.IsLiveStream = true;
                }
                else
                {
                    song.IsLiveStream = false;

                    if (mediaStreamInfo.Audio.Count > 0)
                    {
                        song.Path = mediaStreamInfo.Audio.OrderBy(s => s.Bitrate).Last().Url;
                    }
                    else if (mediaStreamInfo.Muxed.Count > 0)
                    {
                        song.Path = mediaStreamInfo.Muxed.OrderBy(x => x.Resolution).Last().Url;
                    }
                    else
                    {
                        MainActivity.instance.NotStreamable(song.Title);
                        return(null);
                    }

                    song.ExpireDate = mediaStreamInfo.ValidUntil;
                }
                song.IsParsed = true;

                if (queuePosition != -1)
                {
                    Queue.instance?.NotifyItemChanged(queuePosition, Resource.Drawable.PublicIcon);
                }

                if (canceled)
                {
                    return(song);
                }

                if (playPosition == queuePosition && song.Album != null)
                {
                    playPosition = -2;
                    if (queuePosition != -1)
                    {
                        MusicPlayer.currentID = queuePosition;
                        Queue.instance?.RefreshCurrent();
                        Player.instance?.RefreshPlayer();
                    }

                    MusicPlayer.instance.Play(song, -1, queuePosition == -1);
                }

                Video video = await client.GetVideoAsync(song.YoutubeID);

                song.Title  = video.Title;
                song.Artist = video.Author;
                song.Album  = await YoutubeManager.GetBestThumb(video.Thumbnails);

                song.Duration = (int)video.Duration.TotalMilliseconds;

                if (queuePosition == MusicPlayer.CurrentID())
                {
                    Player.instance?.RefreshPlayer();
                }

                if (queuePosition != -1)
                {
                    Queue.instance?.NotifyItemChanged(queuePosition, song.Artist);
                    Home.instance?.NotifyQueueChanged(queuePosition, song.Artist);
                }

                if (canceled)
                {
                    return(song);
                }

                if (playPosition == queuePosition)
                {
                    MusicPlayer.instance.Play(song, -1, queuePosition == -1);
                }
            }
            catch (System.Net.Http.HttpRequestException)
            {
                Console.WriteLine("&Parse time out");
                if (MainActivity.instance != null)
                {
                    MainActivity.instance.FindViewById <ProgressBar>(Resource.Id.ytProgress).Visibility = ViewStates.Gone;
                }
                song.IsParsed = false;

                if (playPosition == queuePosition)
                {
                    playPosition = -2;
                    Queue.instance.RefreshCurrent();
                    Player.instance?.Ready();
                    MainActivity.instance.Timout();
                }
            }
            catch (YoutubeExplode.Exceptions.VideoUnplayableException ex)
            {
                Console.WriteLine("&Parse error: " + ex.Message);
                MainActivity.instance.Unplayable(ErrorCode.SP2, song.Title, ex.Message);
                if (MainActivity.instance != null)
                {
                    MainActivity.instance.FindViewById <ProgressBar>(Resource.Id.ytProgress).Visibility = ViewStates.Gone;
                }

                song.IsParsed = false;
                if (queuePosition != -1)
                {
                    MusicPlayer.RemoveFromQueue(queuePosition); //Remove the song from the queue since it can't be played.
                }
                if (playPosition == queuePosition)
                {
                    playPosition = -2;
                    Queue.instance.RefreshCurrent();
                    Player.instance?.Ready();
                }
            }
            catch (YoutubeExplode.Exceptions.VideoUnavailableException)
            {
                MainActivity.instance.NotStreamable(song.Title);
                if (MainActivity.instance != null)
                {
                    MainActivity.instance.FindViewById <ProgressBar>(Resource.Id.ytProgress).Visibility = ViewStates.Gone;
                }

                song.IsParsed = false;
                if (queuePosition != -1)
                {
                    MusicPlayer.RemoveFromQueue(queuePosition); //Remove the song from the queue since it can't be played.
                }
                if (playPosition == queuePosition)
                {
                    playPosition = -2;
                    Queue.instance.RefreshCurrent();
                    Player.instance?.Ready();
                }
            }
            catch //We use this because when the network is reseted, an unknow error is thrown. We also don't want the app to crash at this state so it's ok to use a global catch.
            {
                song.IsParsed = false;

                if (MainActivity.instance != null)
                {
                    MainActivity.instance.FindViewById <ProgressBar>(Resource.Id.ytProgress).Visibility = ViewStates.Gone;
                }

                if (playPosition == queuePosition)
                {
                    playPosition = -2;
                    Queue.instance.RefreshCurrent();
                    Player.instance?.Ready();
                    MainActivity.instance.UnknowError(ErrorCode.SP1, null, Snackbar.LengthLong);
                }
            }

            if (playPosition == queuePosition)
            {
                playPosition = -2;
            }
            queuePosition = -1;
            instances.Remove(this);
            return(song);
        }