/// <summary> /// Handles a track streaming error. Will simulate two seconds of inactivity to appear /// as though the system is attempting to open the file, and, /// if the user has not taken action after the two seconds, finally /// reports the error. In the event that the user changes the track within /// the two seconds or pauses the audio transport, does nothing. /// </summary> /// <exception cref="InvalidOperationException">if <seealso cref="Current"/> is null.</exception> private async void HandleStreamError() { Contract.Requires <InvalidOperationException>(Current != null); _media.Stop(); _media.Source = null; TrackStreamOpened = false; TrackStreamOpenTimeUtc = DateTime.MinValue; Position = TimeSpan.Zero; UniqueTrack errorTrack = CurrentUnique; var currentMutationCount = UserMutationCount; await Task.Delay(2000); // Only advance the track if the user has not taken any intervening action in the mean-time. if (currentMutationCount == UserMutationCount) { // Report the error. OnCurrentTrackFailed(errorTrack); // Remove the track from the queue. RemoveCurrent(); // Play the current track. Replay(); } }
/// <summary> /// Calls the <seealso cref="CurrentTrackFailed"/> event handler if it is non-null. /// </summary> /// <param name="t">The <seealso cref="UniqueTrack"/> encapsulating the <seealso cref="Track"/> whose playback has failed.</param> protected void OnCurrentTrackFailed(UniqueTrack t) { EventHandler <TrackEventArgs> h = CurrentTrackFailed; if (h != null) { h(this, new TrackEventArgs(t)); } }
/// <summary> /// Attemps to start playback of a particular track. /// Its file wille be opened if, and only if, the track can be found. /// Otherwise, nothing will happen. /// </summary> /// <param name="t">The track to play.</param> /// <exception cref="InvalidOperationException">if <seealso cref="Status"/> is <seealso cref="AudioControllerStatus.NotReady"/>.</exception> public void Play(UniqueTrack t) { Contract.Requires <InvalidOperationException>(Status != AudioControllerStatus.NotReady); if (MoveTo(t)) { Status = AudioControllerStatus.Playing; OpenTrackStream(resetPosition: true); } }
/// <summary> /// Removes an upcoming track in the queue. /// Sets UserMutatedQueue to true. /// </summary> /// <param name="t">The track to remove.</param> public bool Remove(UniqueTrack t) { bool removed = _trackList.Remove(t); if (removed) { UserMutatedQueue = true; return(true); } return(false); }
/// <summary> /// Determines whether the specified object is equal to the current object. /// </summary> /// <param name="obj">The object to compare with the current object.</param> /// <returns>true if the specified object is equal to the current object; otherwise, false.</returns> public override bool Equals(object obj) { if (obj is UniqueTrack) { UniqueTrack t = (UniqueTrack)obj; return(Track == t.Track && UniqueId == t.UniqueId); } else { return(false); } }
/// <summary> /// Advances the track queue forward to a specified element is possible. /// If there were no tracks to begin with, does nothing. /// If the last track is hit, clears the queue. /// </summary> /// <param name="t">The track to advance to.</param> /// <returns>If there are no tracks left after advancing, returns false. Otherwise, returns true.</returns> public bool MoveTo(UniqueTrack t) { if (_trackList.Count == 0) { Clear(); } else { int index = _trackList.IndexOf(t); if (index != -1) { _trackList.Dequeue(index); } } return(_trackList.HasCurrent); }
/// <summary> /// Advances the queue to a specific track, if it can be found. /// </summary> /// <param name="t">The track to advance to.</param> /// <returns>Whether the queue's <seealso cref="Current"/> property is non-null.</returns> private bool MoveTo(UniqueTrack t) { return(MutateQueue(() => _queue.MoveTo(t))); }
/// <summary> /// Removes a single track from the queue. /// </summary> /// <param name="t">The track to remove.</param> public void Remove(UniqueTrack t) { MutateQueue(() => _queue.Remove(t)); }
/// <summary> /// Creates a new <seealso cref="TrackEventArgs"/>. /// </summary> /// <param name="t">The <seealso cref="UniqueTrack"/> associated with the previous state.</param> /// <param name="time">Optional. The time when the track started playing.</param> /// <param name="position">Optional. The position of track playback.</param> public TrackEventArgs(UniqueTrack t, DateTime time = new DateTime(), TimeSpan position = new TimeSpan()) { _UniqueTrack = t; _StartTimeUtc = time; _Position = position; }
/// <summary> /// Creates a new <seealso cref="TrackChangedEventArgs"/>. /// </summary> /// <param name="oldTrack">The track that was playing before the track change.</param> /// <param name="newTrack">The track that started playing after the track change.</param> public TrackChangedEventArgs(TrackEventArgs oldTrack, UniqueTrack newTrack) : base(oldTrack.UniqueTrack, oldTrack.StartTimeUtc, oldTrack.Position) { Contract.Requires(oldTrack != null); _NewUniqueTrack = newTrack; }