Пример #1
0
        /// <summary>
        /// Sorts the play queue into a random order.
        /// </summary>
        public void ShufflePlayQueue()
        {
            bool wasPlayingBefore = false;

            if (ToccataModel.MediaPlayerIsPlaying())
            {
                wasPlayingBefore = true;
            }

            this.Stop();

            // Construct a list of all the items in the play queue (we will pull random items off it, in the code below).
            List <PlayableItem> playableItemList = new List <PlayableItem>((IEnumerable <PlayableItem>) this.PlayQueue);

            this.PlayQueue.Clear();

            Random random = new Random();

            while ((uint)playableItemList.Count > 0U)
            {
                int index = 0;
                if (playableItemList.Count > 1)
                {
                    index = random.Next(0, playableItemList.Count);  // pick a random index in the list
                }
                PlayableItem playableItem = playableItemList[index]; // add the random item to the play queue, and remove it from the list.
                playableItemList.RemoveAt(index);
                this.PlayQueue.Add(playableItem);
            }

            if (wasPlayingBefore)
            {
                this.StartPlayingIfAppropriate();
            }
        }
Пример #2
0
        /// <summary>
        /// Stop playing the current track and move it to the history, then start playing the track that is now the top of the play queue.  This is the right
        /// metyhod to call when the 'Next' button is tapped.
        /// </summary>
        public void Next()
        {
            if (this.PlayQueue.Count <= 1) // if there is no queued track, do nothing.  If there is only one queued track, then there is no next track, so do nothing.
            {
                return;
            }

            // This is a bit nasty and hacky - if the next button is pressed repeatedly in quick succession, the player
            // may be transiently paused when the button is pressed for the second, third, ... etc time, as a result of
            // an earlier press.  So our logic for checking whether the player is playing now, and should therefore be
            // restarted after we have skipped forward a track, needs to be careful to ignore those transient state changes.
            // Hence this code, which says we will examine the player state only if the button hasn't already been pressed
            // in the recent past.
            if (_dtNextPressed.AddMilliseconds(500) < DateTime.Now)
            {
                _wasPlayingBeforeNextPressed = ToccataModel.MediaPlayerIsPlaying();
            }
            _dtNextPressed = DateTime.Now;

            this.Stop();
            this.history.Insert(0, this.PlayQueue[0]); // Take the currently playing track (the one at the top of the queue), add it to the history
            this.PlayQueue.RemoveAt(0);                // and remove it from the play queue.

            if (_wasPlayingBeforeNextPressed)
            {
                this.StartPlayingIfAppropriate();
            }
        }
Пример #3
0
        /// <summary>
        /// Remove an item from the play queue.  If it's the top item of the queue, and currently playing, then stop playing it, and
        /// start playing the next on the queue.
        /// </summary>
        /// <param name="i">item to remove</param>
        public void DeleteFromQueue(PlayableItem i)
        {
            if (this.PlayQueue.Count <= 0)
            {
                return;
            }

            bool wasPlayingBefore = false;

            if (ToccataModel.MediaPlayerIsPlaying())
            {
                wasPlayingBefore = true;
            }

            if (this.PlayQueue[0] == i) // if we're removing the top item of the queue (i.e. the current track)
            {
                this.Stop();            // then hard-stop playback
            }
            this.PlayQueue.Remove(i);

            if (wasPlayingBefore)
            {
                this.StartPlayingIfAppropriate();
            }
        }
Пример #4
0
        /// <summary>
        /// Stops playing the current track (if it's playing) and goes back to the start of the previous track we were playing.
        /// </summary>
        public void Back()
        {
            if (this.history.Count <= 0)
            {
                return;
            }

            // This is a bit nasty and hacky - if the back button is pressed repeatedly in quick succession, the player
            // may be transiently paused when the button is pressed for the second, third, ... etc time, as a result of
            // an earlier press.  So our logic for checking whether the player is playing now, and should therefore be
            // restarted after we have skipped back a track, needs to be careful to ignore those transient state changes.
            // Hence this code, which says we will examine the player state only if the button hasn't already been pressed
            // in the recent past.
            if (_dtBackPressed.AddMilliseconds(500) < DateTime.Now)
            {
                _wasPlayingBeforeBackPressed = ToccataModel.MediaPlayerIsPlaying();
            }
            _dtBackPressed = DateTime.Now;


            this.Stop();
            this.PlayQueue.Insert(0, this.history[0]); // Put the top track from ths history list onto the top of the play queue,
            this.history.RemoveAt(0);                  // and remove it from the history list

            if (_wasPlayingBeforeBackPressed)
            {
                this.StartPlayingIfAppropriate();
            }
        }
Пример #5
0
        private static bool _SliderIsBeingManipulated = false; // set to true while the user is manually manipulating the slider
        private void slPosition_SliderManipulationStarted(object sender, EventArgs e)
        {
            MainPage._SliderIsBeingManipulated = true;

            if (ToccataModel.MediaPlayerIsPlaying())
                MainPage._WasPlayingWhenManipulationStarted = true;

            MainViewModel.Instance.Pause();
        }
Пример #6
0
        /// <summary>
        /// Start playing, from the start of the track, if: (1) there is a queued track to play and (2) the player is in the hard-stopped state at the moment
        /// </summary>
        public void StartPlayingIfAppropriate()
        {
            if (this.PlayQueue.Count == 0 || !ToccataModel.MediaPlayerHasNoSource())
            {
                return;
            }

            ToccataModel.Play(this.PlayQueue[0].storage); // start playing the track that is at the top of the queue.
        }
Пример #7
0
 /// <summary>
 /// Starts or restarts playback.
 /// </summary>
 public void Play()
 {
     if (ToccataModel.MediaPlayerHasNoSource()) // if the player has been hard-stopeed, then ...
     {
         if (this.PlayQueue.Count <= 0)
         {
             return;
         }
         ToccataModel.Play(this.PlayQueue[0].storage); // ... play the top track on the queue
     }
     else
     {
         ToccataModel.Play(); // ... else play whatever is currently assigned as the player's source.
     }
 }
Пример #8
0
        /// <summary>
        /// Clears the existing lists of albums and tracks, and then loads a new list of albums for a given artist.
        /// </summary>
        /// <param name="f">the folder whose name is the artist name</param>
        public async void OpenArtistFolder(FolderEntry f)
        {
            this.Albums.Clear();
            this.Tracks.Clear();

            if (string.IsNullOrEmpty(f.DisplayName))
            {
                this.AlbumsFolderLabel = "";
            }
            else
            {
                this.AlbumsFolderLabel = "(in " + f.DisplayName + ")";
            }

            this.TracksFolderLabel = "";

            await ToccataModel.PopulateFolderItems(this.Albums, f.storage as StorageFolder);
        }
Пример #9
0
        /// <summary>
        /// Clears the existing lists of tracks, and then loads a new list of tracks for a given album.
        /// </summary>
        /// <param name="f">the folder whose name is the album name</param>
        public async void OpenAlbumFolder(FolderEntry f)
        {
            this.Tracks.Clear();

            if (string.IsNullOrEmpty(f.DisplayName))
            {
                this.TracksFolderLabel = "";
            }
            else
            {
                this.TracksFolderLabel = "(in " + f.DisplayName + ")";
            }

            await ToccataModel.PopulateFolderItems(this.Tracks, f.storage as StorageFolder);

            if (this.PlayQueue.Count == 0) // if there are no tracks already queued to play,
            {
                this.AddTracks();          // auto-add the ones we just found in this folderto the play queue
            }
        }
Пример #10
0
 /// <summary>
 /// Call this method before trying to play music.
 /// It sets up and reads the root folder (where the list of artists is).  This is initialised to the user's top-level Music
 ///  folder, but can be changed.  Also it sets up the media player.
 /// </summary>
 public void Initialise()
 {
     this.RootFolder = KnownFolders.MusicLibrary; // a side-effect in the accessor will cause the folder to be read in to the Artists list.
     ToccataModel.SetUpMediaPlayer();
 }
Пример #11
0
        //private DispatcherTimer _dtimer = null;
        private async void ThrottledPlaybackStateChanged(MediaPlayer player)
        {
            if (_playbackStateChangePending)
            {
                // A change has already been noted, and the 'state changed' handler will get called anyway some time within the next 100ms
                return;
            }
            else
            {
                _playbackStateChangePending = true;

                await Task.Delay(100); // allow 100ms for subsequent state changes to come in

                _playbackStateChangePending = false;

                //
                // Now adjust the appearance of the Pause/Play button as needed, and kick off playback of the next track in the queue, if there is one.
                //
                if (player.PlaybackSession == null) // error - never started
                {
                }
                else if (player.PlaybackSession.PlaybackState == MediaPlaybackState.Paused)
                {
                    bool trackFinished = false; //at the end of a track?
                    if (player.PlaybackSession.Position != TimeSpan.Zero && player.PlaybackSession.Position.Add(TimeSpan.FromSeconds(1)) >= player.PlaybackSession.NaturalDuration)
                    {
                        // Position is not at the start of the media, and is equal/near to the duration of the player's media,
                        // This means we are at the end of a track
                        trackFinished = true;
                    }

                    MainPage.SetPlayButtonAppearance(false);              // Set the Play button to display a "play" label, and do 'play' when tapped.

                    if (trackFinished)                                    // paused, and at the end of a track
                    {
                        MainPage.SetNowPlaying("");                       // "***FINISHED: " + player.PlaybackSession.PlaybackState.ToString() + " " + player.PlaybackSession.Position.TotalSeconds.ToString() + "/" + player.PlaybackSession.NaturalDuration.TotalSeconds.ToString()); // set the text label at the bottom of the slider to blank.

                        if (PlayQueue.Count > 0)                          // (this is just defensive coding, it should always be true)
                        {
                            PlayQueue.RemoveAt(0);                        // We've finished this track, so remove it from the top of the play queue.
                        }
                        if (PlayQueue.Count > 0)                          // if there is now a track at the top of the queue ...
                        {
                            ToccataModel.Play(this.PlayQueue[0].storage); // ... start playing it.
                        }
                        else
                        {
                            ToccataModel.Stop(); // ... otherwise, we should hard-stop the player, leaving it ready to play something, when something is queued up.
                        }
                    }
                    else // paused but not finished the track - e.g. because the user tapped the Pause button.
                    {
                        // MainPage.SetNowPlaying("***PAUSED: " + player.PlaybackSession.PlaybackState.ToString()+" "+ player.PlaybackSession.Position.TotalSeconds.ToString()+"/"+ player.PlaybackSession.NaturalDuration.TotalSeconds.ToString());
                    }
                }
                else // playing, buffering, opening, none, or whatever
                {
                    if (player.PlaybackSession.PlaybackState == MediaPlaybackState.Playing)
                    {
                        MainPage.SetPlayButtonAppearance(true); // Set the Play button to display a "pause" label, and do 'pause' when tapped.
                    }
                    else // could be 'buffering', 'opening' or 'none' - anyhow, it's a state in which the media is not (yet) playing.
                    {
                        MainPage.SetPlayButtonAppearance(false); // Set the Play button to display a "play" label, and do 'play' when tapped.
                    }

                    if (PlayQueue.Count > 0) // (this is just defensive coding, it should always be true)
                    {
                        MainPage.SetNowPlaying(PlayQueue[0].DisplayName + " (" + PlayQueue[0].storage.Path + ")");
                    }
                }
            }
        }
Пример #12
0
 /// <summary>
 /// Set the playback position.
 /// </summary>
 /// <param name="t">playback position to set</param>
 public void SetPlayerPosition(TimeSpan t)
 {
     ToccataModel.SetPlayerPosition(t);
 }
Пример #13
0
 /// <summary>
 /// Stop playback and empty the play queue.
 /// </summary>
 public void ClearQueue()
 {
     ToccataModel.Stop();
     this.PlayQueue.Clear();
 }
Пример #14
0
 /// <summary>
 /// Pauses playback (which is to say, stops it, but does not hard-stop it).
 /// </summary>
 public void Pause()
 {
     ToccataModel.Pause();
 }
Пример #15
0
 /// <summary>
 /// Stops the media player (it puts it into the 'hard-stopped' state).
 /// </summary>
 public void Stop()
 {
     ToccataModel.Stop();
 }