using axXez.TS3.Audio;
using axXez.TS3.Protocol;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace axXez.TS3
{
///
/// High-level TeamSpeak voice connection. Extends with audio playback
/// via .
/// The counterpart to for the UDP voice protocol.
///
public class VoiceConnection : VoiceClient, IDisposable
{
private readonly AudioPlayer _player;
/// Handler raised when the current audio track finishes playing.
public delegate void VoiceConnectionTrackEndedHandler(VoiceConnection sender);
/// Raised when the current audio track finishes playing.
public event VoiceConnectionTrackEndedHandler OnTrackEnded;
public bool IsPlaying => _player.IsPlaying;
public bool IsPaused => _player.IsPaused;
public bool IsStreaming => _player.IsStreaming;
public TimeSpan Position => _player.Position;
public TimeSpan Duration => _player.Duration;
public float Volume
{
get => _player.Volume;
set => _player.Volume = value;
}
///
/// Creates a new .
/// Throws if ffmpeg or yt-dlp are not installed.
///
public VoiceConnection(string host, int port = 9987, string nickname = "Bot", VoiceIdentity identity = null, VoiceClientOptions options = null)
: base(host, port, nickname, identity, options)
{
_player = new AudioPlayer(this);
OnDisconnected += _ => _player.Stop();
_player.TrackEnded += () => OnTrackEnded?.Invoke(this);
_player.Error += ex => GlobalLogger.LogError("VoiceConnection", $"Audio error in [{Nickname}]", ex);
}
/// Sends a graceful disconnect to the server and stops the voice client.
public new void Stop()
{
if (State == VoiceClientState.Connected)
Disconnect();
else
base.Stop();
}
/// Converts via ffmpeg and plays it.
public Task PlayFileAsync(string filePath, CancellationToken ct = default)
=> _player.PlayFileAsync(filePath, ct);
/// Resolves a YouTube URL via yt-dlp and streams the audio.
public async Task PlayYouTubeAsync(string url, IReadOnlyList extraArgs = null, CancellationToken ct = default)
{
string direct = await YtDlp.ResolveAsync(url, extraArgs, ct);
_player.PlayStream(direct);
}
/// Streams audio from a direct URL via ffmpeg.
public void PlayStream(string url)
=> _player.PlayStream(url);
public void PausePlayback()
=> _player.Pause();
public void ResumePlayback()
=> _player.Resume();
public void StopPlayback()
=> _player.Stop();
public void Seek(TimeSpan position)
=> _player.Seek(position);
public void Dispose()
{
_player.Stop();
Stop();
}
}
}