@mediabunny/server 1.45.0

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.
Files changed (41) hide show
  1. package/LICENSE +373 -0
  2. package/README.md +276 -0
  3. package/dist/bundles/mediabunny-server.cjs +3361 -0
  4. package/dist/bundles/mediabunny-server.min.cjs +10 -0
  5. package/dist/bundles/mediabunny-server.min.mjs +9 -0
  6. package/dist/bundles/mediabunny-server.mjs +3334 -0
  7. package/dist/mediabunny-server.d.ts +105 -0
  8. package/dist/modules/src/audio-decoder.d.ts +21 -0
  9. package/dist/modules/src/audio-decoder.d.ts.map +1 -0
  10. package/dist/modules/src/audio-decoder.js +132 -0
  11. package/dist/modules/src/audio-encoder.d.ts +35 -0
  12. package/dist/modules/src/audio-encoder.d.ts.map +1 -0
  13. package/dist/modules/src/audio-encoder.js +329 -0
  14. package/dist/modules/src/audio-sample.d.ts +38 -0
  15. package/dist/modules/src/audio-sample.d.ts.map +1 -0
  16. package/dist/modules/src/audio-sample.js +119 -0
  17. package/dist/modules/src/index.d.ts +39 -0
  18. package/dist/modules/src/index.d.ts.map +1 -0
  19. package/dist/modules/src/index.js +132 -0
  20. package/dist/modules/src/misc.d.ts +26 -0
  21. package/dist/modules/src/misc.d.ts.map +1 -0
  22. package/dist/modules/src/misc.js +255 -0
  23. package/dist/modules/src/video-decoder.d.ts +30 -0
  24. package/dist/modules/src/video-decoder.d.ts.map +1 -0
  25. package/dist/modules/src/video-decoder.js +214 -0
  26. package/dist/modules/src/video-encoder.d.ts +35 -0
  27. package/dist/modules/src/video-encoder.d.ts.map +1 -0
  28. package/dist/modules/src/video-encoder.js +474 -0
  29. package/dist/modules/src/video-sample.d.ts +45 -0
  30. package/dist/modules/src/video-sample.d.ts.map +1 -0
  31. package/dist/modules/src/video-sample.js +276 -0
  32. package/dist/modules/tsconfig.tsbuildinfo +1 -0
  33. package/package.json +59 -0
  34. package/src/audio-decoder.ts +120 -0
  35. package/src/audio-encoder.ts +396 -0
  36. package/src/audio-sample.ts +101 -0
  37. package/src/index.ts +104 -0
  38. package/src/misc.ts +242 -0
  39. package/src/video-decoder.ts +224 -0
  40. package/src/video-encoder.ts +568 -0
  41. package/src/video-sample.ts +313 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audio-sample.d.ts","sourceRoot":"","sources":["../../../src/audio-sample.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAC9D,OAAO,KAAK,MAAM,MAAM,SAAS,CAAC;AAIlC;;;;;;;;;;;GAWG;AACH,qBAAa,0BAA2B,SAAQ,mBAAmB;IAIlE;;;OAGG;IACH,IAAI,KAAK,iBAMR;gBAEW,KAAK,EAAE,MAAM,CAAC,KAAK;IAU/B,SAAS,IAAI,iBAAiB;IAU9B,aAAa,IAAI,MAAM;IAIvB,mBAAmB,IAAI,MAAM;IAI7B,iBAAiB,IAAI,MAAM;IAI3B,YAAY,IAAI,MAAM;IAItB,KAAK,IAAI,IAAI;IAKb,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU;CAI5C;AAED,eAAO,MAAM,wBAAwB,GAAI,QAAQ,WAAW,EAAE,OAAO,MAAM,CAAC,KAAK,SAYhF,CAAC"}
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ /*!
3
+ * Copyright (c) 2026-present, Vanilagy and contributors
4
+ *
5
+ * This Source Code Form is subject to the terms of the Mozilla Public
6
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
7
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/.
8
+ */
9
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ var desc = Object.getOwnPropertyDescriptor(m, k);
12
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
13
+ desc = { enumerable: true, get: function() { return m[k]; } };
14
+ }
15
+ Object.defineProperty(o, k2, desc);
16
+ }) : (function(o, m, k, k2) {
17
+ if (k2 === undefined) k2 = k;
18
+ o[k2] = m[k];
19
+ }));
20
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
21
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
22
+ }) : function(o, v) {
23
+ o["default"] = v;
24
+ });
25
+ var __importStar = (this && this.__importStar) || (function () {
26
+ var ownKeys = function(o) {
27
+ ownKeys = Object.getOwnPropertyNames || function (o) {
28
+ var ar = [];
29
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
30
+ return ar;
31
+ };
32
+ return ownKeys(o);
33
+ };
34
+ return function (mod) {
35
+ if (mod && mod.__esModule) return mod;
36
+ var result = {};
37
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
38
+ __setModuleDefault(result, mod);
39
+ return result;
40
+ };
41
+ })();
42
+ Object.defineProperty(exports, "__esModule", { value: true });
43
+ exports.copyAudioSampleToAvFrame = exports.AvFrameAudioSampleResource = void 0;
44
+ const mediabunny_1 = require("mediabunny");
45
+ const NodeAv = __importStar(require("node-av"));
46
+ const misc_1 = require("./misc");
47
+ const misc_2 = require("../../../src/misc");
48
+ /**
49
+ * A custom `AudioSampleResource` backed by NodeAV's
50
+ * [`Frame`](https://seydx.github.io/node-av/api/lib/classes/Frame.html), which in turn is backed by FFmpeg's
51
+ * [`AVFrame`](https://ffmpeg.org/doxygen/2.7/structAVFrame.html). You can use this resource to create `AudioSample`
52
+ * instances that are directly backed by FFmpeg's `AVFrame` without data having to be copied.
53
+ *
54
+ * When passed, the `Frame` is now owned by resource, meaning it takes care of closing the frame later. If you want to
55
+ * keep a copy for your own use, clone the frame first.
56
+ *
57
+ * @group \@mediabunny/server
58
+ * @public
59
+ */
60
+ class AvFrameAudioSampleResource extends mediabunny_1.AudioSampleResource {
61
+ /**
62
+ * The NodeAV [`Frame`](https://seydx.github.io/node-av/api/lib/classes/Frame.html) instance backing this resource.
63
+ * Access throws if the resource has already been closed.
64
+ */
65
+ get frame() {
66
+ if (!this._frame) {
67
+ throw new Error('AvFrameAudioSampleResource has been closed.');
68
+ }
69
+ return this._frame;
70
+ }
71
+ constructor(frame) {
72
+ super();
73
+ if (frame.getMediaType() !== NodeAv.AVMEDIA_TYPE_AUDIO) {
74
+ throw new Error('AvFrameAudioSampleResource must be initialized with an audio frame.');
75
+ }
76
+ this._frame = frame;
77
+ }
78
+ getFormat() {
79
+ const result = (0, misc_1.toAudioSampleFormat)(this.frame.format);
80
+ if (result === null) {
81
+ const name = NodeAv.avGetSampleFmtName(this.frame.format);
82
+ throw new TypeError(`Unsupported audio sample format: ${name} (${this.frame.format})`);
83
+ }
84
+ return result;
85
+ }
86
+ getSampleRate() {
87
+ return this.frame.sampleRate;
88
+ }
89
+ getNumberOfChannels() {
90
+ return this.frame.channels;
91
+ }
92
+ getNumberOfFrames() {
93
+ return this.frame.nbSamples;
94
+ }
95
+ getTimestamp() {
96
+ return Number(this.frame.pts) / this.frame.timeBase.den;
97
+ }
98
+ close() {
99
+ this.frame.free();
100
+ this._frame = null;
101
+ }
102
+ getDataPlane(planeIndex) {
103
+ (0, misc_2.assert)(this.frame.data && planeIndex < this.frame.data.length);
104
+ return (0, misc_2.toUint8Array)(this.frame.data[planeIndex]);
105
+ }
106
+ }
107
+ exports.AvFrameAudioSampleResource = AvFrameAudioSampleResource;
108
+ const copyAudioSampleToAvFrame = (sample, frame) => {
109
+ frame.format = (0, misc_1.fromAudioSampleFormat)(sample.format);
110
+ frame.nbSamples = sample.numberOfFrames;
111
+ frame.sampleRate = sample.sampleRate;
112
+ frame.channelLayout = (0, misc_1.getChannelLayout)(sample.numberOfChannels);
113
+ frame.allocBuffer();
114
+ (0, misc_2.assert)(frame.data);
115
+ for (let i = 0; i < frame.data.length; i++) {
116
+ sample.copyTo(frame.data[i], { planeIndex: i });
117
+ }
118
+ };
119
+ exports.copyAudioSampleToAvFrame = copyAudioSampleToAvFrame;
@@ -0,0 +1,39 @@
1
+ /*!
2
+ * Copyright (c) 2026-present, Vanilagy and contributors
3
+ *
4
+ * This Source Code Form is subject to the terms of the Mozilla Public
5
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
6
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7
+ */
8
+ import { AudioSample, VideoSample } from 'mediabunny';
9
+ import * as NodeAv from 'node-av';
10
+ /**
11
+ * Registers video and audio decoders and encoders for all codecs, using FFmpeg's libavcodec under the hood.
12
+ * Additionally, a custom `VideoSample` transformer based on libavfilter is registered to enable resizing, rotation and
13
+ * cropping of video frames.
14
+ *
15
+ * Make sure to call this function before interacting with Mediabunny.
16
+ *
17
+ * The decoders and encoders will automatically detect hardware acceleration support for each codec and platform and
18
+ * make use of it if applicable.
19
+ *
20
+ * @group \@mediabunny/server
21
+ * @public
22
+ */
23
+ export declare const registerMediabunnyServer: () => void;
24
+ export { AvFrameVideoSampleResource } from './video-sample';
25
+ export { AvFrameAudioSampleResource } from './audio-sample';
26
+ /**
27
+ * Copies a `VideoSample` or `AudioSample` into the given NodeAV
28
+ * [`Frame`](https://seydx.github.io/node-av/api/lib/classes/Frame.html), setting up the frame's format, media type,
29
+ * timing and data. When the sample is already backed by an `AVFrame` (via `AvFrameVideoSampleResource` or
30
+ * `AvFrameAudioSampleResource`), the frame is ref'd instead of copied for zero-copy reuse.
31
+ *
32
+ * For video samples, the frame's time base is always set to 1/1000000 (microsecond accuracy). For audio samples, the
33
+ * frame's time base is always set to 1/sampleRate.
34
+ *
35
+ * @group \@mediabunny/server
36
+ * @public
37
+ */
38
+ export declare const toAvFrame: (sample: VideoSample | AudioSample, frame: NodeAv.Frame) => Promise<void>;
39
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,WAAW,EAAoE,WAAW,EAAE,MAAM,YAAY,CAAC;AACxH,OAAO,KAAK,MAAM,MAAM,SAAS,CAAC;AAqBlC;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,wBAAwB,YAiBpC,CAAC;AAEF,OAAO,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AAE5D;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,SAAS,GAAU,QAAQ,WAAW,GAAG,WAAW,EAAE,OAAO,MAAM,CAAC,KAAK,kBA0BrF,CAAC"}
@@ -0,0 +1,132 @@
1
+ "use strict";
2
+ /*!
3
+ * Copyright (c) 2026-present, Vanilagy and contributors
4
+ *
5
+ * This Source Code Form is subject to the terms of the Mozilla Public
6
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
7
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/.
8
+ */
9
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ var desc = Object.getOwnPropertyDescriptor(m, k);
12
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
13
+ desc = { enumerable: true, get: function() { return m[k]; } };
14
+ }
15
+ Object.defineProperty(o, k2, desc);
16
+ }) : (function(o, m, k, k2) {
17
+ if (k2 === undefined) k2 = k;
18
+ o[k2] = m[k];
19
+ }));
20
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
21
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
22
+ }) : function(o, v) {
23
+ o["default"] = v;
24
+ });
25
+ var __importStar = (this && this.__importStar) || (function () {
26
+ var ownKeys = function(o) {
27
+ ownKeys = Object.getOwnPropertyNames || function (o) {
28
+ var ar = [];
29
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
30
+ return ar;
31
+ };
32
+ return ownKeys(o);
33
+ };
34
+ return function (mod) {
35
+ if (mod && mod.__esModule) return mod;
36
+ var result = {};
37
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
38
+ __setModuleDefault(result, mod);
39
+ return result;
40
+ };
41
+ })();
42
+ Object.defineProperty(exports, "__esModule", { value: true });
43
+ exports.toAvFrame = exports.AvFrameAudioSampleResource = exports.AvFrameVideoSampleResource = exports.registerMediabunnyServer = void 0;
44
+ const mediabunny_1 = require("mediabunny");
45
+ const NodeAv = __importStar(require("node-av"));
46
+ const video_decoder_1 = require("./video-decoder");
47
+ const video_encoder_1 = require("./video-encoder");
48
+ const audio_decoder_1 = require("./audio-decoder");
49
+ const audio_encoder_1 = require("./audio-encoder");
50
+ const video_sample_1 = require("./video-sample");
51
+ const audio_sample_1 = require("./audio-sample");
52
+ const SERVER_LOADED_SYMBOL = Symbol.for('@mediabunny/server loaded');
53
+ if (globalThis[SERVER_LOADED_SYMBOL]) {
54
+ console.error('[WARNING]\n@mediabunny/server was loaded twice.'
55
+ + ' This will likely cause the package not to work correctly.'
56
+ + ' Check if multiple dependencies are importing different versions of @mediabunny/server,'
57
+ + ' or if something is being bundled incorrectly.');
58
+ }
59
+ globalThis[SERVER_LOADED_SYMBOL] = true;
60
+ let registered = false;
61
+ /**
62
+ * Registers video and audio decoders and encoders for all codecs, using FFmpeg's libavcodec under the hood.
63
+ * Additionally, a custom `VideoSample` transformer based on libavfilter is registered to enable resizing, rotation and
64
+ * cropping of video frames.
65
+ *
66
+ * Make sure to call this function before interacting with Mediabunny.
67
+ *
68
+ * The decoders and encoders will automatically detect hardware acceleration support for each codec and platform and
69
+ * make use of it if applicable.
70
+ *
71
+ * @group \@mediabunny/server
72
+ * @public
73
+ */
74
+ const registerMediabunnyServer = () => {
75
+ if (registered) {
76
+ return;
77
+ }
78
+ registered = true;
79
+ NodeAv.Log.setLevel(NodeAv.AV_LOG_ERROR);
80
+ // Video
81
+ (0, mediabunny_1.registerDecoder)(video_decoder_1.NodeAvVideoDecoder);
82
+ (0, mediabunny_1.registerEncoder)(video_encoder_1.NodeAvVideoEncoder);
83
+ // Audio
84
+ (0, mediabunny_1.registerDecoder)(audio_decoder_1.NodeAvAudioDecoder);
85
+ (0, mediabunny_1.registerEncoder)(audio_encoder_1.NodeAvAudioEncoder);
86
+ (0, mediabunny_1.registerVideoSampleTransformer)(video_sample_1.transformVideoSample);
87
+ };
88
+ exports.registerMediabunnyServer = registerMediabunnyServer;
89
+ var video_sample_2 = require("./video-sample");
90
+ Object.defineProperty(exports, "AvFrameVideoSampleResource", { enumerable: true, get: function () { return video_sample_2.AvFrameVideoSampleResource; } });
91
+ var audio_sample_2 = require("./audio-sample");
92
+ Object.defineProperty(exports, "AvFrameAudioSampleResource", { enumerable: true, get: function () { return audio_sample_2.AvFrameAudioSampleResource; } });
93
+ /**
94
+ * Copies a `VideoSample` or `AudioSample` into the given NodeAV
95
+ * [`Frame`](https://seydx.github.io/node-av/api/lib/classes/Frame.html), setting up the frame's format, media type,
96
+ * timing and data. When the sample is already backed by an `AVFrame` (via `AvFrameVideoSampleResource` or
97
+ * `AvFrameAudioSampleResource`), the frame is ref'd instead of copied for zero-copy reuse.
98
+ *
99
+ * For video samples, the frame's time base is always set to 1/1000000 (microsecond accuracy). For audio samples, the
100
+ * frame's time base is always set to 1/sampleRate.
101
+ *
102
+ * @group \@mediabunny/server
103
+ * @public
104
+ */
105
+ const toAvFrame = async (sample, frame) => {
106
+ if (sample instanceof mediabunny_1.VideoSample) {
107
+ if (sample._data instanceof video_sample_1.AvFrameVideoSampleResource) {
108
+ frame.ref(sample._data.frame);
109
+ }
110
+ else {
111
+ if (sample.format === null) {
112
+ throw new Error('Cannot convert foreign VideoSample with unknown (null) format.');
113
+ }
114
+ await (0, video_sample_1.copyVideoSampleToAvFrame)(sample, frame, null);
115
+ }
116
+ frame.pts = BigInt(sample.microsecondTimestamp);
117
+ frame.duration = BigInt(sample.microsecondDuration);
118
+ frame.timeBase = new NodeAv.Rational(1, 1e6);
119
+ }
120
+ else {
121
+ if (sample._data instanceof audio_sample_1.AvFrameAudioSampleResource) {
122
+ frame.ref(sample._data.frame);
123
+ }
124
+ else {
125
+ (0, audio_sample_1.copyAudioSampleToAvFrame)(sample, frame);
126
+ }
127
+ frame.timeBase = new NodeAv.Rational(1, sample.sampleRate);
128
+ frame.pts = BigInt(Math.round(sample.timestamp * sample.sampleRate));
129
+ frame.duration = BigInt(sample.numberOfFrames);
130
+ }
131
+ };
132
+ exports.toAvFrame = toAvFrame;
@@ -0,0 +1,26 @@
1
+ /*!
2
+ * Copyright (c) 2026-present, Vanilagy and contributors
3
+ *
4
+ * This Source Code Form is subject to the terms of the Mozilla Public
5
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
6
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7
+ */
8
+ import { VideoSamplePixelFormat, MediaCodec } from 'mediabunny';
9
+ import * as NodeAv from 'node-av';
10
+ export declare const CODEC_TO_CODEC_ID: Partial<Record<MediaCodec, NodeAv.AVCodecID>>;
11
+ export declare const getHardwareContext: () => NodeAv.HardwareContext | null;
12
+ export declare const getHardwareDecoderCodec: (codecId: NodeAv.AVCodecID) => NodeAv.Codec | null;
13
+ export declare const getHardwareEncoderCodec: (codecId: NodeAv.AVCodecID) => NodeAv.Codec | null;
14
+ export declare const mapColorPrimaries: (primaries: string) => NodeAv.AVColorPrimaries | null;
15
+ export declare const unmapColorPrimaries: (primaries: number) => "bt709" | "bt470bg" | "smpte170m" | "bt2020" | "smpte432" | null;
16
+ export declare const mapTransferCharacteristics: (transfer: string) => NodeAv.AVColorTransferCharacteristic | null;
17
+ export declare const unmapTransferCharacteristics: (transfer: number) => "bt709" | "smpte170m" | "iec61966-2-1" | "linear" | "pq" | "hlg" | null;
18
+ export declare const mapMatrixCoefficients: (matrix: string) => NodeAv.AVColorSpace | null;
19
+ export declare const unmapMatrixCoefficients: (matrix: number) => "bt709" | "bt470bg" | "smpte170m" | "rgb" | "bt2020-ncl" | null;
20
+ export declare const toPixelFormat: (ffmpegPixelFormat: NodeAv.AVPixelFormat) => VideoSamplePixelFormat | null;
21
+ export declare const fromPixelFormat: (pixelFormat: VideoSamplePixelFormat) => NodeAv.AVPixelFormat;
22
+ export declare const toAudioSampleFormat: (ffmpegSampleFormat: NodeAv.AVSampleFormat) => AudioSampleFormat | null;
23
+ export declare const fromAudioSampleFormat: (sampleFormat: AudioSampleFormat) => NodeAv.AVSampleFormat;
24
+ export declare const getChannelLayout: (numChannels: number) => NodeAv.ChannelLayout;
25
+ export declare const LIBVPX_VP9: (NodeAv.FFEncoderCodec & NodeAv.FFDecoderCodec);
26
+ //# sourceMappingURL=misc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"misc.d.ts","sourceRoot":"","sources":["../../../src/misc.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,sBAAsB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,KAAK,MAAM,MAAM,SAAS,CAAC;AAElC,eAAO,MAAM,iBAAiB,EAAE,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,SAAS,CAAC,CAc3E,CAAC;AAGF,eAAO,MAAM,kBAAkB,QAAO,MAAM,CAAC,eAAe,GAAG,IAK9D,CAAC;AAGF,eAAO,MAAM,uBAAuB,GAAI,SAAS,MAAM,CAAC,SAAS,KAAG,MAAM,CAAC,KAAK,GAAG,IAMlF,CAAC;AAGF,eAAO,MAAM,uBAAuB,GAAI,SAAS,MAAM,CAAC,SAAS,KAAG,MAAM,CAAC,KAAK,GAAG,IAMlF,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,WAAW,MAAM,mCAUlD,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,WAAW,MAAM,qEAUpD,CAAC;AAEF,eAAO,MAAM,0BAA0B,GAAI,UAAU,MAAM,gDAW1D,CAAC;AAEF,eAAO,MAAM,4BAA4B,GAAI,UAAU,MAAM,4EAW5D,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,QAAQ,MAAM,+BAUnD,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAI,QAAQ,MAAM,oEAUrD,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,mBAAmB,MAAM,CAAC,aAAa,KAAG,sBAAsB,GAAG,IAqChG,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,aAAa,sBAAsB,yBA+BlE,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,oBAAoB,MAAM,CAAC,cAAc,KAAG,iBAAiB,GAAG,IAanG,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,cAAc,iBAAiB,KAAG,MAAM,CAAC,cAa9E,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,aAAa,MAAM,KAAG,MAAM,CAAC,aAS7D,CAAC;AAGF,eAAO,MAAM,UAAU,EAAmB,CAAC,MAAM,CAAC,cAAc,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC"}
@@ -0,0 +1,255 @@
1
+ "use strict";
2
+ /*!
3
+ * Copyright (c) 2026-present, Vanilagy and contributors
4
+ *
5
+ * This Source Code Form is subject to the terms of the Mozilla Public
6
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
7
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/.
8
+ */
9
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ var desc = Object.getOwnPropertyDescriptor(m, k);
12
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
13
+ desc = { enumerable: true, get: function() { return m[k]; } };
14
+ }
15
+ Object.defineProperty(o, k2, desc);
16
+ }) : (function(o, m, k, k2) {
17
+ if (k2 === undefined) k2 = k;
18
+ o[k2] = m[k];
19
+ }));
20
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
21
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
22
+ }) : function(o, v) {
23
+ o["default"] = v;
24
+ });
25
+ var __importStar = (this && this.__importStar) || (function () {
26
+ var ownKeys = function(o) {
27
+ ownKeys = Object.getOwnPropertyNames || function (o) {
28
+ var ar = [];
29
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
30
+ return ar;
31
+ };
32
+ return ownKeys(o);
33
+ };
34
+ return function (mod) {
35
+ if (mod && mod.__esModule) return mod;
36
+ var result = {};
37
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
38
+ __setModuleDefault(result, mod);
39
+ return result;
40
+ };
41
+ })();
42
+ Object.defineProperty(exports, "__esModule", { value: true });
43
+ exports.LIBVPX_VP9 = exports.getChannelLayout = exports.fromAudioSampleFormat = exports.toAudioSampleFormat = exports.fromPixelFormat = exports.toPixelFormat = exports.unmapMatrixCoefficients = exports.mapMatrixCoefficients = exports.unmapTransferCharacteristics = exports.mapTransferCharacteristics = exports.unmapColorPrimaries = exports.mapColorPrimaries = exports.getHardwareEncoderCodec = exports.getHardwareDecoderCodec = exports.getHardwareContext = exports.CODEC_TO_CODEC_ID = void 0;
44
+ const NodeAv = __importStar(require("node-av"));
45
+ exports.CODEC_TO_CODEC_ID = {
46
+ avc: NodeAv.AV_CODEC_ID_H264,
47
+ hevc: NodeAv.AV_CODEC_ID_HEVC,
48
+ vp8: NodeAv.AV_CODEC_ID_VP8,
49
+ vp9: NodeAv.AV_CODEC_ID_VP9,
50
+ av1: NodeAv.AV_CODEC_ID_AV1,
51
+ aac: NodeAv.AV_CODEC_ID_AAC,
52
+ opus: NodeAv.AV_CODEC_ID_OPUS,
53
+ mp3: NodeAv.AV_CODEC_ID_MP3,
54
+ vorbis: NodeAv.AV_CODEC_ID_VORBIS,
55
+ flac: NodeAv.AV_CODEC_ID_FLAC,
56
+ ac3: NodeAv.AV_CODEC_ID_AC3,
57
+ eac3: NodeAv.AV_CODEC_ID_EAC3,
58
+ };
59
+ let cachedHardwareContext = undefined;
60
+ const getHardwareContext = () => {
61
+ if (cachedHardwareContext === undefined) {
62
+ cachedHardwareContext = NodeAv.HardwareContext.auto();
63
+ }
64
+ return cachedHardwareContext;
65
+ };
66
+ exports.getHardwareContext = getHardwareContext;
67
+ const hardwareDecoderCodecCache = new Map();
68
+ const getHardwareDecoderCodec = (codecId) => {
69
+ if (!hardwareDecoderCodecCache.has(codecId)) {
70
+ const hw = (0, exports.getHardwareContext)();
71
+ hardwareDecoderCodecCache.set(codecId, hw?.getDecoderCodec(codecId) ?? null);
72
+ }
73
+ return hardwareDecoderCodecCache.get(codecId);
74
+ };
75
+ exports.getHardwareDecoderCodec = getHardwareDecoderCodec;
76
+ const hardwareEncoderCodecCache = new Map();
77
+ const getHardwareEncoderCodec = (codecId) => {
78
+ if (!hardwareEncoderCodecCache.has(codecId)) {
79
+ const hw = (0, exports.getHardwareContext)();
80
+ hardwareEncoderCodecCache.set(codecId, hw?.getEncoderCodec(codecId) ?? null);
81
+ }
82
+ return hardwareEncoderCodecCache.get(codecId);
83
+ };
84
+ exports.getHardwareEncoderCodec = getHardwareEncoderCodec;
85
+ const mapColorPrimaries = (primaries) => {
86
+ switch (primaries) {
87
+ case 'bt709': return NodeAv.AVCOL_PRI_BT709;
88
+ case 'bt470bg': return NodeAv.AVCOL_PRI_BT470BG;
89
+ case 'smpte170m': return NodeAv.AVCOL_PRI_SMPTE170M;
90
+ case 'bt2020': return NodeAv.AVCOL_PRI_BT2020;
91
+ case 'smpte432': return NodeAv.AVCOL_PRI_SMPTE432;
92
+ }
93
+ return null;
94
+ };
95
+ exports.mapColorPrimaries = mapColorPrimaries;
96
+ const unmapColorPrimaries = (primaries) => {
97
+ switch (primaries) {
98
+ case NodeAv.AVCOL_PRI_BT709: return 'bt709';
99
+ case NodeAv.AVCOL_PRI_BT470BG: return 'bt470bg';
100
+ case NodeAv.AVCOL_PRI_SMPTE170M: return 'smpte170m';
101
+ case NodeAv.AVCOL_PRI_BT2020: return 'bt2020';
102
+ case NodeAv.AVCOL_PRI_SMPTE432: return 'smpte432';
103
+ }
104
+ return null;
105
+ };
106
+ exports.unmapColorPrimaries = unmapColorPrimaries;
107
+ const mapTransferCharacteristics = (transfer) => {
108
+ switch (transfer) {
109
+ case 'bt709': return NodeAv.AVCOL_TRC_BT709;
110
+ case 'smpte170m': return NodeAv.AVCOL_TRC_SMPTE170M;
111
+ case 'iec61966-2-1': return NodeAv.AVCOL_TRC_IEC61966_2_1;
112
+ case 'linear': return NodeAv.AVCOL_TRC_LINEAR;
113
+ case 'pq': return NodeAv.AVCOL_TRC_SMPTE2084;
114
+ case 'hlg': return NodeAv.AVCOL_TRC_ARIB_STD_B67;
115
+ }
116
+ return null;
117
+ };
118
+ exports.mapTransferCharacteristics = mapTransferCharacteristics;
119
+ const unmapTransferCharacteristics = (transfer) => {
120
+ switch (transfer) {
121
+ case NodeAv.AVCOL_TRC_BT709: return 'bt709';
122
+ case NodeAv.AVCOL_TRC_SMPTE170M: return 'smpte170m';
123
+ case NodeAv.AVCOL_TRC_IEC61966_2_1: return 'iec61966-2-1';
124
+ case NodeAv.AVCOL_TRC_LINEAR: return 'linear';
125
+ case NodeAv.AVCOL_TRC_SMPTE2084: return 'pq';
126
+ case NodeAv.AVCOL_TRC_ARIB_STD_B67: return 'hlg';
127
+ }
128
+ return null;
129
+ };
130
+ exports.unmapTransferCharacteristics = unmapTransferCharacteristics;
131
+ const mapMatrixCoefficients = (matrix) => {
132
+ switch (matrix) {
133
+ case 'rgb': return NodeAv.AVCOL_SPC_RGB;
134
+ case 'bt709': return NodeAv.AVCOL_SPC_BT709;
135
+ case 'bt470bg': return NodeAv.AVCOL_SPC_BT470BG;
136
+ case 'smpte170m': return NodeAv.AVCOL_SPC_SMPTE170M;
137
+ case 'bt2020-ncl': return NodeAv.AVCOL_SPC_BT2020_NCL;
138
+ }
139
+ return null;
140
+ };
141
+ exports.mapMatrixCoefficients = mapMatrixCoefficients;
142
+ const unmapMatrixCoefficients = (matrix) => {
143
+ switch (matrix) {
144
+ case NodeAv.AVCOL_SPC_RGB: return 'rgb';
145
+ case NodeAv.AVCOL_SPC_BT709: return 'bt709';
146
+ case NodeAv.AVCOL_SPC_BT470BG: return 'bt470bg';
147
+ case NodeAv.AVCOL_SPC_SMPTE170M: return 'smpte170m';
148
+ case NodeAv.AVCOL_SPC_BT2020_NCL: return 'bt2020-ncl';
149
+ }
150
+ return null;
151
+ };
152
+ exports.unmapMatrixCoefficients = unmapMatrixCoefficients;
153
+ const toPixelFormat = (ffmpegPixelFormat) => {
154
+ switch (ffmpegPixelFormat) {
155
+ case NodeAv.AV_PIX_FMT_YUV420P: return 'I420';
156
+ // "deprecated in favor of AV_PIX_FMT_YUV420P and setting color_range"
157
+ case NodeAv.AV_PIX_FMT_YUVJ420P: return 'I420';
158
+ case NodeAv.AV_PIX_FMT_YUV420P10LE: return 'I420P10';
159
+ case NodeAv.AV_PIX_FMT_YUV420P12LE: return 'I420P12';
160
+ case NodeAv.AV_PIX_FMT_YUVA420P: return 'I420A';
161
+ case NodeAv.AV_PIX_FMT_YUVA420P10LE: return 'I420AP10';
162
+ case NodeAv.AV_PIX_FMT_YUV422P: return 'I422';
163
+ // "deprecated in favor of AV_PIX_FMT_YUV422P and setting color_range"
164
+ case NodeAv.AV_PIX_FMT_YUVJ422P: return 'I422';
165
+ case NodeAv.AV_PIX_FMT_YUV422P10LE: return 'I422P10';
166
+ case NodeAv.AV_PIX_FMT_YUV422P12LE: return 'I422P12';
167
+ case NodeAv.AV_PIX_FMT_YUVA422P: return 'I422A';
168
+ case NodeAv.AV_PIX_FMT_YUVA422P10LE: return 'I422AP10';
169
+ case NodeAv.AV_PIX_FMT_YUVA422P12LE: return 'I422AP12';
170
+ case NodeAv.AV_PIX_FMT_YUV444P: return 'I444';
171
+ // "deprecated in favor of AV_PIX_FMT_YUV444P and setting color_range"
172
+ case NodeAv.AV_PIX_FMT_YUVJ444P: return 'I444';
173
+ case NodeAv.AV_PIX_FMT_YUV444P10LE: return 'I444P10';
174
+ case NodeAv.AV_PIX_FMT_YUV444P12LE: return 'I444P12';
175
+ case NodeAv.AV_PIX_FMT_YUVA444P: return 'I444A';
176
+ case NodeAv.AV_PIX_FMT_YUVA444P10LE: return 'I444AP10';
177
+ case NodeAv.AV_PIX_FMT_YUVA444P12LE: return 'I444AP12';
178
+ case NodeAv.AV_PIX_FMT_NV12: return 'NV12';
179
+ case NodeAv.AV_PIX_FMT_RGBA: return 'RGBA';
180
+ case NodeAv.AV_PIX_FMT_RGB0: return 'RGBX';
181
+ case NodeAv.AV_PIX_FMT_BGRA: return 'BGRA';
182
+ case NodeAv.AV_PIX_FMT_BGR0: return 'BGRX';
183
+ default: return null;
184
+ }
185
+ };
186
+ exports.toPixelFormat = toPixelFormat;
187
+ const fromPixelFormat = (pixelFormat) => {
188
+ switch (pixelFormat) {
189
+ case 'I420': return NodeAv.AV_PIX_FMT_YUV420P;
190
+ case 'I420P10': return NodeAv.AV_PIX_FMT_YUV420P10LE;
191
+ case 'I420P12': return NodeAv.AV_PIX_FMT_YUV420P12LE;
192
+ case 'I420A': return NodeAv.AV_PIX_FMT_YUVA420P;
193
+ case 'I420AP10': return NodeAv.AV_PIX_FMT_YUVA420P10LE;
194
+ case 'I422': return NodeAv.AV_PIX_FMT_YUV422P;
195
+ case 'I422P10': return NodeAv.AV_PIX_FMT_YUV422P10LE;
196
+ case 'I422P12': return NodeAv.AV_PIX_FMT_YUV422P12LE;
197
+ case 'I422A': return NodeAv.AV_PIX_FMT_YUVA422P;
198
+ case 'I422AP10': return NodeAv.AV_PIX_FMT_YUVA422P10LE;
199
+ case 'I422AP12': return NodeAv.AV_PIX_FMT_YUVA422P12LE;
200
+ case 'I444': return NodeAv.AV_PIX_FMT_YUV444P;
201
+ case 'I444P10': return NodeAv.AV_PIX_FMT_YUV444P10LE;
202
+ case 'I444P12': return NodeAv.AV_PIX_FMT_YUV444P12LE;
203
+ case 'I444A': return NodeAv.AV_PIX_FMT_YUVA444P;
204
+ case 'I444AP10': return NodeAv.AV_PIX_FMT_YUVA444P10LE;
205
+ case 'I444AP12': return NodeAv.AV_PIX_FMT_YUVA444P12LE;
206
+ case 'NV12': return NodeAv.AV_PIX_FMT_NV12;
207
+ case 'RGBA': return NodeAv.AV_PIX_FMT_RGBA;
208
+ case 'RGBX': return NodeAv.AV_PIX_FMT_RGB0;
209
+ case 'BGRA': return NodeAv.AV_PIX_FMT_BGRA;
210
+ case 'BGRX': return NodeAv.AV_PIX_FMT_BGR0;
211
+ default: return NodeAv.AV_PIX_FMT_NONE;
212
+ }
213
+ };
214
+ exports.fromPixelFormat = fromPixelFormat;
215
+ const toAudioSampleFormat = (ffmpegSampleFormat) => {
216
+ switch (ffmpegSampleFormat) {
217
+ case NodeAv.AV_SAMPLE_FMT_U8: return 'u8';
218
+ case NodeAv.AV_SAMPLE_FMT_S16: return 's16';
219
+ case NodeAv.AV_SAMPLE_FMT_S32: return 's32';
220
+ case NodeAv.AV_SAMPLE_FMT_FLT: return 'f32';
221
+ case NodeAv.AV_SAMPLE_FMT_U8P: return 'u8-planar';
222
+ case NodeAv.AV_SAMPLE_FMT_S16P: return 's16-planar';
223
+ case NodeAv.AV_SAMPLE_FMT_S32P: return 's32-planar';
224
+ case NodeAv.AV_SAMPLE_FMT_FLTP: return 'f32-planar';
225
+ default: return null;
226
+ }
227
+ };
228
+ exports.toAudioSampleFormat = toAudioSampleFormat;
229
+ const fromAudioSampleFormat = (sampleFormat) => {
230
+ switch (sampleFormat) {
231
+ case 'u8': return NodeAv.AV_SAMPLE_FMT_U8;
232
+ case 's16': return NodeAv.AV_SAMPLE_FMT_S16;
233
+ case 's32': return NodeAv.AV_SAMPLE_FMT_S32;
234
+ case 'f32': return NodeAv.AV_SAMPLE_FMT_FLT;
235
+ case 'u8-planar': return NodeAv.AV_SAMPLE_FMT_U8P;
236
+ case 's16-planar': return NodeAv.AV_SAMPLE_FMT_S16P;
237
+ case 's32-planar': return NodeAv.AV_SAMPLE_FMT_S32P;
238
+ case 'f32-planar': return NodeAv.AV_SAMPLE_FMT_FLTP;
239
+ default: return NodeAv.AV_SAMPLE_FMT_NONE;
240
+ }
241
+ };
242
+ exports.fromAudioSampleFormat = fromAudioSampleFormat;
243
+ const getChannelLayout = (numChannels) => {
244
+ switch (numChannels) {
245
+ case 1: return NodeAv.AV_CHANNEL_LAYOUT_MONO;
246
+ case 2: return NodeAv.AV_CHANNEL_LAYOUT_STEREO;
247
+ case 4: return NodeAv.AV_CHANNEL_LAYOUT_QUAD;
248
+ case 6: return NodeAv.AV_CHANNEL_LAYOUT_5POINT1_BACK;
249
+ case 8: return NodeAv.AV_CHANNEL_LAYOUT_7POINT1;
250
+ default: return { nbChannels: numChannels, order: NodeAv.AV_CHANNEL_ORDER_UNSPEC, mask: 0n };
251
+ }
252
+ };
253
+ exports.getChannelLayout = getChannelLayout;
254
+ // The value is incorrect in the node-av source code, so we do:
255
+ exports.LIBVPX_VP9 = 'libvpx-vp9';
@@ -0,0 +1,30 @@
1
+ /*!
2
+ * Copyright (c) 2026-present, Vanilagy and contributors
3
+ *
4
+ * This Source Code Form is subject to the terms of the Mozilla Public
5
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
6
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7
+ */
8
+ import { CustomVideoDecoder, VideoCodec, EncodedPacket, type MaybePromise, Rational } from 'mediabunny';
9
+ import * as NodeAv from 'node-av';
10
+ export declare class NodeAvVideoDecoder extends CustomVideoDecoder {
11
+ frame: NodeAv.Frame;
12
+ packet: NodeAv.Packet;
13
+ codecContext: NodeAv.CodecContext | null;
14
+ pixelAspectRatio: Rational;
15
+ preciseTimings: {
16
+ microsecondTimestamp: number;
17
+ timestamp: number;
18
+ duration: number;
19
+ timestampIsValid: boolean;
20
+ durationIsValid: boolean;
21
+ }[];
22
+ static supports(codec: VideoCodec, config: VideoDecoderConfig): boolean;
23
+ init(): Promise<void>;
24
+ initCodecContext(packet: EncodedPacket): Promise<void>;
25
+ decode(packet: EncodedPacket): Promise<void>;
26
+ receiveFrame(ret: number): void;
27
+ flush(): Promise<void>;
28
+ close(): MaybePromise<void>;
29
+ }
30
+ //# sourceMappingURL=video-decoder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"video-decoder.d.ts","sourceRoot":"","sources":["../../../src/video-decoder.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,aAAa,EAAe,KAAK,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACrH,OAAO,KAAK,MAAM,MAAM,SAAS,CAAC;AAKlC,qBAAa,kBAAmB,SAAQ,kBAAkB;IACzD,KAAK,EAAG,MAAM,CAAC,KAAK,CAAC;IACrB,MAAM,EAAG,MAAM,CAAC,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC,YAAY,GAAG,IAAI,CAAQ;IAChD,gBAAgB,EAAG,QAAQ,CAAC;IAG5B,cAAc,EAAE;QACf,oBAAoB,EAAE,MAAM,CAAC;QAC7B,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,gBAAgB,EAAE,OAAO,CAAC;QAC1B,eAAe,EAAE,OAAO,CAAC;KACzB,EAAE,CAAM;WAGO,QAAQ,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,kBAAkB,GAAG,OAAO;IAI1E,IAAI;IAOJ,gBAAgB,CAAC,MAAM,EAAE,aAAa;IAiDtC,MAAM,CAAC,MAAM,EAAE,aAAa;IAkElC,YAAY,CAAC,GAAG,EAAE,MAAM;IAuClB,KAAK;IAuBX,KAAK,IAAI,YAAY,CAAC,IAAI,CAAC;CAK3B"}