private void PlayStateChanged(object sender, EventArgs e) { EventHandler handlerStoppedPlaying = null; switch (BackgroundAudioPlayer.Instance.PlayerState) { case PlayState.Playing: PodcastEpisodeModel currentEpisode = updateCurrentlyPlayingEpisode(); if (currentEpisode == null) { Debug.WriteLine("Error: No playing episode in DB."); return; } if (CurrentlyPlayingEpisode == null) { CurrentlyPlayingEpisode = currentEpisode; } else if (currentEpisode.EpisodeId != CurrentlyPlayingEpisode.EpisodeId) { CurrentlyPlayingEpisode = currentEpisode; CurrentlyPlayingEpisode.setPlaying(); } if (CurrentlyPlayingEpisode.TotalLengthTicks == 0) { CurrentlyPlayingEpisode.TotalLengthTicks = BackgroundAudioPlayer.Instance.Track.Duration.Ticks; using (var db = new PodcastSqlModel()) { PodcastEpisodeModel episode = db.episodeForEpisodeId(CurrentlyPlayingEpisode.EpisodeId); if (episode == null) { Debug.WriteLine("Warning: Got NULL episode from DB when trying to update this episode."); return; } episode.TotalLengthTicks = CurrentlyPlayingEpisode.TotalLengthTicks; db.SubmitChanges(); PodcastSubscriptionsManager.getInstance().podcastPlaystateChanged(episode.PodcastSubscription); } } break; case PlayState.Paused: BackgroundAudioPlayer playerPaused = BackgroundAudioPlayer.Instance; if (CurrentlyPlayingEpisode != null) { CurrentlyPlayingEpisode = App.refreshEpisodeFromAudioAgent(CurrentlyPlayingEpisode); CurrentlyPlayingEpisode.EpisodePlayState = PodcastEpisodeModel.EpisodePlayStateEnum.Paused; using (var db = new PodcastSqlModel()) { PodcastEpisodeModel updatedEpisode = db.Episodes.FirstOrDefault(ep => ep.EpisodeId == CurrentlyPlayingEpisode.EpisodeId); updatedEpisode.EpisodePlayState = CurrentlyPlayingEpisode.EpisodePlayState; db.SubmitChanges(); } handlerStoppedPlaying = OnPodcastStoppedPlaying; if (handlerStoppedPlaying != null) { OnPodcastStoppedPlaying(this, new EventArgs()); } } else { Debug.WriteLine("SHOULD NOT HAPPEND! Cannot save episode state to paused!"); } break; case PlayState.Stopped: case PlayState.Shutdown: case PlayState.TrackEnded: if (CurrentlyPlayingEpisode == null) { // We didn't have a track playing. return; } // F**K YOU WINDOWS PHONE!! /** * This is so horrible that I can't find other words to describe how bad the BackgroundAudioPlayer * is in Windows Phone! * * First of all the events are fired totally differently between Windows Phone 7 and Windows Phone 8. * Secondly the events related to when tracks end arae totally wrong and horrible! Let me explain: * - We get here the PlayState.Stopped event when the track ends. * - We get the event here BEFORE the AudioAgent gets any events. * - AudioAgent correctly gets the PlayState.TrackEnded event, but it gets it after we have received the * event here. * - We NEVER get the the PlayState.TrackEnded event here. * - Which is not the case for Windows Phone 7, because it first fires PlayState.TrackEnded. * * So this code here is a horrible kludge that just guesses that Windows Phone means "track did end" * when the state is stopped and the play position is still 0. * * Johan, when you return from the future to this piece of code, don't even try to change it or "fix it". **/ long playpos = 0; if (BackgroundAudioPlayer.Instance.PlayerState == PlayState.TrackEnded) { playpos = CurrentlyPlayingEpisode.TotalLengthTicks; } else if (BackgroundAudioPlayer.Instance.PlayerState == PlayState.Stopped && BackgroundAudioPlayer.Instance.Position.Ticks == 0) { playpos = CurrentlyPlayingEpisode.TotalLengthTicks; } else { try { playpos = BackgroundAudioPlayer.Instance.Position.Ticks; } catch (Exception) { Debug.WriteLine("Warning: Player didn't return us a play pos!"); } } CurrentlyPlayingEpisode.SavedPlayPos = playpos; CurrentlyPlayingEpisode.setNoPlaying(); using (var db = new PodcastSqlModel()) { PodcastEpisodeModel savingEpisode = db.Episodes.FirstOrDefault(ep => ep.EpisodeId == CurrentlyPlayingEpisode.EpisodeId); if (savingEpisode != null) { savingEpisode.SavedPlayPos = CurrentlyPlayingEpisode.SavedPlayPos; // Update play state to listened as appropriate. if (savingEpisode.isListened()) { savingEpisode.markAsListened(db.settings().IsAutoDelete); removeFromPlayqueue(savingEpisode); } else { savingEpisode.EpisodePlayState = CurrentlyPlayingEpisode.EpisodePlayState; } db.SubmitChanges(); PodcastSubscriptionsManager.getInstance().podcastPlaystateChanged(savingEpisode.PodcastSubscription); } } PodcastSubscriptionsManager.getInstance().podcastPlaystateChanged(CurrentlyPlayingEpisode.PodcastSubscriptionInstance); handlerStoppedPlaying = OnPodcastStoppedPlaying; if (handlerStoppedPlaying != null) { OnPodcastStoppedPlaying(this, new EventArgs()); } // Cleanup CurrentlyPlayingEpisode = null; break; case PlayState.TrackReady: break; case PlayState.Unknown: // Unknown? WTF. break; } App.mainViewModels.PlayQueue = new System.Collections.ObjectModel.ObservableCollection<PlaylistItem>(); if (CurrentlyPlayingEpisode != null) { PodcastSubscriptionsManager.getInstance().podcastPlaystateChanged(CurrentlyPlayingEpisode.PodcastSubscriptionInstance); } }
private void initializeCurrentlyPlayingEpisode() { // If we have an episodeId stored in local cache, this means we returned to the app and // have that episode playing. Hence, here we need to reload the episode data from the SQL. CurrentlyPlayingEpisode = updateCurrentlyPlayingEpisode(); if (CurrentlyPlayingEpisode != null) { CurrentlyPlayingEpisode.setPlaying(); } }