/// <summary> /// Pushes a track between the current asynchronously. /// </summary> /// <param name="track">the track to push between the current</param> /// <param name="push"> /// a value indicating whether the track should only played when a track is playing currently. /// </param> /// <remarks> /// Note: This feature is experimental. This will stop playing the current track and /// start playing the specified <paramref name="track"/> after the track is finished the /// track will restart at the stopped position. This can be useful for example /// soundboards (playing an air-horn or something). /// </remarks> /// <returns> /// a task that represents the asynchronous operation. The task result is a value /// indicating whether the track was pushed between the current ( <see /// langword="true"/>) or the specified track was simply started ( <see /// langword="false"/>), because there is no track playing. /// </returns> public virtual async Task <bool> PushTrackAsync(LavalinkTrack track, bool push = false) { // star track immediately if (State == PlayerState.NotPlaying) { if (push) { return(false); } await PlayAsync(track, enqueue : false); return(false); } // create clone and set starting position var oldTrack = CurrentTrack.WithPosition(TrackPosition); // enqueue old track with starting position Queue.Add(oldTrack); // push track await PlayAsync(track, enqueue : false); return(true); }
/// <summary> /// Plays the specified <paramref name="track"/> asynchronously. /// </summary> /// <param name="track">the track to play</param> /// <param name="startTime">the track start position</param> /// <param name="endTime">the track end position</param> /// <param name="noReplace"> /// a value indicating whether the track play should be ignored if the same track is /// currently playing /// </param> /// <returns>a task that represents the asynchronous operation</returns> /// <exception cref="InvalidOperationException"> /// thrown if the player is not connected to a voice channel /// </exception> /// <exception cref="InvalidOperationException">thrown if the player is destroyed</exception> public virtual async Task PlayAsync(LavalinkTrack track, TimeSpan?startTime = null, TimeSpan?endTime = null, bool noReplace = false) { EnsureNotDestroyed(); EnsureConnected(); CurrentTrack = track ?? throw new ArgumentNullException(nameof(track)); startTime = startTime ?? track.Position; await LavalinkSocket.SendPayloadAsync(new PlayerPlayPayload(GuildId, track.Identifier, startTime, endTime, noReplace)); State = PlayerState.Playing; }
/// <summary> /// Skips the current track asynchronously. /// </summary> /// <param name="count">the number of tracks to skip</param> /// <returns>a task that represents the asynchronous operation</returns> /// <exception cref="InvalidOperationException">thrown if the player is destroyed</exception> public virtual Task SkipAsync(int count = 1) { // no tracks to skip if (count <= 0) { return(Task.CompletedTask); } EnsureNotDestroyed(); EnsureConnected(); // the looping option is enabled, repeat current track, does not matter how often we skip if (IsLooping && CurrentTrack != null) { return(PlayAsync(CurrentTrack, false)); } // tracks are enqueued else if (!Queue.IsEmpty) { LavalinkTrack track = null; while (count-- > 0) { // no more tracks in queue if (Queue.Count < 1) { // no tracks found return(DisconnectAsync()); } // dequeue track track = Queue.Dequeue(); } // a track to play was found, dequeue and play return(PlayAsync(track, false)); } // no tracks queued, disconnect if wanted else if (_disconnectOnStop) { return(DisconnectAsync()); } return(Task.CompletedTask); }
/// <summary> /// Plays the specified <paramref name="track"/> at the top of the queue asynchronously. /// </summary> /// <param name="track">the track to play</param> /// <returns>a task that represents the asynchronous operation</returns> /// <exception cref="InvalidOperationException">thrown if the player is destroyed</exception> public virtual async Task PlayTopAsync(LavalinkTrack track) { EnsureNotDestroyed(); if (track is null) { throw new ArgumentNullException(nameof(track)); } // play track if none is playing if (State == PlayerState.NotPlaying) { await PlayAsync(track, enqueue : false); } // the player is currently playing a track, enqueue the track at top else { Queue.Insert(0, track); } }
/// <summary> /// Plays the specified <paramref name="track"/> asynchronously. /// </summary> /// <param name="track">the track to play</param> /// <param name="enqueue"> /// a value indicating whether the track should be enqueued in the track queue /// </param> /// <param name="startTime">the track start position</param> /// <param name="endTime">the track end position</param> /// <param name="noReplace"> /// a value indicating whether the track play should be ignored if the same track is /// currently playing /// </param> /// <returns> /// a task that represents the asynchronous operation /// <para>the position in the track queue ( <c>0</c> = now playing)</para> /// </returns> /// <exception cref="InvalidOperationException">thrown if the player is destroyed</exception> public virtual async Task <int> PlayAsync(LavalinkTrack track, bool enqueue, TimeSpan?startTime = null, TimeSpan?endTime = null, bool noReplace = false) { EnsureNotDestroyed(); EnsureConnected(); // check if the track should be enqueued (if a track is already playing) if (enqueue && State == PlayerState.Playing) { // add the track to the queue Queue.Add(track); // return track queue position return(Queue.Count); } // play the track immediately await base.PlayAsync(track, startTime, endTime, noReplace); // 0 = now playing return(0); }
/// <summary> /// Plays the specified <paramref name="track"/> asynchronously. /// </summary> /// <param name="track">the track to play</param> /// <param name="enqueue"> /// a value indicating whether the track should be enqueued in the track queue /// </param> /// <param name="startTime">the track start position</param> /// <param name="endTime">the track end position</param> /// <param name="noReplace"> /// a value indicating whether the track play should be ignored if the same track is /// currently playing /// </param> /// <returns> /// a task that represents the asynchronous operation /// <para>the position in the track queue ( <c>0</c> = now playing)</para> /// </returns> /// <exception cref="InvalidOperationException">thrown if the player is destroyed</exception> public virtual async Task <int> PlayAsync(LavalinkTrack track, bool enqueue, TimeSpan?startTime = null, TimeSpan?endTime = null, bool noReplace = false) { EnsureNotDestroyed(); EnsureConnected(); if (enqueue && State == PlayerState.Playing) { Queue.Add(track); if (State == PlayerState.NotPlaying) { await SkipAsync(); } return(Queue.Count); } await base.PlayAsync(track, startTime, endTime, noReplace); return(0); }
/// <summary> /// Plays the specified <paramref name="track"/> asynchronously. /// </summary> /// <param name="track">the track to play</param> /// <param name="startTime">the track start position</param> /// <param name="endTime">the track end position</param> /// <param name="noReplace"> /// a value indicating whether the track play should be ignored if the same track is /// currently playing /// </param> /// <returns> /// a task that represents the asynchronous operation /// <para>the position in the track queue ( <c>0</c> = now playing)</para> /// </returns> public new virtual Task <int> PlayAsync(LavalinkTrack track, TimeSpan?startTime = null, TimeSpan?endTime = null, bool noReplace = false) => PlayAsync(track, true, startTime, endTime, noReplace);