improve: docs
This commit is contained in:
@@ -4,39 +4,34 @@
|
|||||||

|

|
||||||

|

|
||||||
|
|
||||||
> **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)!
|
||||||
|
|||||||
Reference in New Issue
Block a user