or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

audio-playback.mdaudio-reception.mddave-encryption.mdindex.mdnetworking.mdutilities.mdvoice-connections.md
tile.json

audio-playback.mddocs/

Audio Playback System

Comprehensive audio playback functionality with support for multiple audio formats, automatic stream processing, advanced playback control, and robust error handling for Discord voice channels.

Capabilities

Audio Player Creation

Creates audio players with configurable behavior for handling subscribers and audio processing.

/**
 * Creates an audio player with optional configuration
 * @param options - Configuration options for player behavior
 * @returns AudioPlayer instance ready for playback
 */
function createAudioPlayer(options?: CreateAudioPlayerOptions): AudioPlayer;

interface CreateAudioPlayerOptions {
  /** Configuration for player behaviors */
  behaviors?: {
    /** Behavior when no voice connections are subscribed */
    noSubscriber?: NoSubscriberBehavior;
    /** Maximum consecutive missed audio frames before considering resource ended */
    maxMissedFrames?: number;
  };
  /** Enable debug messages for this player */
  debug?: boolean;
}

enum NoSubscriberBehavior {
  /** Pause playback when no subscribers (default) */
  Pause = "pause", 
  /** Continue playing even with no subscribers */
  Play = "play",
  /** Stop playback when no subscribers */
  Stop = "stop"
}

Usage Example:

import { createAudioPlayer, NoSubscriberBehavior } from "@discordjs/voice";

// Basic audio player
const player = createAudioPlayer();

// Advanced configuration
const player = createAudioPlayer({
  behaviors: {
    noSubscriber: NoSubscriberBehavior.Play,
    maxMissedFrames: 5,
  },
  debug: true,
});

AudioPlayer Class

Main audio playback controller with state management and event-driven architecture.

class AudioPlayer extends EventEmitter {
  /** Current player state */
  readonly state: AudioPlayerState;
  /** Array of voice connections subscribed to this player */
  readonly playable: VoiceConnection[];

  /** 
   * Play an audio resource
   * @param resource - AudioResource to play
   */
  play<T>(resource: AudioResource<T>): void;

  /** 
   * Pause playback with optional silence interpolation
   * @param interpolateSilence - Whether to play silence frames during pause
   * @returns true if successfully paused, false if not playing
   */
  pause(interpolateSilence?: boolean): boolean;

  /** 
   * Resume playback
   * @returns true if successfully resumed, false if not paused  
   */
  unpause(): boolean;

  /**
   * Stop playback
   * @param force - Whether to force stop even if not playing
   * @returns true if successfully stopped
   */
  stop(force?: boolean): boolean;

  /** Check if player has any playable voice connections */
  checkPlayable(): boolean;
}

// Player state types
type AudioPlayerState = 
  | AudioPlayerIdleState
  | AudioPlayerBufferingState
  | AudioPlayerPlayingState
  | AudioPlayerPausedState;

interface AudioPlayerIdleState {
  status: AudioPlayerStatus.Idle;
}

interface AudioPlayerBufferingState {
  status: AudioPlayerStatus.Buffering;
  resource: AudioResource;
  onReadableCallback: () => void;
  onFailureCallback: () => void;
  onStreamError: (error: Error) => void;
}

interface AudioPlayerPlayingState {
  status: AudioPlayerStatus.Playing;
  resource: AudioResource; 
  playbackDuration: number;
  missedFrames: number;
  onStreamError: (error: Error) => void;
}

interface AudioPlayerPausedState {
  status: AudioPlayerStatus.AutoPaused | AudioPlayerStatus.Paused;
  resource: AudioResource;
  playbackDuration: number;
  silencePacketsRemaining: number;
  onStreamError: (error: Error) => void;
}

Usage Example:

import { AudioPlayerStatus, createAudioResource } from "@discordjs/voice";

const player = createAudioPlayer();

// Handle player events
player.on(AudioPlayerStatus.Playing, () => {
  console.log("Started playing audio");
});

player.on(AudioPlayerStatus.Idle, () => {
  console.log("Audio finished playing");
});

player.on("error", (error) => {
  console.error("Player error:", error);
});

// Play audio
const resource = createAudioResource("./music.mp3");
player.play(resource);

// Control playback
setTimeout(() => player.pause(), 10000); // Pause after 10 seconds
setTimeout(() => player.unpause(), 15000); // Resume after 15 seconds
setTimeout(() => player.stop(), 30000); // Stop after 30 seconds

Audio Resource Creation

Creates audio resources from various input sources with automatic format detection and processing.

/**
 * Creates an audio resource from input with optional configuration
 * @param input - Input stream, file path, or URL
 * @param options - Configuration options for the resource
 * @returns AudioResource ready for playback
 */
function createAudioResource<T>(
  input: Readable | string,
  options?: CreateAudioResourceOptions<T>
): AudioResource<T>;

interface CreateAudioResourceOptions<T> {
  /** Stream type hint for input format */
  inputType?: StreamType;
  /** Metadata to associate with the resource */
  metadata?: T;
  /** Add inline volume control transformer */
  inlineVolume?: boolean;
  /** Number of silence frames to add at end for smooth ending */
  silencePaddingFrames?: number;
}

enum StreamType {
  /** Unknown format - will be probed automatically */
  Arbitrary = "arbitrary",
  /** Raw PCM audio data */
  Raw = "raw", 
  /** Opus audio packets */
  Opus = "opus",
  /** Ogg container with Opus audio */
  OggOpus = "ogg/opus",
  /** WebM container with Opus audio */
  WebmOpus = "webm/opus"
}

Usage Example:

import { createAudioResource, StreamType } from "@discordjs/voice";
import { createReadStream } from "fs";

// From file path (automatic format detection)
const resource = createAudioResource("./music.mp3");

// From stream with format hint
const stream = createReadStream("./audio.ogg");
const resource = createAudioResource(stream, {
  inputType: StreamType.OggOpus,
  metadata: { title: "Background Music", artist: "Example Artist" },
});

// With inline volume control
const resource = createAudioResource("./music.wav", {
  inlineVolume: true,
});

// Adjust volume (only if inlineVolume was enabled)
if (resource.volume) {
  resource.volume.setVolume(0.5); // 50% volume
}

AudioResource Class

Represents an audio resource with stream management and metadata support.

class AudioResource<T = unknown> {
  /** The playable audio stream */
  readonly playStream: Readable;
  /** Transformation pipeline edges */
  readonly edges: readonly Edge[];
  /** Associated metadata */
  metadata: T;
  /** Volume transformer (if inlineVolume was enabled) */
  readonly volume?: VolumeTransformer;
  /** Opus encoder (if required for stream processing) */
  readonly encoder?: OpusEncoder;
  /** Currently associated audio player */
  audioPlayer?: AudioPlayer;
  /** Playback duration in milliseconds */
  playbackDuration: number;
  /** Whether playback has started */
  started: boolean;
  /** Number of silence frames to pad at end */
  readonly silencePaddingFrames: number;
  /** Remaining silence frames to play */
  silenceRemaining: number;

  /** Whether the resource stream is readable */
  get readable(): boolean;
  /** Whether the resource has ended */
  get ended(): boolean;

  /** Read audio data from the resource */
  read(): Buffer | null;
}

Audio Player Status

Enum defining all possible audio player states.

enum AudioPlayerStatus {
  /** No resource loaded, ready to play */
  Idle = "idle",
  /** Loading and preparing resource for playback */
  Buffering = "buffering",
  /** Actively playing audio */
  Playing = "playing", 
  /** Manually paused by user */
  Paused = "paused",
  /** Automatically paused due to no subscribers */
  AutoPaused = "autopaused"
}

Stream Processing and Transformation

Automatic audio format conversion and processing system.

enum TransformerType {
  /** FFmpeg PCM conversion */
  FFmpegPCM = "ffmpeg pcm",
  /** FFmpeg Ogg conversion */
  FFmpegOgg = "ffmpeg ogg",
  /** Opus encoding */
  OpusEncoder = "opus encoder",
  /** Opus decoding */
  OpusDecoder = "opus decoder",
  /** Ogg/Opus demuxing */
  OggOpusDemuxer = "ogg/opus demuxer",
  /** WebM/Opus demuxing */
  WebmOpusDemuxer = "webm/opus demuxer",
  /** Inline volume control */
  InlineVolume = "volume transformer"
}

interface Edge {
  /** Transformation cost (for optimal path selection) */
  cost: number;
  /** Source stream type */
  from: Node;
  /** Target stream type */
  to: Node;
  /** Transformer function */  
  transformer: (input: Readable | string) => Readable;
  /** Type of transformation */
  type: TransformerType;
}

class Node {
  /** Outgoing transformation edges */
  readonly edges: Edge[];
  /** Stream type this node represents */
  readonly type: StreamType;

  /** Add a transformation edge from this node */
  addEdge(edge: Omit<Edge, 'from'>): void;
}

/** Get node for a specific stream type */
function getNode(type: StreamType): Node;

/** Find optimal transformation pipeline between formats */
function findPipeline(from: StreamType, constraint: (path: Edge[]) => boolean): Edge[];

Audio Player Error Handling

Specialized error class for audio player issues with resource context.

class AudioPlayerError extends Error {
  /** The audio resource that caused the error */
  readonly resource: AudioResource;

  constructor(error: Error, resource: AudioResource);
}

Usage Example:

player.on("error", (error) => {
  if (error instanceof AudioPlayerError) {
    console.error("Audio resource error:", error.message);
    console.error("Resource metadata:", error.resource.metadata);
  } else {
    console.error("Player error:", error);
  }
});

Advanced Usage

Resource Stream Probing

Probe audio streams to determine format and compatibility.

import { demuxProbe, validateDiscordOpusHead } from "@discordjs/voice";

const stream = createReadStream("unknown-format.audio");
const probeInfo = await demuxProbe(stream);

console.log("Detected format:", probeInfo.type);
const resource = createAudioResource(probeInfo.stream, {
  inputType: probeInfo.type,
});

Volume Control

Enable and control audio volume during playback.

const resource = createAudioResource("music.mp3", {
  inlineVolume: true,
});

player.play(resource);

// Adjust volume during playback
if (resource.volume) {
  resource.volume.setVolume(0.8); // 80% volume
  resource.volume.setVolumeDecibels(-10); // -10dB
  resource.volume.setVolumeLogarithmic(0.5); // Logarithmic scaling
}

Playback Duration Tracking

Track how long audio has been playing.

player.on(AudioPlayerStatus.Playing, () => {
  const checkDuration = setInterval(() => {
    if (player.state.status === AudioPlayerStatus.Playing) {
      console.log(`Played for: ${player.state.playbackDuration}ms`);
      console.log(`Resource duration: ${player.state.resource.playbackDuration}ms`);
    } else {
      clearInterval(checkDuration);
    }
  }, 1000);
});