@fluxerjs/voice 1.3.0 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +14 -6
- package/dist/index.d.ts +14 -6
- package/dist/index.js +48 -20
- package/dist/index.mjs +48 -20
- package/package.json +5 -5
package/dist/index.d.mts
CHANGED
|
@@ -42,12 +42,17 @@ declare class VoiceConnection extends EventEmitter {
|
|
|
42
42
|
private setupUDP;
|
|
43
43
|
/**
|
|
44
44
|
* Play a stream of raw Opus packets
|
|
45
|
-
* Uses the same queue and 20ms pacing as play(). Use this for
|
|
45
|
+
* Uses the same queue and 20ms pacing as play(). Use this for raw Opus packet streams (e.g. MP3 → PCM → Opus pipelines) when you are not using WebM/Opus.
|
|
46
46
|
*/
|
|
47
47
|
playOpus(stream: NodeJS.ReadableStream): void;
|
|
48
48
|
/**
|
|
49
|
-
* Play a direct WebM/Opus
|
|
50
|
-
*
|
|
49
|
+
* Play a direct WebM/Opus source. When `urlOrStream` is a string:
|
|
50
|
+
* - `http://` / `https://` — fetched over the network
|
|
51
|
+
* - `file://` — read from the local filesystem
|
|
52
|
+
* - any other string — treated as a filesystem path (e.g. `./music/track.webm`)
|
|
53
|
+
*
|
|
54
|
+
* You can also pass a Node.js Readable stream. Demuxes with prism-media WebmDemuxer; no FFmpeg;
|
|
55
|
+
* input must be WebM with Opus.
|
|
51
56
|
*/
|
|
52
57
|
play(urlOrStream: string | NodeJS.ReadableStream): Promise<void>;
|
|
53
58
|
private sendAudioFrame;
|
|
@@ -222,10 +227,13 @@ declare class LiveKitRtcConnection extends EventEmitter {
|
|
|
222
227
|
*/
|
|
223
228
|
private playVideoFFmpeg;
|
|
224
229
|
/**
|
|
225
|
-
* Play audio from a WebM/Opus
|
|
230
|
+
* Play audio from a WebM/Opus source. Publishes to the LiveKit room as an audio track.
|
|
231
|
+
*
|
|
232
|
+
* When `urlOrStream` is a string: `http(s)://` is fetched; `file://` or any other string is read
|
|
233
|
+
* from the local filesystem (path). Otherwise pass a Node.js ReadableStream.
|
|
226
234
|
*
|
|
227
|
-
* @param urlOrStream -
|
|
228
|
-
* @emits error - On fetch failure or decode errors
|
|
235
|
+
* @param urlOrStream - WebM/Opus HTTP(S) URL, `file://` URL, filesystem path, or ReadableStream
|
|
236
|
+
* @emits error - On fetch/read failure or decode errors
|
|
229
237
|
*/
|
|
230
238
|
play(urlOrStream: string | NodeJS.ReadableStream): Promise<void>;
|
|
231
239
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -42,12 +42,17 @@ declare class VoiceConnection extends EventEmitter {
|
|
|
42
42
|
private setupUDP;
|
|
43
43
|
/**
|
|
44
44
|
* Play a stream of raw Opus packets
|
|
45
|
-
* Uses the same queue and 20ms pacing as play(). Use this for
|
|
45
|
+
* Uses the same queue and 20ms pacing as play(). Use this for raw Opus packet streams (e.g. MP3 → PCM → Opus pipelines) when you are not using WebM/Opus.
|
|
46
46
|
*/
|
|
47
47
|
playOpus(stream: NodeJS.ReadableStream): void;
|
|
48
48
|
/**
|
|
49
|
-
* Play a direct WebM/Opus
|
|
50
|
-
*
|
|
49
|
+
* Play a direct WebM/Opus source. When `urlOrStream` is a string:
|
|
50
|
+
* - `http://` / `https://` — fetched over the network
|
|
51
|
+
* - `file://` — read from the local filesystem
|
|
52
|
+
* - any other string — treated as a filesystem path (e.g. `./music/track.webm`)
|
|
53
|
+
*
|
|
54
|
+
* You can also pass a Node.js Readable stream. Demuxes with prism-media WebmDemuxer; no FFmpeg;
|
|
55
|
+
* input must be WebM with Opus.
|
|
51
56
|
*/
|
|
52
57
|
play(urlOrStream: string | NodeJS.ReadableStream): Promise<void>;
|
|
53
58
|
private sendAudioFrame;
|
|
@@ -222,10 +227,13 @@ declare class LiveKitRtcConnection extends EventEmitter {
|
|
|
222
227
|
*/
|
|
223
228
|
private playVideoFFmpeg;
|
|
224
229
|
/**
|
|
225
|
-
* Play audio from a WebM/Opus
|
|
230
|
+
* Play audio from a WebM/Opus source. Publishes to the LiveKit room as an audio track.
|
|
231
|
+
*
|
|
232
|
+
* When `urlOrStream` is a string: `http(s)://` is fetched; `file://` or any other string is read
|
|
233
|
+
* from the local filesystem (path). Otherwise pass a Node.js ReadableStream.
|
|
226
234
|
*
|
|
227
|
-
* @param urlOrStream -
|
|
228
|
-
* @emits error - On fetch failure or decode errors
|
|
235
|
+
* @param urlOrStream - WebM/Opus HTTP(S) URL, `file://` URL, filesystem path, or ReadableStream
|
|
236
|
+
* @emits error - On fetch/read failure or decode errors
|
|
229
237
|
*/
|
|
230
238
|
play(urlOrStream: string | NodeJS.ReadableStream): Promise<void>;
|
|
231
239
|
/**
|
package/dist/index.js
CHANGED
|
@@ -53,7 +53,9 @@ var import_util = require("@fluxerjs/util");
|
|
|
53
53
|
var nacl = __toESM(require("tweetnacl"));
|
|
54
54
|
var dgram = __toESM(require("dgram"));
|
|
55
55
|
var ws = __toESM(require("ws"));
|
|
56
|
+
var import_node_fs = require("fs");
|
|
56
57
|
var import_node_stream = require("stream");
|
|
58
|
+
var import_node_url = require("url");
|
|
57
59
|
var import_prism_media = require("prism-media");
|
|
58
60
|
var VOICE_WS_OPCODES = {
|
|
59
61
|
Identify: 0,
|
|
@@ -257,7 +259,7 @@ var VoiceConnection = class extends import_events.EventEmitter {
|
|
|
257
259
|
}
|
|
258
260
|
/**
|
|
259
261
|
* Play a stream of raw Opus packets
|
|
260
|
-
* Uses the same queue and 20ms pacing as play(). Use this for
|
|
262
|
+
* Uses the same queue and 20ms pacing as play(). Use this for raw Opus packet streams (e.g. MP3 → PCM → Opus pipelines) when you are not using WebM/Opus.
|
|
261
263
|
*/
|
|
262
264
|
playOpus(stream) {
|
|
263
265
|
this.stop();
|
|
@@ -293,22 +295,35 @@ var VoiceConnection = class extends import_events.EventEmitter {
|
|
|
293
295
|
});
|
|
294
296
|
}
|
|
295
297
|
/**
|
|
296
|
-
* Play a direct WebM/Opus
|
|
297
|
-
*
|
|
298
|
+
* Play a direct WebM/Opus source. When `urlOrStream` is a string:
|
|
299
|
+
* - `http://` / `https://` — fetched over the network
|
|
300
|
+
* - `file://` — read from the local filesystem
|
|
301
|
+
* - any other string — treated as a filesystem path (e.g. `./music/track.webm`)
|
|
302
|
+
*
|
|
303
|
+
* You can also pass a Node.js Readable stream. Demuxes with prism-media WebmDemuxer; no FFmpeg;
|
|
304
|
+
* input must be WebM with Opus.
|
|
298
305
|
*/
|
|
299
306
|
async play(urlOrStream) {
|
|
300
307
|
this.stop();
|
|
301
308
|
let inputStream;
|
|
302
309
|
if (typeof urlOrStream === "string") {
|
|
303
310
|
try {
|
|
304
|
-
const
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
311
|
+
const spec = urlOrStream.trim();
|
|
312
|
+
const lower = spec.toLowerCase();
|
|
313
|
+
if (lower.startsWith("http://") || lower.startsWith("https://")) {
|
|
314
|
+
const response = await fetch(spec);
|
|
315
|
+
if (!response.ok) {
|
|
316
|
+
throw new import_util.FluxerError(`HTTP ${response.status}`, { code: import_util.ErrorCodes.VoiceHttpError });
|
|
317
|
+
}
|
|
318
|
+
if (!response.body) {
|
|
319
|
+
throw new import_util.FluxerError("No response body", { code: import_util.ErrorCodes.VoiceNoResponseBody });
|
|
320
|
+
}
|
|
321
|
+
inputStream = import_node_stream.Readable.fromWeb(response.body);
|
|
322
|
+
} else if (lower.startsWith("file:")) {
|
|
323
|
+
inputStream = (0, import_node_fs.createReadStream)((0, import_node_url.fileURLToPath)(new URL(spec)));
|
|
324
|
+
} else {
|
|
325
|
+
inputStream = (0, import_node_fs.createReadStream)(spec);
|
|
310
326
|
}
|
|
311
|
-
inputStream = import_node_stream.Readable.fromWeb(response.body);
|
|
312
327
|
} catch (e) {
|
|
313
328
|
const err = e instanceof import_util.FluxerError ? e : new import_util.FluxerError(e instanceof Error ? e.message : String(e), {
|
|
314
329
|
code: import_util.ErrorCodes.FileFetchFailed,
|
|
@@ -504,7 +519,9 @@ function concatUint8Arrays(a, b) {
|
|
|
504
519
|
}
|
|
505
520
|
|
|
506
521
|
// src/LiveKitRtcConnection.ts
|
|
522
|
+
var import_node_fs2 = require("fs");
|
|
507
523
|
var import_node_stream2 = require("stream");
|
|
524
|
+
var import_node_url2 = require("url");
|
|
508
525
|
var import_opus_decoder = require("opus-decoder");
|
|
509
526
|
var import_prism_media2 = require("prism-media");
|
|
510
527
|
var import_node_util = require("util");
|
|
@@ -1698,10 +1715,13 @@ var LiveKitRtcConnection = class extends import_events2.EventEmitter {
|
|
|
1698
1715
|
runFFmpeg().catch((e) => this.audioDebug("ffmpeg error", { error: String(e) }));
|
|
1699
1716
|
}
|
|
1700
1717
|
/**
|
|
1701
|
-
* Play audio from a WebM/Opus
|
|
1718
|
+
* Play audio from a WebM/Opus source. Publishes to the LiveKit room as an audio track.
|
|
1719
|
+
*
|
|
1720
|
+
* When `urlOrStream` is a string: `http(s)://` is fetched; `file://` or any other string is read
|
|
1721
|
+
* from the local filesystem (path). Otherwise pass a Node.js ReadableStream.
|
|
1702
1722
|
*
|
|
1703
|
-
* @param urlOrStream -
|
|
1704
|
-
* @emits error - On fetch failure or decode errors
|
|
1723
|
+
* @param urlOrStream - WebM/Opus HTTP(S) URL, `file://` URL, filesystem path, or ReadableStream
|
|
1724
|
+
* @emits error - On fetch/read failure or decode errors
|
|
1705
1725
|
*/
|
|
1706
1726
|
async play(urlOrStream) {
|
|
1707
1727
|
this.stop();
|
|
@@ -1712,14 +1732,22 @@ var LiveKitRtcConnection = class extends import_events2.EventEmitter {
|
|
|
1712
1732
|
let inputStream;
|
|
1713
1733
|
if (typeof urlOrStream === "string") {
|
|
1714
1734
|
try {
|
|
1715
|
-
const
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1735
|
+
const spec = urlOrStream.trim();
|
|
1736
|
+
const lower = spec.toLowerCase();
|
|
1737
|
+
if (lower.startsWith("http://") || lower.startsWith("https://")) {
|
|
1738
|
+
const response = await fetch(spec);
|
|
1739
|
+
if (!response.ok) {
|
|
1740
|
+
throw new import_util2.FluxerError(`HTTP ${response.status}`, { code: import_util2.ErrorCodes.VoiceHttpError });
|
|
1741
|
+
}
|
|
1742
|
+
if (!response.body) {
|
|
1743
|
+
throw new import_util2.FluxerError("No response body", { code: import_util2.ErrorCodes.VoiceNoResponseBody });
|
|
1744
|
+
}
|
|
1745
|
+
inputStream = import_node_stream2.Readable.fromWeb(response.body);
|
|
1746
|
+
} else if (lower.startsWith("file:")) {
|
|
1747
|
+
inputStream = (0, import_node_fs2.createReadStream)((0, import_node_url2.fileURLToPath)(new URL(spec)));
|
|
1748
|
+
} else {
|
|
1749
|
+
inputStream = (0, import_node_fs2.createReadStream)(spec);
|
|
1721
1750
|
}
|
|
1722
|
-
inputStream = import_node_stream2.Readable.fromWeb(response.body);
|
|
1723
1751
|
} catch (e) {
|
|
1724
1752
|
const err = e instanceof import_util2.FluxerError ? e : new import_util2.FluxerError(e instanceof Error ? e.message : String(e), {
|
|
1725
1753
|
code: import_util2.ErrorCodes.FileFetchFailed,
|
package/dist/index.mjs
CHANGED
|
@@ -13,7 +13,9 @@ import { ErrorCodes, FluxerError } from "@fluxerjs/util";
|
|
|
13
13
|
import * as nacl from "tweetnacl";
|
|
14
14
|
import * as dgram from "dgram";
|
|
15
15
|
import * as ws from "ws";
|
|
16
|
+
import { createReadStream } from "fs";
|
|
16
17
|
import { Readable } from "stream";
|
|
18
|
+
import { fileURLToPath } from "url";
|
|
17
19
|
import { opus } from "prism-media";
|
|
18
20
|
var VOICE_WS_OPCODES = {
|
|
19
21
|
Identify: 0,
|
|
@@ -217,7 +219,7 @@ var VoiceConnection = class extends EventEmitter {
|
|
|
217
219
|
}
|
|
218
220
|
/**
|
|
219
221
|
* Play a stream of raw Opus packets
|
|
220
|
-
* Uses the same queue and 20ms pacing as play(). Use this for
|
|
222
|
+
* Uses the same queue and 20ms pacing as play(). Use this for raw Opus packet streams (e.g. MP3 → PCM → Opus pipelines) when you are not using WebM/Opus.
|
|
221
223
|
*/
|
|
222
224
|
playOpus(stream) {
|
|
223
225
|
this.stop();
|
|
@@ -253,22 +255,35 @@ var VoiceConnection = class extends EventEmitter {
|
|
|
253
255
|
});
|
|
254
256
|
}
|
|
255
257
|
/**
|
|
256
|
-
* Play a direct WebM/Opus
|
|
257
|
-
*
|
|
258
|
+
* Play a direct WebM/Opus source. When `urlOrStream` is a string:
|
|
259
|
+
* - `http://` / `https://` — fetched over the network
|
|
260
|
+
* - `file://` — read from the local filesystem
|
|
261
|
+
* - any other string — treated as a filesystem path (e.g. `./music/track.webm`)
|
|
262
|
+
*
|
|
263
|
+
* You can also pass a Node.js Readable stream. Demuxes with prism-media WebmDemuxer; no FFmpeg;
|
|
264
|
+
* input must be WebM with Opus.
|
|
258
265
|
*/
|
|
259
266
|
async play(urlOrStream) {
|
|
260
267
|
this.stop();
|
|
261
268
|
let inputStream;
|
|
262
269
|
if (typeof urlOrStream === "string") {
|
|
263
270
|
try {
|
|
264
|
-
const
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
271
|
+
const spec = urlOrStream.trim();
|
|
272
|
+
const lower = spec.toLowerCase();
|
|
273
|
+
if (lower.startsWith("http://") || lower.startsWith("https://")) {
|
|
274
|
+
const response = await fetch(spec);
|
|
275
|
+
if (!response.ok) {
|
|
276
|
+
throw new FluxerError(`HTTP ${response.status}`, { code: ErrorCodes.VoiceHttpError });
|
|
277
|
+
}
|
|
278
|
+
if (!response.body) {
|
|
279
|
+
throw new FluxerError("No response body", { code: ErrorCodes.VoiceNoResponseBody });
|
|
280
|
+
}
|
|
281
|
+
inputStream = Readable.fromWeb(response.body);
|
|
282
|
+
} else if (lower.startsWith("file:")) {
|
|
283
|
+
inputStream = createReadStream(fileURLToPath(new URL(spec)));
|
|
284
|
+
} else {
|
|
285
|
+
inputStream = createReadStream(spec);
|
|
270
286
|
}
|
|
271
|
-
inputStream = Readable.fromWeb(response.body);
|
|
272
287
|
} catch (e) {
|
|
273
288
|
const err = e instanceof FluxerError ? e : new FluxerError(e instanceof Error ? e.message : String(e), {
|
|
274
289
|
code: ErrorCodes.FileFetchFailed,
|
|
@@ -478,7 +493,9 @@ function concatUint8Arrays(a, b) {
|
|
|
478
493
|
}
|
|
479
494
|
|
|
480
495
|
// src/LiveKitRtcConnection.ts
|
|
496
|
+
import { createReadStream as createReadStream2 } from "fs";
|
|
481
497
|
import { Readable as Readable2 } from "stream";
|
|
498
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
482
499
|
import { OpusDecoder } from "opus-decoder";
|
|
483
500
|
import { opus as opus2 } from "prism-media";
|
|
484
501
|
import { promisify } from "util";
|
|
@@ -1672,10 +1689,13 @@ var LiveKitRtcConnection = class extends EventEmitter2 {
|
|
|
1672
1689
|
runFFmpeg().catch((e) => this.audioDebug("ffmpeg error", { error: String(e) }));
|
|
1673
1690
|
}
|
|
1674
1691
|
/**
|
|
1675
|
-
* Play audio from a WebM/Opus
|
|
1692
|
+
* Play audio from a WebM/Opus source. Publishes to the LiveKit room as an audio track.
|
|
1693
|
+
*
|
|
1694
|
+
* When `urlOrStream` is a string: `http(s)://` is fetched; `file://` or any other string is read
|
|
1695
|
+
* from the local filesystem (path). Otherwise pass a Node.js ReadableStream.
|
|
1676
1696
|
*
|
|
1677
|
-
* @param urlOrStream -
|
|
1678
|
-
* @emits error - On fetch failure or decode errors
|
|
1697
|
+
* @param urlOrStream - WebM/Opus HTTP(S) URL, `file://` URL, filesystem path, or ReadableStream
|
|
1698
|
+
* @emits error - On fetch/read failure or decode errors
|
|
1679
1699
|
*/
|
|
1680
1700
|
async play(urlOrStream) {
|
|
1681
1701
|
this.stop();
|
|
@@ -1686,14 +1706,22 @@ var LiveKitRtcConnection = class extends EventEmitter2 {
|
|
|
1686
1706
|
let inputStream;
|
|
1687
1707
|
if (typeof urlOrStream === "string") {
|
|
1688
1708
|
try {
|
|
1689
|
-
const
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1709
|
+
const spec = urlOrStream.trim();
|
|
1710
|
+
const lower = spec.toLowerCase();
|
|
1711
|
+
if (lower.startsWith("http://") || lower.startsWith("https://")) {
|
|
1712
|
+
const response = await fetch(spec);
|
|
1713
|
+
if (!response.ok) {
|
|
1714
|
+
throw new FluxerError2(`HTTP ${response.status}`, { code: ErrorCodes2.VoiceHttpError });
|
|
1715
|
+
}
|
|
1716
|
+
if (!response.body) {
|
|
1717
|
+
throw new FluxerError2("No response body", { code: ErrorCodes2.VoiceNoResponseBody });
|
|
1718
|
+
}
|
|
1719
|
+
inputStream = Readable2.fromWeb(response.body);
|
|
1720
|
+
} else if (lower.startsWith("file:")) {
|
|
1721
|
+
inputStream = createReadStream2(fileURLToPath2(new URL(spec)));
|
|
1722
|
+
} else {
|
|
1723
|
+
inputStream = createReadStream2(spec);
|
|
1695
1724
|
}
|
|
1696
|
-
inputStream = Readable2.fromWeb(response.body);
|
|
1697
1725
|
} catch (e) {
|
|
1698
1726
|
const err = e instanceof FluxerError2 ? e : new FluxerError2(e instanceof Error ? e.message : String(e), {
|
|
1699
1727
|
code: ErrorCodes2.FileFetchFailed,
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "1.3.
|
|
6
|
+
"version": "1.3.1",
|
|
7
7
|
"description": "Voice support for Fluxer bots",
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
@@ -39,10 +39,10 @@
|
|
|
39
39
|
"prism-media": "^1.3.5",
|
|
40
40
|
"tweetnacl": "^1.0.3",
|
|
41
41
|
"ws": "^8.18.0",
|
|
42
|
-
"@fluxerjs/collection": "1.3.
|
|
43
|
-
"@fluxerjs/core": "1.3.
|
|
44
|
-
"@fluxerjs/
|
|
45
|
-
"@fluxerjs/
|
|
42
|
+
"@fluxerjs/collection": "1.3.1",
|
|
43
|
+
"@fluxerjs/core": "1.3.1",
|
|
44
|
+
"@fluxerjs/types": "1.3.1",
|
|
45
|
+
"@fluxerjs/util": "1.3.1"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@types/node": "^20.0.0",
|