improve: docs

This commit is contained in:
2026-06-22 12:51:46 +02:00
parent 1f55657390
commit 60871ccd60
+45 -63
View File
@@ -4,39 +4,34 @@
![latest release](https://img.shields.io/badge/dynamic/json?label=release&query=$.name&url=https%3A%2F%2Fapi.github.com%2Frepos%2FFrauJulian%2Fdiscord-audio-stream%2Freleases%2Flatest&color=blue) ![latest release](https://img.shields.io/badge/dynamic/json?label=release&query=$.name&url=https%3A%2F%2Fapi.github.com%2Frepos%2FFrauJulian%2Fdiscord-audio-stream%2Freleases%2Flatest&color=blue)
![GitHub Repo stars](https://img.shields.io/github/stars/FrauJulian/discord-audio-stream?style=social) ![GitHub Repo stars](https://img.shields.io/github/stars/FrauJulian/discord-audio-stream?style=social)
> **Designed for 24/7 Discord audio playback.** `discord-audio-stream` is a small TypeScript library for managed Discord voice playback through
> `discord-audio-stream` is a small TypeScript library for managed Discord voice playback through `@discordjs/voice` and ffmpeg.
> `@discordjs/voice` and ffmpeg.
Discord voice streams need careful lifecycle handling. This package manages the voice connection, ffmpeg process, It manages the Discord voice connection, ffmpeg process, raw PCM audio resource, optional renewal, and cleanup. Keep one
raw PCM resource creation, optional reconnect renewal, and predictable cleanup so your bot code stays small and readable. `AudioManager` per guild, usually in a `Map<string, AudioManager>`, and call `dispose()` when that manager will not be
reused.
> **Recommended best practice:** ## Support
> Keep one `AudioManager` per guild, usually in a `Map<string, AudioManager>`. Update the connection or source through
> `setConnection()` and `setSource()`, then call `start()`. When playback stops, call `stop()`. When the manager will not
> be reused, call `dispose()` to release timers, streams, ffmpeg, and the voice connection.
> **For large bots:** Create an [issue](https://github.com/FrauJulian/Discord-Audio-Stream/issues) on GitHub or contact
> Queue many simultaneous starts, for example with [`p-queue`](https://www.npmjs.com/package/p-queue), so the host does
> not spawn too many ffmpeg processes in the same tick.
## 👋 Support
Please create an [issue](https://github.com/FrauJulian/Discord-Audio-Stream/issues) on GitHub or contact
[`fraujulian`](https://discord.com/users/860206216893693973) on Discord. [`fraujulian`](https://discord.com/users/860206216893693973) on Discord.
## 📝 Usage ## Installation
### Installation Node.js `22.22.3` or newer is required.
**Node.js `22.22.3` or newer is required.**
Install the library and the required voice packages:
```bash ```bash
npm install discord-audio-stream @discordjs/voice prism-media @snazzah/davey opusscript npm install discord-audio-stream @discordjs/voice prism-media @snazzah/davey opusscript
``` ```
`ffmpeg` must be available either on the host PATH or through the optional `ffmpeg-static` package:
```bash
npm install ffmpeg-static
```
Use `ffmpeg.mode: 'native'` for PATH-based ffmpeg and `ffmpeg.mode: 'static'` for `ffmpeg-static`.
`libsodium-wrappers` is optional. Install it only when your runtime does not support `aes-256-gcm`: `libsodium-wrappers` is optional. Install it only when your runtime does not support `aes-256-gcm`:
```bash ```bash
@@ -44,15 +39,7 @@ node -e "console.log(require('node:crypto').getCiphers().includes('aes-256-gcm')
npm install libsodium-wrappers npm install libsodium-wrappers
``` ```
For bundled ffmpeg support, install `ffmpeg-static` and use `ffmpeg.mode: 'static'`: ## Basic Usage
```bash
npm install ffmpeg-static
```
If ffmpeg is already available on the host PATH, use `ffmpeg.mode: 'native'`.
### AudioManager Example
```ts ```ts
import { AudioManager } from 'discord-audio-stream'; import { AudioManager } from 'discord-audio-stream';
@@ -70,7 +57,6 @@ const manager = new AudioManager({
ffmpeg: { ffmpeg: {
mode: 'native', mode: 'native',
}, },
renewIntervalMs: 5_400_000,
}); });
await manager.start(); await manager.start();
@@ -89,9 +75,25 @@ await manager.start();
Relative file paths are resolved from `process.cwd()`. URL sources are validated before playback starts. Relative file paths are resolved from `process.cwd()`. URL sources are validated before playback starts.
## ⚙️ API For large bots, queue many simultaneous starts so the host does not spawn too many ffmpeg processes in the same tick.
### Constructor ## Lifecycle
```ts
manager.setConnection(connectionOptions);
manager.setSource(source);
await manager.start(); // connect() + play()
manager.pause();
manager.resume();
await manager.stop(); // stops playback and destroys the voice connection
manager.dispose(); // final cleanup; the manager cannot be reused
```
`connect()` joins the configured voice channel. `play(source?)` starts playback on an existing connection. Use `start()`
when you want both.
## API
```ts ```ts
type AudioManagerOptions = { type AudioManagerOptions = {
@@ -148,11 +150,9 @@ manager.isPlaying;
manager.isConnected; manager.isConnected;
``` ```
## 🔊 Audio Options ## Audio Options
### Volume Inline volume has runtime cost in `@discordjs/voice`, so it is disabled by default.
Inline volume has a runtime cost in `@discordjs/voice`, so it is disabled by default.
```ts ```ts
const manager = new AudioManager({ const manager = new AudioManager({
@@ -170,33 +170,15 @@ manager.setVolume(25);
Calling `setVolume()` without `volume.enabled: true` throws `AudioManagerStateError`. Calling `setVolume()` without `volume.enabled: true` throws `AudioManagerStateError`.
### ffmpeg Modes Default ffmpeg output is raw Discord-compatible PCM: `s16le`, `48000 Hz`, `2 channels`.
- `mode: 'native'` uses the `ffmpeg` executable from the host environment.
- `mode: 'static'` resolves the optional `ffmpeg-static` package.
- `executablePath` overrides both modes and is useful for Docker images or custom ffmpeg builds.
Default output is raw Discord-compatible PCM: `s16le`, `48000 Hz`, `2 channels`.
You can override ffmpeg arguments through `ffmpeg.inputArgs` and `ffmpeg.outputArgs`. When you override them, you are You can override ffmpeg arguments through `ffmpeg.inputArgs` and `ffmpeg.outputArgs`. When you override them, you are
responsible for keeping the output compatible with `StreamType.Raw`. responsible for keeping the output compatible with `StreamType.Raw`.
### Renewal
By default, the manager schedules a renewal after `5_400_000 ms` so long-running streams can reconnect periodically. By default, the manager schedules a renewal after `5_400_000 ms` so long-running streams can reconnect periodically.
Set `renewIntervalMs: false` to disable this behavior: Set `renewIntervalMs: false` to disable it. `stop()` and `dispose()` always clear the renewal timer.
```ts ## Errors
const manager = new AudioManager({
connection,
source,
renewIntervalMs: false,
});
```
`stop()` and `dispose()` always clear the renewal timer.
## 🧯 Errors
The package exports these error classes: The package exports these error classes:
@@ -208,7 +190,7 @@ The package exports these error classes:
Configuration problems, such as a missing source or invalid URL, throw `AudioManagerConfigError`. Invalid lifecycle Configuration problems, such as a missing source or invalid URL, throw `AudioManagerConfigError`. Invalid lifecycle
operations, such as calling `pause()` while nothing is playing, throw `AudioManagerStateError`. operations, such as calling `pause()` while nothing is playing, throw `AudioManagerStateError`.
## 🧑‍💻 Development ## Development
```bash ```bash
npm ci npm ci
@@ -216,10 +198,10 @@ npm run check
npm run build npm run build
``` ```
## 📋 Contributors ## Contributors
~ [**FrauJulian - Julian Lechner**](https://fraujulian.xyz/) - CODEOWNER ~ [**FrauJulian - Julian Lechner**](https://fraujulian.xyz/) - CODEOWNER
## 🤝 Enjoy the package? ## Enjoy the package?
Give it a star on [GitHub](https://github.com/FrauJulian/discord-audio-stream)! Give it a star on [GitHub](https://github.com/FrauJulian/discord-audio-stream)!