@remedia/node 0.1.0-dev.3 → 0.1.0-dev.5
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/README.md +21 -7
- package/dist/bootstrap-locator.d.ts +1 -0
- package/dist/bootstrap-locator.js +104 -0
- package/dist/discord.d.ts +14 -1
- package/dist/discord.js +57 -0
- package/dist/ffmpeg-runtime.d.ts +94 -0
- package/dist/ffmpeg-runtime.js +499 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.js +2 -0
- package/dist/lifecycle.d.ts +103 -0
- package/dist/lifecycle.js +5 -0
- package/dist/native-binding.d.ts +26 -0
- package/dist/native-binding.js +80 -0
- package/dist/playback.d.ts +19 -1
- package/dist/playback.js +300 -13
- package/dist/remedia.d.ts +6 -0
- package/dist/remedia.js +15 -1
- package/dist/resources.d.ts +51 -0
- package/dist/resources.js +1 -0
- package/native.d.ts +48 -0
- package/native.js +56 -56
- package/package.json +19 -16
package/README.md
CHANGED
|
@@ -34,18 +34,32 @@ Requires Node.js **22.18.0 or newer** (ESM).
|
|
|
34
34
|
npm install @remedia/node
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
-
Install FFmpeg 9 shared libraries separately
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
Install FFmpeg 9 shared libraries separately on the Node.js host. npm does not install FFmpeg, and
|
|
38
|
+
importing the package never downloads anything. The Remedia installer provisions FFmpeg 9.0.2 only
|
|
39
|
+
(no server) into `~/.remedia/ffmpeg9`, which the package finds automatically:
|
|
40
|
+
|
|
41
|
+
```sh
|
|
42
|
+
curl -fsSL https://raw.githubusercontent.com/twlite/remedia/main/scripts/install.sh | sh -s -- --ffmpeg-only
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
```powershell
|
|
46
|
+
& ([scriptblock]::Create((irm https://raw.githubusercontent.com/twlite/remedia/main/scripts/install.ps1))) -FFmpegOnly
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
No `LD_LIBRARY_PATH`, `DYLD_LIBRARY_PATH`, `PATH` change, or launcher is needed. Discovery order:
|
|
50
|
+
`REMEDIA_FFMPEG_DIR` (an explicit override that is never silently replaced), an existing system
|
|
51
|
+
FFmpeg 9, then `~/.remedia/ffmpeg9`. Required ABI majors are avcodec 63, avformat 63, avutil 61,
|
|
52
|
+
avfilter 12, and swresample 7. `getFfmpegRuntime()` reports which installation was loaded, and a
|
|
53
|
+
failed import lists the paths considered. libopus is statically included; FFmpeg is dynamically linked.
|
|
54
|
+
FFmpeg is needed on the Node.js host in embedded mode; in remote mode it is needed on the
|
|
55
|
+
`remedia-server` host instead.
|
|
40
56
|
|
|
41
57
|
Native runtime CI covers Linux x64/ARM64 glibc, macOS x64/ARM64, Windows x64 MSVC, and
|
|
42
58
|
FreeBSD x64. Additional build-only packages cover Linux x64/ARM64 musl, Linux ARMv7 hard-float GNU,
|
|
43
59
|
Windows x86/ARM64 MSVC, and Android ARM64/ARMv7 (API 24). Build-only targets have no native runtime
|
|
44
60
|
integration coverage. See the [distribution guide](https://github.com/twlite/remedia/blob/main/apps/docs/content/docs/node/distribution.mdx)
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
matching architecture/ABI, transitive FFmpeg dependencies, and that optional npm dependencies were
|
|
48
|
-
installed. Windows also needs the Visual C++ v14 runtime.
|
|
61
|
+
and [native library troubleshooting](https://github.com/twlite/remedia/blob/main/apps/docs/content/docs/node/troubleshooting.mdx)
|
|
62
|
+
for verification limits and load errors. Windows also needs the Visual C++ v14 runtime.
|
|
49
63
|
|
|
50
64
|
```js
|
|
51
65
|
import { Remedia } from '@remedia/node';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
3
|
+
import { dirname, join } from 'node:path';
|
|
4
|
+
const require = createRequire(import.meta.url);
|
|
5
|
+
/**
|
|
6
|
+
* Whether Linux uses musl rather than glibc, mirroring the generated napi-rs loader's decision so
|
|
7
|
+
* that the bootstrap comes from the same platform package as the engine addon.
|
|
8
|
+
*/
|
|
9
|
+
function isMusl() {
|
|
10
|
+
// @types/node does not declare `excludeNetwork`, which keeps the report from doing DNS lookups.
|
|
11
|
+
const report = process.report;
|
|
12
|
+
if (typeof report?.getReport === 'function') {
|
|
13
|
+
const previous = report.excludeNetwork;
|
|
14
|
+
try {
|
|
15
|
+
report.excludeNetwork = true;
|
|
16
|
+
const data = report.getReport();
|
|
17
|
+
if (data.header?.glibcVersionRuntime)
|
|
18
|
+
return false;
|
|
19
|
+
if (data.sharedObjects?.some((object) => object.includes('libc.musl-') || object.includes('ld-musl-'))) {
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
// Fall through to the filesystem check.
|
|
25
|
+
}
|
|
26
|
+
finally {
|
|
27
|
+
report.excludeNetwork = previous;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
return readFileSync('/usr/bin/ldd', 'utf8').includes('musl');
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* napi-rs platform suffixes that may hold this machine's addons, in the generated loader's order.
|
|
39
|
+
*
|
|
40
|
+
* @param platform - Node.js platform string.
|
|
41
|
+
* @param arch - Node.js architecture string.
|
|
42
|
+
* @param musl - Whether a Linux system uses musl; only consulted on Linux.
|
|
43
|
+
* @returns Suffixes such as `linux-x64-gnu` or `darwin-arm64`; empty when unsupported.
|
|
44
|
+
* @internal
|
|
45
|
+
*/
|
|
46
|
+
export function platformSuffixes(platform, arch, musl = isMusl) {
|
|
47
|
+
switch (platform) {
|
|
48
|
+
case 'linux': {
|
|
49
|
+
const libc = musl() ? 'musl' : 'gnu';
|
|
50
|
+
if (arch === 'x64')
|
|
51
|
+
return [`linux-x64-${libc}`];
|
|
52
|
+
if (arch === 'arm64')
|
|
53
|
+
return [`linux-arm64-${libc}`];
|
|
54
|
+
if (arch === 'arm')
|
|
55
|
+
return [libc === 'musl' ? 'linux-arm-musleabihf' : 'linux-arm-gnueabihf'];
|
|
56
|
+
return [];
|
|
57
|
+
}
|
|
58
|
+
case 'darwin':
|
|
59
|
+
return ['darwin-universal', `darwin-${arch}`];
|
|
60
|
+
case 'win32':
|
|
61
|
+
return arch === 'x64'
|
|
62
|
+
? ['win32-x64-msvc']
|
|
63
|
+
: arch === 'ia32'
|
|
64
|
+
? ['win32-ia32-msvc']
|
|
65
|
+
: arch === 'arm64'
|
|
66
|
+
? ['win32-arm64-msvc']
|
|
67
|
+
: [];
|
|
68
|
+
case 'freebsd':
|
|
69
|
+
return [`freebsd-${arch}`];
|
|
70
|
+
case 'android':
|
|
71
|
+
return arch === 'arm64' ? ['android-arm64'] : arch === 'arm' ? ['android-arm-eabi'] : [];
|
|
72
|
+
default:
|
|
73
|
+
return [];
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* File locations where this platform's bootstrap addon could be: next to `native.js` in a source
|
|
78
|
+
* checkout, then inside the installed `@remedia/node-<suffix>` platform package.
|
|
79
|
+
*
|
|
80
|
+
* @param packageRoot - Directory of the `@remedia/node` package.
|
|
81
|
+
* @param suffixes - Platform suffixes from {@link platformSuffixes}.
|
|
82
|
+
* @param resolvePackage - Resolves a module specifier to a file path; throws if absent.
|
|
83
|
+
* @returns Existing file paths in preference order.
|
|
84
|
+
* @internal
|
|
85
|
+
*/
|
|
86
|
+
export function bootstrapCandidates(packageRoot, suffixes, resolvePackage = (specifier) => require.resolve(specifier)) {
|
|
87
|
+
const candidates = [];
|
|
88
|
+
for (const suffix of suffixes) {
|
|
89
|
+
const fileName = `bootstrap.${suffix}.node`;
|
|
90
|
+
const local = join(packageRoot, fileName);
|
|
91
|
+
if (existsSync(local))
|
|
92
|
+
candidates.push(local);
|
|
93
|
+
try {
|
|
94
|
+
const manifest = resolvePackage(`@remedia/node-${suffix}/package.json`);
|
|
95
|
+
const packaged = join(dirname(manifest), fileName);
|
|
96
|
+
if (existsSync(packaged))
|
|
97
|
+
candidates.push(packaged);
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
// The optional platform package is not installed.
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return candidates;
|
|
104
|
+
}
|
package/dist/discord.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RemediaEventEmitter } from './events.js';
|
|
2
|
-
import { PlaybackHooks, type PlayOptions, type SessionLifecycleEvents } from './lifecycle.js';
|
|
2
|
+
import { PlaybackHooks, type PlayOptions, type SessionLifecycleEvents, type CrossfadeOptions, type StageNextOptions, type StageSnapshot } from './lifecycle.js';
|
|
3
3
|
import { FilterControls } from './filters.js';
|
|
4
4
|
import type { MediaSource } from './input.js';
|
|
5
5
|
import type { AudioStreamInfo, PlaybackPosition, PlaybackState, VoiceConnectionState } from './types.js';
|
|
@@ -21,6 +21,8 @@ export interface DiscordSessionOptions {
|
|
|
21
21
|
volume?: number;
|
|
22
22
|
/** Trusted raw FFmpeg audio filtergraph; defaults to null. Native syntax validation occurs during backend configuration before playback. */
|
|
23
23
|
filterGraph?: string | null;
|
|
24
|
+
/** Explicit PCM crossfade opt-in; disabled by default. */
|
|
25
|
+
crossfade?: CrossfadeOptions | false;
|
|
24
26
|
}
|
|
25
27
|
/** Cancellation and timeout controls for obtaining credentials and establishing a voice transport. */
|
|
26
28
|
export interface DiscordConnectOptions {
|
|
@@ -113,6 +115,17 @@ export declare class DiscordSession<Metadata = unknown> extends RemediaEventEmit
|
|
|
113
115
|
* Pause the current playback without replacing its decoder or source generation.
|
|
114
116
|
* @returns Resolves when the backend accepts the pause request.
|
|
115
117
|
*/
|
|
118
|
+
/**
|
|
119
|
+
* Prepare one upcoming source without restarting playback or its output.
|
|
120
|
+
* @param source - Fresh media input; Readables and buffers require embedded execution.
|
|
121
|
+
* @param options - Queue occurrence, revision fencing, expiry and locally retained metadata.
|
|
122
|
+
* @returns Preparation snapshot; rejects disabled sessions, stale identities or invalid inputs.
|
|
123
|
+
*/
|
|
124
|
+
stageNext(source: MediaSource, options: StageNextOptions<Metadata>): Promise<StageSnapshot>;
|
|
125
|
+
/** Cancel the queued stage and release its input. @returns Resolves after cancellation. */
|
|
126
|
+
clearStage(): Promise<void>;
|
|
127
|
+
/** Current preparation snapshot, or null when no stage is pending. */
|
|
128
|
+
get stagedSource(): StageSnapshot | null;
|
|
116
129
|
pause(): Promise<void>;
|
|
117
130
|
/**
|
|
118
131
|
* Resume paused playback on its existing source generation.
|
package/dist/discord.js
CHANGED
|
@@ -51,6 +51,7 @@ export class DiscordSession extends RemediaEventEmitter {
|
|
|
51
51
|
#disposed = false;
|
|
52
52
|
#filterGraph = null;
|
|
53
53
|
#volume = 1;
|
|
54
|
+
#crossfade;
|
|
54
55
|
#configurationWork = Promise.resolve();
|
|
55
56
|
#nativeStateTimer;
|
|
56
57
|
/**
|
|
@@ -66,6 +67,7 @@ export class DiscordSession extends RemediaEventEmitter {
|
|
|
66
67
|
this.#channelId = validateSnowflake('channelId', options.channelId);
|
|
67
68
|
this.userId = validateSnowflake('userId', options.userId);
|
|
68
69
|
validateVolume(options.volume ?? 1);
|
|
70
|
+
this.#crossfade = options.crossfade;
|
|
69
71
|
if (options.filterGraph !== undefined &&
|
|
70
72
|
options.filterGraph !== null &&
|
|
71
73
|
(typeof options.filterGraph !== 'string' || !options.filterGraph.trim()))
|
|
@@ -310,6 +312,24 @@ export class DiscordSession extends RemediaEventEmitter {
|
|
|
310
312
|
* Pause the current playback without replacing its decoder or source generation.
|
|
311
313
|
* @returns Resolves when the backend accepts the pause request.
|
|
312
314
|
*/
|
|
315
|
+
/**
|
|
316
|
+
* Prepare one upcoming source without restarting playback or its output.
|
|
317
|
+
* @param source - Fresh media input; Readables and buffers require embedded execution.
|
|
318
|
+
* @param options - Queue occurrence, revision fencing, expiry and locally retained metadata.
|
|
319
|
+
* @returns Preparation snapshot; rejects disabled sessions, stale identities or invalid inputs.
|
|
320
|
+
*/
|
|
321
|
+
async stageNext(source, options) {
|
|
322
|
+
await this.#configurationWork;
|
|
323
|
+
return this.#requireExistingPlayback().stageNext(source, options);
|
|
324
|
+
}
|
|
325
|
+
/** Cancel the queued stage and release its input. @returns Resolves after cancellation. */
|
|
326
|
+
clearStage() {
|
|
327
|
+
return this.#requireExistingPlayback().clearStage();
|
|
328
|
+
}
|
|
329
|
+
/** Current preparation snapshot, or null when no stage is pending. */
|
|
330
|
+
get stagedSource() {
|
|
331
|
+
return this.#playback?.stagedSource ?? null;
|
|
332
|
+
}
|
|
313
333
|
pause() {
|
|
314
334
|
return this.#requireExistingPlayback().pause();
|
|
315
335
|
}
|
|
@@ -694,6 +714,8 @@ export class DiscordSession extends RemediaEventEmitter {
|
|
|
694
714
|
const createdPlayback = new PlaybackSession(this.#native, nativeSession.playbackId, undefined, this.guildId, this.hooks);
|
|
695
715
|
playback = createdPlayback;
|
|
696
716
|
this.#playback = createdPlayback;
|
|
717
|
+
if (this.#crossfade)
|
|
718
|
+
createdPlayback.configureCrossfade(this.#crossfade);
|
|
697
719
|
await this.#serializeConfiguration(async () => {
|
|
698
720
|
if (this.#playback !== createdPlayback)
|
|
699
721
|
return;
|
|
@@ -1133,6 +1155,41 @@ export class DiscordSession extends RemediaEventEmitter {
|
|
|
1133
1155
|
guildId: this.guildId,
|
|
1134
1156
|
});
|
|
1135
1157
|
});
|
|
1158
|
+
forward(PlaybackEvent.prepareRequested, (event) => {
|
|
1159
|
+
this.emit(PlaybackEvent.prepareRequested, {
|
|
1160
|
+
...event,
|
|
1161
|
+
sessionId: this.sessionId,
|
|
1162
|
+
guildId: this.guildId,
|
|
1163
|
+
});
|
|
1164
|
+
});
|
|
1165
|
+
forward(PlaybackEvent.stageReady, (event) => {
|
|
1166
|
+
this.emit(PlaybackEvent.stageReady, {
|
|
1167
|
+
...event,
|
|
1168
|
+
sessionId: this.sessionId,
|
|
1169
|
+
guildId: this.guildId,
|
|
1170
|
+
});
|
|
1171
|
+
});
|
|
1172
|
+
forward(PlaybackEvent.stageFailed, (event) => {
|
|
1173
|
+
this.emit(PlaybackEvent.stageFailed, {
|
|
1174
|
+
...event,
|
|
1175
|
+
sessionId: this.sessionId,
|
|
1176
|
+
guildId: this.guildId,
|
|
1177
|
+
});
|
|
1178
|
+
});
|
|
1179
|
+
forward(PlaybackEvent.stageInvalidated, (event) => {
|
|
1180
|
+
this.emit(PlaybackEvent.stageInvalidated, {
|
|
1181
|
+
...event,
|
|
1182
|
+
sessionId: this.sessionId,
|
|
1183
|
+
guildId: this.guildId,
|
|
1184
|
+
});
|
|
1185
|
+
});
|
|
1186
|
+
forward(PlaybackEvent.transitionCancelled, (event) => {
|
|
1187
|
+
this.emit(PlaybackEvent.transitionCancelled, {
|
|
1188
|
+
...event,
|
|
1189
|
+
sessionId: this.sessionId,
|
|
1190
|
+
guildId: this.guildId,
|
|
1191
|
+
});
|
|
1192
|
+
});
|
|
1136
1193
|
this.#playbackSubscriptions = {
|
|
1137
1194
|
playback,
|
|
1138
1195
|
detach: () => {
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where the loaded FFmpeg installation came from.
|
|
3
|
+
*
|
|
4
|
+
* - `explicit`: the `REMEDIA_FFMPEG_DIR` environment variable.
|
|
5
|
+
* - `system`: an installation the platform's library search finds (package manager, Homebrew,
|
|
6
|
+
* `LD_LIBRARY_PATH`, `DYLD_LIBRARY_PATH`, `PATH`, ...).
|
|
7
|
+
* - `managed`: the Remedia installer's `~/.remedia/ffmpeg9` prefix.
|
|
8
|
+
* - `unmanaged`: the platform has no bootstrap addon, so the operating system's loader resolved
|
|
9
|
+
* FFmpeg on its own and Remedia cannot report which installation it chose.
|
|
10
|
+
*/
|
|
11
|
+
export type FfmpegSource = 'explicit' | 'system' | 'managed' | 'unmanaged';
|
|
12
|
+
/**
|
|
13
|
+
* Why an FFmpeg installation candidate was rejected, where that can be determined.
|
|
14
|
+
*
|
|
15
|
+
* - `not-found`: the directory does not exist.
|
|
16
|
+
* - `missing-libraries`: required FFmpeg libraries are absent from the directory.
|
|
17
|
+
* - `abi-mismatch`: libraries exist but have a different ABI major than FFmpeg 9 requires.
|
|
18
|
+
* - `architecture-mismatch`: the libraries were built for a different CPU architecture.
|
|
19
|
+
* - `unresolved-dependency`: a library or one of its own dependencies could not be resolved.
|
|
20
|
+
* - `mixed-installations`: the five libraries did not all come from one directory.
|
|
21
|
+
* - `load-failed`: the loader rejected a library for another reason.
|
|
22
|
+
*/
|
|
23
|
+
export type FfmpegFailureReason = 'not-found' | 'missing-libraries' | 'abi-mismatch' | 'architecture-mismatch' | 'unresolved-dependency' | 'mixed-installations' | 'load-failed';
|
|
24
|
+
/** One FFmpeg shared library loaded by Remedia. */
|
|
25
|
+
export interface FfmpegLibraryInfo {
|
|
26
|
+
/** FFmpeg library name without the `lib` prefix, for example `avcodec`. */
|
|
27
|
+
readonly name: string;
|
|
28
|
+
/** Absolute path of the loaded file as reported by the operating system. */
|
|
29
|
+
readonly path: string;
|
|
30
|
+
/** Library version reported by the library itself, as `major.minor.micro`. */
|
|
31
|
+
readonly version: string;
|
|
32
|
+
/** ABI major version, which must match the FFmpeg 9 requirement for `name`. */
|
|
33
|
+
readonly major: number;
|
|
34
|
+
}
|
|
35
|
+
/** What discovery concluded about one FFmpeg installation candidate. */
|
|
36
|
+
export interface FfmpegCandidateReport {
|
|
37
|
+
/** Which discovery step produced this candidate. */
|
|
38
|
+
readonly source: Exclude<FfmpegSource, 'unmanaged'>;
|
|
39
|
+
/** Directory that was inspected, or `null` when the step looked at several directories. */
|
|
40
|
+
readonly directory: string | null;
|
|
41
|
+
/** Whether this candidate was loaded (`selected`) or not. */
|
|
42
|
+
readonly outcome: 'selected' | 'rejected';
|
|
43
|
+
/** Classified rejection cause when `outcome` is `rejected` and the cause is known. */
|
|
44
|
+
readonly reason?: FfmpegFailureReason;
|
|
45
|
+
/** Human-readable explanation, including the loader's own message where available. */
|
|
46
|
+
readonly detail?: string;
|
|
47
|
+
}
|
|
48
|
+
/** The FFmpeg runtime that `@remedia/node` loaded. */
|
|
49
|
+
export interface FfmpegRuntimeInfo {
|
|
50
|
+
/** How the installation was found. */
|
|
51
|
+
readonly source: FfmpegSource;
|
|
52
|
+
/** Directory containing the loaded libraries, or `null` when `source` is `unmanaged`. */
|
|
53
|
+
readonly directory: string | null;
|
|
54
|
+
/** The five loaded libraries in load order; empty when `source` is `unmanaged`. */
|
|
55
|
+
readonly libraries: readonly FfmpegLibraryInfo[];
|
|
56
|
+
/** Every candidate discovery examined, in order, including the selected one. */
|
|
57
|
+
readonly considered: readonly FfmpegCandidateReport[];
|
|
58
|
+
}
|
|
59
|
+
/** Command that installs FFmpeg 9 on Linux and macOS with the Remedia installer. */
|
|
60
|
+
export declare const UNIX_INSTALL_COMMAND = "curl -fsSL https://raw.githubusercontent.com/twlite/remedia/main/scripts/install.sh | sh -s -- --ffmpeg-only";
|
|
61
|
+
/** Command that installs FFmpeg 9 on Windows PowerShell with the Remedia installer. */
|
|
62
|
+
export declare const WINDOWS_INSTALL_COMMAND = "& ([scriptblock]::Create((irm https://raw.githubusercontent.com/twlite/remedia/main/scripts/install.ps1))) -FFmpegOnly";
|
|
63
|
+
/**
|
|
64
|
+
* Raised when no compatible FFmpeg 9 installation could be loaded, or when an explicit
|
|
65
|
+
* `REMEDIA_FFMPEG_DIR` override is unusable. The message lists every path considered and how to
|
|
66
|
+
* install or point to FFmpeg.
|
|
67
|
+
*/
|
|
68
|
+
export declare class FfmpegLoadError extends Error {
|
|
69
|
+
/** Every candidate that was examined, in order. */
|
|
70
|
+
readonly candidates: readonly FfmpegCandidateReport[];
|
|
71
|
+
/**
|
|
72
|
+
* @param candidates - Reports for each installation candidate that was examined.
|
|
73
|
+
* @param explicitOverride - Whether `REMEDIA_FFMPEG_DIR` was set, which disables fallbacks.
|
|
74
|
+
* @param platform - Platform used to choose the install command shown in the message.
|
|
75
|
+
*/
|
|
76
|
+
constructor(candidates: readonly FfmpegCandidateReport[], explicitOverride: boolean, platform?: NodeJS.Platform);
|
|
77
|
+
}
|
|
78
|
+
/** FFmpeg 9 shared libraries in dependency order (leaf libraries first) with their ABI majors. */
|
|
79
|
+
export declare const FFMPEG_LIBRARIES: readonly [{
|
|
80
|
+
readonly name: "avutil";
|
|
81
|
+
readonly major: 61;
|
|
82
|
+
}, {
|
|
83
|
+
readonly name: "swresample";
|
|
84
|
+
readonly major: 7;
|
|
85
|
+
}, {
|
|
86
|
+
readonly name: "avcodec";
|
|
87
|
+
readonly major: 63;
|
|
88
|
+
}, {
|
|
89
|
+
readonly name: "avformat";
|
|
90
|
+
readonly major: 63;
|
|
91
|
+
}, {
|
|
92
|
+
readonly name: "avfilter";
|
|
93
|
+
readonly major: 12;
|
|
94
|
+
}];
|