@remotion/webcodecs 4.0.236 → 4.0.239
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/audio-decoder.js +11 -7
- package/dist/audio-encoder.js +4 -2
- package/dist/auto-select-writer.d.ts +1 -1
- package/dist/auto-select-writer.js +22 -5
- package/dist/can-copy-audio-track.d.ts +4 -3
- package/dist/can-copy-audio-track.js +7 -6
- package/dist/can-copy-video-track.d.ts +4 -3
- package/dist/can-copy-video-track.js +7 -6
- package/dist/convert-media.js +2 -2
- package/dist/default-on-audio-track-handler.js +9 -11
- package/dist/default-on-video-track-handler.js +6 -15
- package/dist/esm/index.mjs +188 -140
- package/dist/io-manager/io-synchronizer.d.ts +4 -3
- package/dist/io-manager/io-synchronizer.js +25 -10
- package/dist/on-audio-track-handler.d.ts +4 -2
- package/dist/on-audio-track.d.ts +2 -2
- package/dist/on-audio-track.js +13 -6
- package/dist/on-frame.js +4 -1
- package/dist/on-video-track-handler.d.ts +4 -2
- package/dist/on-video-track.d.ts +2 -2
- package/dist/on-video-track.js +15 -6
- package/dist/video-decoder.js +5 -2
- package/dist/video-encoder.js +4 -2
- package/package.json +4 -4
- package/dist/codec-id.d.ts +0 -10
- package/dist/codec-id.js +0 -38
- package/dist/create-aac-codecprivate.d.ts +0 -14
- package/dist/create-aac-codecprivate.js +0 -72
- package/dist/io-manager/event-emitter.d.ts +0 -31
- package/dist/io-manager/event-emitter.js +0 -25
- package/dist/rotate-video.d.ts +0 -4
- package/dist/rotate-video.js +0 -43
- package/dist/test/aac-codecprivate.test.js +0 -12
- package/dist/with-resolvers.d.ts +0 -10
- package/dist/with-resolvers.js +0 -28
- /package/dist/test/{aac-codecprivate.test.d.ts → avi-to-mp4.test.d.ts} +0 -0
package/dist/audio-decoder.js
CHANGED
|
@@ -17,10 +17,11 @@ const createAudioDecoder = ({ onFrame, onError, signal, config, logLevel, track,
|
|
|
17
17
|
});
|
|
18
18
|
let outputQueue = Promise.resolve();
|
|
19
19
|
const audioDecoder = new AudioDecoder({
|
|
20
|
-
output(
|
|
21
|
-
|
|
20
|
+
output(frame) {
|
|
21
|
+
var _a;
|
|
22
|
+
ioSynchronizer.onOutput(frame.timestamp + ((_a = frame.duration) !== null && _a !== void 0 ? _a : 0));
|
|
22
23
|
const abortHandler = () => {
|
|
23
|
-
|
|
24
|
+
frame.close();
|
|
24
25
|
};
|
|
25
26
|
signal.addEventListener('abort', abortHandler, { once: true });
|
|
26
27
|
outputQueue = outputQueue
|
|
@@ -28,7 +29,7 @@ const createAudioDecoder = ({ onFrame, onError, signal, config, logLevel, track,
|
|
|
28
29
|
if (signal.aborted) {
|
|
29
30
|
return;
|
|
30
31
|
}
|
|
31
|
-
return onFrame(
|
|
32
|
+
return onFrame(frame);
|
|
32
33
|
})
|
|
33
34
|
.then(() => {
|
|
34
35
|
ioSynchronizer.onProcessed();
|
|
@@ -36,7 +37,7 @@ const createAudioDecoder = ({ onFrame, onError, signal, config, logLevel, track,
|
|
|
36
37
|
return Promise.resolve();
|
|
37
38
|
})
|
|
38
39
|
.catch((err) => {
|
|
39
|
-
|
|
40
|
+
frame.close();
|
|
40
41
|
onError(err);
|
|
41
42
|
});
|
|
42
43
|
},
|
|
@@ -58,13 +59,16 @@ const createAudioDecoder = ({ onFrame, onError, signal, config, logLevel, track,
|
|
|
58
59
|
signal.addEventListener('abort', onAbort);
|
|
59
60
|
audioDecoder.configure(config);
|
|
60
61
|
const processSample = async (audioSample) => {
|
|
62
|
+
var _a, _b;
|
|
61
63
|
if (audioDecoder.state === 'closed') {
|
|
62
64
|
return;
|
|
63
65
|
}
|
|
66
|
+
progressTracker.setPossibleLowestTimestamp(Math.min(audioSample.timestamp, (_a = audioSample.dts) !== null && _a !== void 0 ? _a : Infinity, (_b = audioSample.cts) !== null && _b !== void 0 ? _b : Infinity));
|
|
64
67
|
await ioSynchronizer.waitFor({
|
|
65
68
|
unemitted: 20,
|
|
66
|
-
|
|
69
|
+
unprocessed: 20,
|
|
67
70
|
minimumProgress: audioSample.timestamp - 10000000,
|
|
71
|
+
signal,
|
|
68
72
|
});
|
|
69
73
|
// Don't flush, it messes up the audio
|
|
70
74
|
const chunk = new EncodedAudioChunk(audioSample);
|
|
@@ -89,7 +93,7 @@ const createAudioDecoder = ({ onFrame, onError, signal, config, logLevel, track,
|
|
|
89
93
|
}
|
|
90
94
|
catch (_a) { }
|
|
91
95
|
await queue;
|
|
92
|
-
await ioSynchronizer.waitForFinish();
|
|
96
|
+
await ioSynchronizer.waitForFinish(signal);
|
|
93
97
|
await outputQueue;
|
|
94
98
|
},
|
|
95
99
|
close,
|
package/dist/audio-encoder.js
CHANGED
|
@@ -58,10 +58,12 @@ const createAudioEncoder = ({ onChunk, onError, codec, signal, config: audioEnco
|
|
|
58
58
|
if (encoder.state === 'closed') {
|
|
59
59
|
return;
|
|
60
60
|
}
|
|
61
|
+
progressTracker.setPossibleLowestTimestamp(audioData.timestamp);
|
|
61
62
|
await ioSynchronizer.waitFor({
|
|
62
63
|
unemitted: 20,
|
|
63
|
-
|
|
64
|
+
unprocessed: 20,
|
|
64
65
|
minimumProgress: audioData.timestamp - 10000000,
|
|
66
|
+
signal,
|
|
65
67
|
});
|
|
66
68
|
// @ts-expect-error - can have changed in the meanwhile
|
|
67
69
|
if (encoder.state === 'closed') {
|
|
@@ -90,7 +92,7 @@ const createAudioEncoder = ({ onChunk, onError, codec, signal, config: audioEnco
|
|
|
90
92
|
},
|
|
91
93
|
waitForFinish: async () => {
|
|
92
94
|
await encoder.flush();
|
|
93
|
-
await ioSynchronizer.waitForFinish();
|
|
95
|
+
await ioSynchronizer.waitForFinish(signal);
|
|
94
96
|
await prom;
|
|
95
97
|
},
|
|
96
98
|
close,
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type WriterInterface } from '@remotion/media-parser';
|
|
2
2
|
import type { LogLevel } from './log';
|
|
3
3
|
export declare const autoSelectWriter: (writer: WriterInterface | undefined, logLevel: LogLevel) => Promise<WriterInterface>;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.autoSelectWriter = void 0;
|
|
4
|
-
const buffer_1 = require("@remotion/media-parser/buffer");
|
|
5
4
|
const web_fs_1 = require("@remotion/media-parser/web-fs");
|
|
5
|
+
const media_parser_1 = require("@remotion/media-parser");
|
|
6
|
+
const buffer_1 = require("@remotion/media-parser/buffer");
|
|
6
7
|
const log_1 = require("./log");
|
|
7
8
|
const autoSelectWriter = async (writer, logLevel) => {
|
|
8
9
|
if (writer) {
|
|
@@ -10,11 +11,27 @@ const autoSelectWriter = async (writer, logLevel) => {
|
|
|
10
11
|
return writer;
|
|
11
12
|
}
|
|
12
13
|
log_1.Log.verbose(logLevel, 'Determining best writer');
|
|
13
|
-
if
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
// Check if we're offline using the navigator API
|
|
15
|
+
const isOffline = !navigator.onLine;
|
|
16
|
+
if (isOffline) {
|
|
17
|
+
log_1.Log.verbose(logLevel, 'Offline mode detected, using buffer writer');
|
|
18
|
+
return buffer_1.bufferWriter;
|
|
19
|
+
}
|
|
20
|
+
try {
|
|
21
|
+
const { promise: timeout, reject, resolve, } = media_parser_1.MediaParserInternals.withResolvers();
|
|
22
|
+
const time = setTimeout(() => reject(new Error('WebFS check timeout')), 2000);
|
|
23
|
+
const webFsSupported = await Promise.race([(0, web_fs_1.canUseWebFsWriter)(), timeout]);
|
|
24
|
+
resolve();
|
|
25
|
+
clearTimeout(time);
|
|
26
|
+
if (webFsSupported) {
|
|
27
|
+
log_1.Log.verbose(logLevel, 'Using WebFS writer because it is supported');
|
|
28
|
+
return web_fs_1.webFsWriter;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
log_1.Log.verbose(logLevel, `WebFS check failed: ${err}. Falling back to buffer writer`);
|
|
16
33
|
}
|
|
17
|
-
log_1.Log.verbose(logLevel, 'Using buffer writer because WebFS writer is not supported');
|
|
34
|
+
log_1.Log.verbose(logLevel, 'Using buffer writer because WebFS writer is not supported or unavailable');
|
|
18
35
|
return buffer_1.bufferWriter;
|
|
19
36
|
};
|
|
20
37
|
exports.autoSelectWriter = autoSelectWriter;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import type { MediaParserAudioCodec } from '@remotion/media-parser';
|
|
1
|
+
import type { MediaParserAudioCodec, ParseMediaContainer } from '@remotion/media-parser';
|
|
2
2
|
import type { ConvertMediaContainer } from './get-available-containers';
|
|
3
|
-
export declare const canCopyAudioTrack: ({ inputCodec,
|
|
3
|
+
export declare const canCopyAudioTrack: ({ inputCodec, outputContainer, inputContainer, }: {
|
|
4
4
|
inputCodec: MediaParserAudioCodec;
|
|
5
|
-
|
|
5
|
+
outputContainer: ConvertMediaContainer;
|
|
6
|
+
inputContainer: ParseMediaContainer;
|
|
6
7
|
}) => boolean;
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.canCopyAudioTrack = void 0;
|
|
4
|
-
const canCopyAudioTrack = ({ inputCodec,
|
|
5
|
-
if (
|
|
4
|
+
const canCopyAudioTrack = ({ inputCodec, outputContainer, inputContainer, }) => {
|
|
5
|
+
if (outputContainer === 'webm') {
|
|
6
6
|
return inputCodec === 'opus';
|
|
7
7
|
}
|
|
8
|
-
if (
|
|
9
|
-
return inputCodec === 'aac'
|
|
8
|
+
if (outputContainer === 'mp4') {
|
|
9
|
+
return (inputCodec === 'aac' &&
|
|
10
|
+
(inputContainer === 'mp4' || inputContainer === 'avi'));
|
|
10
11
|
}
|
|
11
|
-
if (
|
|
12
|
+
if (outputContainer === 'wav') {
|
|
12
13
|
return false;
|
|
13
14
|
}
|
|
14
|
-
throw new Error(`Unhandled
|
|
15
|
+
throw new Error(`Unhandled container: ${outputContainer}`);
|
|
15
16
|
};
|
|
16
17
|
exports.canCopyAudioTrack = canCopyAudioTrack;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import type { MediaParserVideoCodec } from '@remotion/media-parser';
|
|
1
|
+
import type { MediaParserVideoCodec, ParseMediaContainer } from '@remotion/media-parser';
|
|
2
2
|
import type { ConvertMediaContainer } from './get-available-containers';
|
|
3
|
-
export declare const canCopyVideoTrack: ({ inputCodec,
|
|
3
|
+
export declare const canCopyVideoTrack: ({ inputCodec, outputContainer, inputRotation, rotationToApply, inputContainer, }: {
|
|
4
|
+
inputContainer: ParseMediaContainer;
|
|
4
5
|
inputCodec: MediaParserVideoCodec;
|
|
5
6
|
inputRotation: number;
|
|
6
7
|
rotationToApply: number;
|
|
7
|
-
|
|
8
|
+
outputContainer: ConvertMediaContainer;
|
|
8
9
|
}) => boolean;
|
|
@@ -2,20 +2,21 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.canCopyVideoTrack = void 0;
|
|
4
4
|
const rotate_video_frame_1 = require("./rotate-video-frame");
|
|
5
|
-
const canCopyVideoTrack = ({ inputCodec,
|
|
5
|
+
const canCopyVideoTrack = ({ inputCodec, outputContainer, inputRotation, rotationToApply, inputContainer, }) => {
|
|
6
6
|
if ((0, rotate_video_frame_1.normalizeVideoRotation)(inputRotation) !==
|
|
7
7
|
(0, rotate_video_frame_1.normalizeVideoRotation)(rotationToApply)) {
|
|
8
8
|
return false;
|
|
9
9
|
}
|
|
10
|
-
if (
|
|
10
|
+
if (outputContainer === 'webm') {
|
|
11
11
|
return inputCodec === 'vp8' || inputCodec === 'vp9';
|
|
12
12
|
}
|
|
13
|
-
if (
|
|
14
|
-
return inputCodec === 'h264'
|
|
13
|
+
if (outputContainer === 'mp4') {
|
|
14
|
+
return (inputCodec === 'h264' &&
|
|
15
|
+
(inputContainer === 'mp4' || inputContainer === 'avi'));
|
|
15
16
|
}
|
|
16
|
-
if (
|
|
17
|
+
if (outputContainer === 'wav') {
|
|
17
18
|
return false;
|
|
18
19
|
}
|
|
19
|
-
throw new Error(`Unhandled codec: ${
|
|
20
|
+
throw new Error(`Unhandled codec: ${outputContainer}`);
|
|
20
21
|
};
|
|
21
22
|
exports.canCopyVideoTrack = canCopyVideoTrack;
|
package/dist/convert-media.js
CHANGED
|
@@ -87,7 +87,7 @@ const convertMedia = async function ({ src, onVideoFrame, onProgress: onProgress
|
|
|
87
87
|
defaultVideoCodec: videoCodec !== null && videoCodec !== void 0 ? videoCodec : null,
|
|
88
88
|
onVideoTrack: userVideoResolver !== null && userVideoResolver !== void 0 ? userVideoResolver : null,
|
|
89
89
|
logLevel,
|
|
90
|
-
container,
|
|
90
|
+
outputContainer: container,
|
|
91
91
|
rotate: rotate !== null && rotate !== void 0 ? rotate : 0,
|
|
92
92
|
progress: progressTracker,
|
|
93
93
|
});
|
|
@@ -99,7 +99,7 @@ const convertMedia = async function ({ src, onVideoFrame, onProgress: onProgress
|
|
|
99
99
|
state,
|
|
100
100
|
onAudioTrack: userAudioResolver !== null && userAudioResolver !== void 0 ? userAudioResolver : null,
|
|
101
101
|
logLevel,
|
|
102
|
-
container,
|
|
102
|
+
outputContainer: container,
|
|
103
103
|
progressTracker,
|
|
104
104
|
});
|
|
105
105
|
(0, media_parser_1.parseMedia)({
|
|
@@ -2,23 +2,21 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.defaultOnAudioTrackHandler = void 0;
|
|
4
4
|
const media_parser_1 = require("@remotion/media-parser");
|
|
5
|
-
const can_copy_audio_track_1 = require("./can-copy-audio-track");
|
|
6
5
|
const can_reencode_audio_track_1 = require("./can-reencode-audio-track");
|
|
7
|
-
const get_default_audio_codec_1 = require("./get-default-audio-codec");
|
|
8
6
|
const DEFAULT_BITRATE = 128000;
|
|
9
|
-
const defaultOnAudioTrackHandler = async ({ track, defaultAudioCodec, logLevel,
|
|
7
|
+
const defaultOnAudioTrackHandler = async ({ track, defaultAudioCodec, logLevel, canCopyTrack, }) => {
|
|
10
8
|
const bitrate = DEFAULT_BITRATE;
|
|
11
|
-
|
|
12
|
-
inputCodec: track.codecWithoutConfig,
|
|
13
|
-
container,
|
|
14
|
-
});
|
|
15
|
-
if (canCopy) {
|
|
9
|
+
if (canCopyTrack) {
|
|
16
10
|
media_parser_1.MediaParserInternals.Log.verbose(logLevel, `Track ${track.trackId} (audio): Can copy track, therefore copying`);
|
|
17
11
|
return Promise.resolve({ type: 'copy' });
|
|
18
12
|
}
|
|
19
|
-
|
|
13
|
+
// The idea is that for example for GIFs, we will return defaultAudioCodec = null
|
|
14
|
+
if (defaultAudioCodec === null) {
|
|
15
|
+
media_parser_1.MediaParserInternals.Log.verbose(logLevel, `Track ${track.trackId} (audio): Container does not support audio, dropping audio`);
|
|
16
|
+
return Promise.resolve({ type: 'drop' });
|
|
17
|
+
}
|
|
20
18
|
const canReencode = await (0, can_reencode_audio_track_1.canReencodeAudioTrack)({
|
|
21
|
-
audioCodec,
|
|
19
|
+
audioCodec: defaultAudioCodec,
|
|
22
20
|
track,
|
|
23
21
|
bitrate,
|
|
24
22
|
});
|
|
@@ -27,7 +25,7 @@ const defaultOnAudioTrackHandler = async ({ track, defaultAudioCodec, logLevel,
|
|
|
27
25
|
return Promise.resolve({
|
|
28
26
|
type: 'reencode',
|
|
29
27
|
bitrate,
|
|
30
|
-
audioCodec,
|
|
28
|
+
audioCodec: defaultAudioCodec,
|
|
31
29
|
});
|
|
32
30
|
}
|
|
33
31
|
media_parser_1.MediaParserInternals.Log.verbose(logLevel, `Track ${track.trackId} (audio): Can neither re-encode nor copy, failing render`);
|
|
@@ -2,34 +2,25 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.defaultOnVideoTrackHandler = void 0;
|
|
4
4
|
const media_parser_1 = require("@remotion/media-parser");
|
|
5
|
-
const can_copy_video_track_1 = require("./can-copy-video-track");
|
|
6
5
|
const can_reencode_video_track_1 = require("./can-reencode-video-track");
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
const canCopy = (0, can_copy_video_track_1.canCopyVideoTrack)({
|
|
10
|
-
inputCodec: track.codecWithoutConfig,
|
|
11
|
-
container,
|
|
12
|
-
inputRotation: track.rotation,
|
|
13
|
-
rotationToApply: rotate,
|
|
14
|
-
});
|
|
15
|
-
if (canCopy) {
|
|
6
|
+
const defaultOnVideoTrackHandler = async ({ track, defaultVideoCodec, logLevel, rotate, canCopyTrack, }) => {
|
|
7
|
+
if (canCopyTrack) {
|
|
16
8
|
media_parser_1.MediaParserInternals.Log.verbose(logLevel, `Track ${track.trackId} (video): Can copy, therefore copying`);
|
|
17
9
|
return Promise.resolve({ type: 'copy' });
|
|
18
10
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
media_parser_1.MediaParserInternals.Log.verbose(logLevel, `Track ${track.trackId} (video): No default video codec, therefore dropping`);
|
|
11
|
+
if (defaultVideoCodec === null) {
|
|
12
|
+
media_parser_1.MediaParserInternals.Log.verbose(logLevel, `Track ${track.trackId} (video): Is audio container, therefore dropping video`);
|
|
22
13
|
return Promise.resolve({ type: 'drop' });
|
|
23
14
|
}
|
|
24
15
|
const canReencode = await (0, can_reencode_video_track_1.canReencodeVideoTrack)({
|
|
25
|
-
videoCodec,
|
|
16
|
+
videoCodec: defaultVideoCodec,
|
|
26
17
|
track,
|
|
27
18
|
});
|
|
28
19
|
if (canReencode) {
|
|
29
20
|
media_parser_1.MediaParserInternals.Log.verbose(logLevel, `Track ${track.trackId} (video): Cannot copy, but re-enconde, therefore re-encoding`);
|
|
30
21
|
return Promise.resolve({
|
|
31
22
|
type: 'reencode',
|
|
32
|
-
videoCodec,
|
|
23
|
+
videoCodec: defaultVideoCodec,
|
|
33
24
|
rotation: rotate - track.rotation,
|
|
34
25
|
});
|
|
35
26
|
}
|