/// <summary> /// dispatcher timer tick - the view has to be updated /// (Song position, left time, ...) /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void SongProgressTimerTick(object sender, EventArgs e) { int positionInMs = _mediaPlayer.GetSongPosition(); int durationOfSongInMs = _mediaPlayer.GetDurationOfPlayedSong(); ((IPlayerView)View).SetSongProgressSlider(positionInMs, durationOfSongInMs); string totalDuration = TimeSpan.FromMilliseconds(durationOfSongInMs).ToString(@"mm\:ss"); string currentTime = TimeSpan.FromMilliseconds(positionInMs).ToString(@"mm\:ss"); string timeTo = "-" + TimeSpan.FromMilliseconds(durationOfSongInMs - positionInMs).ToString(@"mm\:ss"); string progressOf = currentTime + " | " + totalDuration; ((IPlayerView)View).SetSongProgressToggleButton(progressOf, timeTo); if (_lastSongPositionTimePair == null) { _lastSongPositionTimePair = new Tuple <DateTime, int>(DateTime.Now, positionInMs); } if (positionInMs > 0 && PlaybackPaused == false) { bool haveToHandleEndOfSong = (positionInMs >= durationOfSongInMs); int lastPositionInMs = _lastSongPositionTimePair.Item2; bool fiveHundredMsSinceLastUpdate = (DateTime.Now - _lastSongPositionTimePair.Item1).TotalMilliseconds > 500; if (fiveHundredMsSinceLastUpdate) { _lastSongPositionTimePair = new Tuple <DateTime, int>(DateTime.Now, positionInMs); } // sometimes the karaoke library will state that the song still has some milliseconds to play // but has already stopped playing if (haveToHandleEndOfSong == false && fiveHundredMsSinceLastUpdate && _lastSongPositionTimePair.Item2 == lastPositionInMs ) { haveToHandleEndOfSong = true; } if (haveToHandleEndOfSong) { HandleEndOfSong(); } } }