@remotion/webcodecs 4.0.229 → 4.0.231
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 +12 -1
- package/dist/arraybuffer-to-uint8-array.d.ts +1 -0
- package/dist/arraybuffer-to-uint8-array.js +7 -0
- package/dist/audio-decoder.d.ts +2 -2
- package/dist/audio-encoder-config.js +15 -2
- package/dist/audio-encoder.d.ts +2 -1
- package/dist/audio-encoder.js +17 -5
- package/dist/browser-quirks.d.ts +2 -0
- package/dist/browser-quirks.js +11 -0
- package/dist/can-copy-audio-track.d.ts +2 -4
- package/dist/can-copy-audio-track.js +7 -4
- package/dist/can-copy-video-track.d.ts +2 -4
- package/dist/can-copy-video-track.js +6 -6
- package/dist/can-reencode-audio-track.js +1 -6
- package/dist/can-reencode-video-track.js +1 -0
- package/dist/choose-correct-avc1-profile.d.ts +5 -0
- package/dist/choose-correct-avc1-profile.js +54 -0
- package/dist/codec-id.d.ts +7 -4
- package/dist/codec-id.js +28 -5
- package/dist/convert-encoded-chunk.d.ts +2 -1
- package/dist/convert-encoded-chunk.js +25 -2
- package/dist/convert-media.d.ts +13 -12
- package/dist/convert-media.js +62 -46
- package/dist/convert-to-correct-videoframe.d.ts +9 -0
- package/dist/convert-to-correct-videoframe.js +28 -0
- package/dist/default-on-audio-track-handler.d.ts +2 -0
- package/dist/default-on-audio-track-handler.js +36 -0
- package/dist/default-on-video-track-handler.d.ts +2 -0
- package/dist/default-on-video-track-handler.js +29 -0
- package/dist/esm/index.mjs +493 -174
- package/dist/generate-output-filename.d.ts +2 -0
- package/dist/generate-output-filename.js +14 -0
- package/dist/get-default-audio-codec.d.ts +4 -0
- package/dist/get-default-audio-codec.js +13 -0
- package/dist/get-default-video-codec.d.ts +4 -0
- package/dist/get-default-video-codec.js +10 -0
- package/dist/index.d.ts +12 -8
- package/dist/index.js +12 -1
- package/dist/io-manager/io-synchronizer.js +2 -2
- package/dist/{resolve-audio-action.d.ts → on-audio-track-handler.d.ts} +5 -5
- package/dist/on-audio-track-handler.js +2 -0
- package/dist/on-audio-track.d.ts +7 -8
- package/dist/on-audio-track.js +55 -16
- package/dist/on-frame.d.ts +4 -4
- package/dist/on-frame.js +15 -9
- package/dist/{resolve-video-action.d.ts → on-video-track-handler.d.ts} +5 -5
- package/dist/on-video-track-handler.js +2 -0
- package/dist/on-video-track.d.ts +8 -8
- package/dist/on-video-track.js +49 -15
- package/dist/set-remotion-imported.d.ts +6 -0
- package/dist/set-remotion-imported.js +25 -0
- package/dist/throttled-state-update.d.ts +13 -0
- package/dist/throttled-state-update.js +49 -0
- package/dist/video-decoder.d.ts +2 -2
- package/dist/video-decoder.js +5 -0
- package/dist/video-encoder-config.d.ts +2 -1
- package/dist/video-encoder-config.js +9 -2
- package/dist/video-encoder.d.ts +4 -2
- package/dist/video-encoder.js +12 -10
- package/package.json +4 -3
- package/dist/can-reencode-audio.d.ts +0 -7
- package/dist/can-reencode-audio.js +0 -21
- package/dist/can-reencode-video.d.ts +0 -6
- package/dist/can-reencode-video.js +0 -15
- package/dist/event-emitter.d.ts +0 -25
- package/dist/event-emitter.js +0 -23
- package/dist/polyfill-encoded-audio-chunk.d.ts +0 -3
- package/dist/polyfill-encoded-audio-chunk.js +0 -5
- package/dist/resolve-audio-action.js +0 -32
- package/dist/resolve-video-action.js +0 -26
- package/dist/wait-until-return.d.ts +0 -4
- package/dist/wait-until-return.js +0 -14
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateOutputFilename = void 0;
|
|
4
|
+
const generateOutputFilename = (source, container) => {
|
|
5
|
+
const filename = typeof source === 'string'
|
|
6
|
+
? source
|
|
7
|
+
: source instanceof File
|
|
8
|
+
? source.name
|
|
9
|
+
: 'converted';
|
|
10
|
+
const behindSlash = filename.split('/').pop();
|
|
11
|
+
const withoutExtension = behindSlash.split('.').slice(0, -1).join('.');
|
|
12
|
+
return `${withoutExtension}.${container}`;
|
|
13
|
+
};
|
|
14
|
+
exports.generateOutputFilename = generateOutputFilename;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getDefaultAudioCodec = void 0;
|
|
4
|
+
const getDefaultAudioCodec = ({ container, }) => {
|
|
5
|
+
if (container === 'webm') {
|
|
6
|
+
return 'opus';
|
|
7
|
+
}
|
|
8
|
+
if (container === 'mp4') {
|
|
9
|
+
return 'aac';
|
|
10
|
+
}
|
|
11
|
+
throw new Error(`Unhandled container: ${container}`);
|
|
12
|
+
};
|
|
13
|
+
exports.getDefaultAudioCodec = getDefaultAudioCodec;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getDefaultVideoCodec = void 0;
|
|
4
|
+
const getDefaultVideoCodec = ({ container, }) => {
|
|
5
|
+
if (container === 'webm') {
|
|
6
|
+
return 'vp8';
|
|
7
|
+
}
|
|
8
|
+
throw new Error(`Unhandled container: ${container} satisfies never`);
|
|
9
|
+
};
|
|
10
|
+
exports.getDefaultVideoCodec = getDefaultVideoCodec;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export {
|
|
1
|
+
export { createAudioDecoder, WebCodecsAudioDecoder } from './audio-decoder';
|
|
2
|
+
export { createAudioEncoder, WebCodecsAudioEncoder } from './audio-encoder';
|
|
3
3
|
export { canCopyAudioTrack } from './can-copy-audio-track';
|
|
4
4
|
export { canCopyVideoTrack } from './can-copy-video-track';
|
|
5
5
|
export { canReencodeAudioTrack } from './can-reencode-audio-track';
|
|
6
6
|
export { canReencodeVideoTrack } from './can-reencode-video-track';
|
|
7
|
-
export { ConvertMediaAudioCodec, ConvertMediaVideoCodec, getAvailableAudioCodecs, getAvailableVideoCodecs, } from './codec-id';
|
|
8
|
-
export {
|
|
9
|
-
export {
|
|
10
|
-
export {
|
|
11
|
-
export {
|
|
12
|
-
export {
|
|
7
|
+
export { ConvertMediaAudioCodec, ConvertMediaContainer, ConvertMediaVideoCodec, getAvailableAudioCodecs, getAvailableContainers, getAvailableVideoCodecs, } from './codec-id';
|
|
8
|
+
export { convertMedia, ConvertMediaOnProgress, ConvertMediaOnVideoFrame, ConvertMediaProgress, ConvertMediaResult, } from './convert-media';
|
|
9
|
+
export { defaultOnAudioTrackHandler } from './default-on-audio-track-handler';
|
|
10
|
+
export { defaultOnVideoTrackHandler } from './default-on-video-track-handler';
|
|
11
|
+
export { getDefaultAudioCodec } from './get-default-audio-codec';
|
|
12
|
+
export { getDefaultVideoCodec } from './get-default-video-codec';
|
|
13
|
+
export { AudioOperation, ConvertMediaOnAudioTrackHandler, } from './on-audio-track-handler';
|
|
14
|
+
export { ConvertMediaOnVideoTrackHandler, VideoOperation, } from './on-video-track-handler';
|
|
15
|
+
export { createVideoDecoder, WebCodecsVideoDecoder } from './video-decoder';
|
|
16
|
+
export { createVideoEncoder, WebCodecsVideoEncoder } from './video-encoder';
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createVideoEncoder = exports.createVideoDecoder = exports.convertMedia = exports.getAvailableVideoCodecs = exports.getAvailableAudioCodecs = exports.canReencodeVideoTrack = exports.canReencodeAudioTrack = exports.canCopyVideoTrack = exports.canCopyAudioTrack = exports.createAudioEncoder = exports.createAudioDecoder = void 0;
|
|
3
|
+
exports.createVideoEncoder = exports.createVideoDecoder = exports.getDefaultVideoCodec = exports.getDefaultAudioCodec = exports.defaultOnVideoTrackHandler = exports.defaultOnAudioTrackHandler = exports.convertMedia = exports.getAvailableVideoCodecs = exports.getAvailableContainers = exports.getAvailableAudioCodecs = exports.canReencodeVideoTrack = exports.canReencodeAudioTrack = exports.canCopyVideoTrack = exports.canCopyAudioTrack = exports.createAudioEncoder = exports.createAudioDecoder = void 0;
|
|
4
|
+
const set_remotion_imported_1 = require("./set-remotion-imported");
|
|
4
5
|
var audio_decoder_1 = require("./audio-decoder");
|
|
5
6
|
Object.defineProperty(exports, "createAudioDecoder", { enumerable: true, get: function () { return audio_decoder_1.createAudioDecoder; } });
|
|
6
7
|
var audio_encoder_1 = require("./audio-encoder");
|
|
@@ -15,10 +16,20 @@ var can_reencode_video_track_1 = require("./can-reencode-video-track");
|
|
|
15
16
|
Object.defineProperty(exports, "canReencodeVideoTrack", { enumerable: true, get: function () { return can_reencode_video_track_1.canReencodeVideoTrack; } });
|
|
16
17
|
var codec_id_1 = require("./codec-id");
|
|
17
18
|
Object.defineProperty(exports, "getAvailableAudioCodecs", { enumerable: true, get: function () { return codec_id_1.getAvailableAudioCodecs; } });
|
|
19
|
+
Object.defineProperty(exports, "getAvailableContainers", { enumerable: true, get: function () { return codec_id_1.getAvailableContainers; } });
|
|
18
20
|
Object.defineProperty(exports, "getAvailableVideoCodecs", { enumerable: true, get: function () { return codec_id_1.getAvailableVideoCodecs; } });
|
|
19
21
|
var convert_media_1 = require("./convert-media");
|
|
20
22
|
Object.defineProperty(exports, "convertMedia", { enumerable: true, get: function () { return convert_media_1.convertMedia; } });
|
|
23
|
+
var default_on_audio_track_handler_1 = require("./default-on-audio-track-handler");
|
|
24
|
+
Object.defineProperty(exports, "defaultOnAudioTrackHandler", { enumerable: true, get: function () { return default_on_audio_track_handler_1.defaultOnAudioTrackHandler; } });
|
|
25
|
+
var default_on_video_track_handler_1 = require("./default-on-video-track-handler");
|
|
26
|
+
Object.defineProperty(exports, "defaultOnVideoTrackHandler", { enumerable: true, get: function () { return default_on_video_track_handler_1.defaultOnVideoTrackHandler; } });
|
|
27
|
+
var get_default_audio_codec_1 = require("./get-default-audio-codec");
|
|
28
|
+
Object.defineProperty(exports, "getDefaultAudioCodec", { enumerable: true, get: function () { return get_default_audio_codec_1.getDefaultAudioCodec; } });
|
|
29
|
+
var get_default_video_codec_1 = require("./get-default-video-codec");
|
|
30
|
+
Object.defineProperty(exports, "getDefaultVideoCodec", { enumerable: true, get: function () { return get_default_video_codec_1.getDefaultVideoCodec; } });
|
|
21
31
|
var video_decoder_1 = require("./video-decoder");
|
|
22
32
|
Object.defineProperty(exports, "createVideoDecoder", { enumerable: true, get: function () { return video_decoder_1.createVideoDecoder; } });
|
|
23
33
|
var video_encoder_1 = require("./video-encoder");
|
|
24
34
|
Object.defineProperty(exports, "createVideoEncoder", { enumerable: true, get: function () { return video_encoder_1.createVideoEncoder; } });
|
|
35
|
+
(0, set_remotion_imported_1.setRemotionImported)();
|
|
@@ -17,11 +17,11 @@ const makeIoSynchronizer = (logLevel, label) => {
|
|
|
17
17
|
let unprocessed = 0;
|
|
18
18
|
const getUnprocessed = () => unprocessed;
|
|
19
19
|
const getUnemittedItems = () => {
|
|
20
|
-
inputs = inputs.filter((input) => input > lastOutput);
|
|
20
|
+
inputs = inputs.filter((input) => Math.floor(input) > Math.floor(lastOutput));
|
|
21
21
|
return inputs.length;
|
|
22
22
|
};
|
|
23
23
|
const getUnemittedKeyframes = () => {
|
|
24
|
-
keyframes = keyframes.filter((keyframe) => keyframe > lastOutput);
|
|
24
|
+
keyframes = keyframes.filter((keyframe) => Math.floor(keyframe) > Math.floor(lastOutput));
|
|
25
25
|
return keyframes.length;
|
|
26
26
|
};
|
|
27
27
|
const printState = (prefix) => {
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import type { AudioTrack, LogLevel } from '@remotion/media-parser';
|
|
2
|
-
import type { ConvertMediaAudioCodec } from './codec-id';
|
|
3
|
-
import type { ConvertMediaContainer } from './convert-media';
|
|
2
|
+
import type { ConvertMediaAudioCodec, ConvertMediaContainer } from './codec-id';
|
|
4
3
|
export type AudioOperation = {
|
|
5
4
|
type: 'reencode';
|
|
6
5
|
bitrate: number;
|
|
7
6
|
audioCodec: ConvertMediaAudioCodec;
|
|
8
7
|
} | {
|
|
9
8
|
type: 'copy';
|
|
9
|
+
} | {
|
|
10
|
+
type: 'fail';
|
|
10
11
|
} | {
|
|
11
12
|
type: 'drop';
|
|
12
13
|
};
|
|
13
|
-
export type
|
|
14
|
+
export type ConvertMediaOnAudioTrackHandler = (options: {
|
|
14
15
|
track: AudioTrack;
|
|
15
|
-
|
|
16
|
+
defaultAudioCodec: ConvertMediaAudioCodec | null;
|
|
16
17
|
logLevel: LogLevel;
|
|
17
18
|
container: ConvertMediaContainer;
|
|
18
19
|
}) => AudioOperation | Promise<AudioOperation>;
|
|
19
|
-
export declare const defaultResolveAudioAction: ResolveAudioActionFn;
|
package/dist/on-audio-track.d.ts
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import type { LogLevel, MediaFn, OnAudioTrack } from '@remotion/media-parser';
|
|
2
|
-
import type { ConvertMediaAudioCodec } from './codec-id';
|
|
3
|
-
import type { ConvertMediaContainer, ConvertMediaState } from './convert-media';
|
|
2
|
+
import type { ConvertMediaAudioCodec, ConvertMediaContainer } from './codec-id';
|
|
4
3
|
import Error from './error-cause';
|
|
5
|
-
import type {
|
|
6
|
-
|
|
4
|
+
import type { ConvertMediaOnAudioTrackHandler } from './on-audio-track-handler';
|
|
5
|
+
import type { ConvertMediaProgressFn } from './throttled-state-update';
|
|
6
|
+
export declare const makeAudioTrackHandler: ({ state, defaultAudioCodec: audioCodec, controller, abortConversion, onMediaStateUpdate, onAudioTrack, logLevel, container, }: {
|
|
7
7
|
state: MediaFn;
|
|
8
|
-
|
|
9
|
-
convertMediaState: ConvertMediaState;
|
|
8
|
+
defaultAudioCodec: ConvertMediaAudioCodec | null;
|
|
10
9
|
controller: AbortController;
|
|
11
10
|
abortConversion: (errCause: Error) => void;
|
|
12
|
-
onMediaStateUpdate: null |
|
|
13
|
-
onAudioTrack:
|
|
11
|
+
onMediaStateUpdate: null | ConvertMediaProgressFn;
|
|
12
|
+
onAudioTrack: ConvertMediaOnAudioTrackHandler | null;
|
|
14
13
|
logLevel: LogLevel;
|
|
15
14
|
container: ConvertMediaContainer;
|
|
16
15
|
}) => OnAudioTrack;
|
package/dist/on-audio-track.js
CHANGED
|
@@ -9,11 +9,12 @@ const audio_decoder_config_1 = require("./audio-decoder-config");
|
|
|
9
9
|
const audio_encoder_1 = require("./audio-encoder");
|
|
10
10
|
const audio_encoder_config_1 = require("./audio-encoder-config");
|
|
11
11
|
const convert_encoded_chunk_1 = require("./convert-encoded-chunk");
|
|
12
|
+
const default_on_audio_track_handler_1 = require("./default-on-audio-track-handler");
|
|
12
13
|
const error_cause_1 = __importDefault(require("./error-cause"));
|
|
13
|
-
const
|
|
14
|
-
const makeAudioTrackHandler = ({ state, audioCodec,
|
|
15
|
-
const audioOperation = await (onAudioTrack !== null && onAudioTrack !== void 0 ? onAudioTrack :
|
|
16
|
-
audioCodec,
|
|
14
|
+
const log_1 = require("./log");
|
|
15
|
+
const makeAudioTrackHandler = ({ state, defaultAudioCodec: audioCodec, controller, abortConversion, onMediaStateUpdate, onAudioTrack, logLevel, container, }) => async (track) => {
|
|
16
|
+
const audioOperation = await (onAudioTrack !== null && onAudioTrack !== void 0 ? onAudioTrack : default_on_audio_track_handler_1.defaultOnAudioTrackHandler)({
|
|
17
|
+
defaultAudioCodec: audioCodec,
|
|
17
18
|
track,
|
|
18
19
|
logLevel,
|
|
19
20
|
container,
|
|
@@ -21,18 +22,33 @@ const makeAudioTrackHandler = ({ state, audioCodec, convertMediaState, controlle
|
|
|
21
22
|
if (audioOperation.type === 'drop') {
|
|
22
23
|
return null;
|
|
23
24
|
}
|
|
25
|
+
if (audioOperation.type === 'fail') {
|
|
26
|
+
throw new error_cause_1.default(`Audio track with ID ${track.trackId} could resolved with {"type": "fail"}. This could mean that this audio track could neither be copied to the output container or re-encoded. You have the option to drop the track instead of failing it: https://remotion.dev/docs/webcodecs/track-transformation`);
|
|
27
|
+
}
|
|
24
28
|
if (audioOperation.type === 'copy') {
|
|
25
29
|
const addedTrack = await state.addTrack({
|
|
26
30
|
type: 'audio',
|
|
27
|
-
codec:
|
|
31
|
+
codec: track.codecWithoutConfig,
|
|
28
32
|
numberOfChannels: track.numberOfChannels,
|
|
29
33
|
sampleRate: track.sampleRate,
|
|
30
34
|
codecPrivate: track.codecPrivate,
|
|
35
|
+
timescale: track.timescale,
|
|
31
36
|
});
|
|
37
|
+
log_1.Log.verbose(logLevel, `Copying audio track ${track.trackId} as track ${addedTrack.trackNumber}. Timescale = ${track.timescale}, codec = ${track.codecWithoutConfig} (${track.codec}) `);
|
|
32
38
|
return async (audioSample) => {
|
|
33
|
-
await state.addSample(
|
|
34
|
-
|
|
35
|
-
|
|
39
|
+
await state.addSample({
|
|
40
|
+
chunk: audioSample,
|
|
41
|
+
trackNumber: addedTrack.trackNumber,
|
|
42
|
+
isVideo: false,
|
|
43
|
+
timescale: track.timescale,
|
|
44
|
+
codecPrivate: track.codecPrivate,
|
|
45
|
+
});
|
|
46
|
+
onMediaStateUpdate === null || onMediaStateUpdate === void 0 ? void 0 : onMediaStateUpdate((prevState) => {
|
|
47
|
+
return {
|
|
48
|
+
...prevState,
|
|
49
|
+
encodedAudioFrames: prevState.encodedAudioFrames + 1,
|
|
50
|
+
};
|
|
51
|
+
});
|
|
36
52
|
};
|
|
37
53
|
}
|
|
38
54
|
const audioEncoderConfig = await (0, audio_encoder_config_1.getAudioEncoderConfig)({
|
|
@@ -55,25 +71,44 @@ const makeAudioTrackHandler = ({ state, audioCodec, convertMediaState, controlle
|
|
|
55
71
|
abortConversion(new error_cause_1.default(`Could not configure audio decoder of track ${track.trackId}`));
|
|
56
72
|
return null;
|
|
57
73
|
}
|
|
74
|
+
const codecPrivate = audioOperation.audioCodec === 'aac' ? new Uint8Array([17, 144]) : null;
|
|
58
75
|
const { trackNumber } = await state.addTrack({
|
|
59
76
|
type: 'audio',
|
|
60
|
-
codec: audioCodec,
|
|
77
|
+
codec: audioOperation.audioCodec,
|
|
61
78
|
numberOfChannels: track.numberOfChannels,
|
|
62
79
|
sampleRate: track.sampleRate,
|
|
63
|
-
codecPrivate
|
|
80
|
+
codecPrivate,
|
|
81
|
+
timescale: track.timescale,
|
|
64
82
|
});
|
|
65
83
|
const audioEncoder = (0, audio_encoder_1.createAudioEncoder)({
|
|
84
|
+
// This is weird 😵💫
|
|
85
|
+
// Chrome completely ignores the sample rate and uses it's own
|
|
86
|
+
// We cannot determine it here because it depends on the system
|
|
87
|
+
// sample rate. Unhardcode then declare it later once we know.
|
|
88
|
+
onNewAudioSampleRate: (sampleRate) => {
|
|
89
|
+
state.updateTrackSampleRate({ sampleRate, trackNumber });
|
|
90
|
+
},
|
|
66
91
|
onChunk: async (chunk) => {
|
|
67
|
-
await state.addSample(
|
|
68
|
-
|
|
69
|
-
|
|
92
|
+
await state.addSample({
|
|
93
|
+
chunk: (0, convert_encoded_chunk_1.convertEncodedChunk)(chunk, trackNumber),
|
|
94
|
+
trackNumber,
|
|
95
|
+
isVideo: false,
|
|
96
|
+
timescale: track.timescale,
|
|
97
|
+
codecPrivate,
|
|
98
|
+
});
|
|
99
|
+
onMediaStateUpdate === null || onMediaStateUpdate === void 0 ? void 0 : onMediaStateUpdate((prevState) => {
|
|
100
|
+
return {
|
|
101
|
+
...prevState,
|
|
102
|
+
encodedAudioFrames: prevState.encodedAudioFrames + 1,
|
|
103
|
+
};
|
|
104
|
+
});
|
|
70
105
|
},
|
|
71
106
|
onError: (err) => {
|
|
72
107
|
abortConversion(new error_cause_1.default(`Audio encoder of ${track.trackId} failed (see .cause of this error)`, {
|
|
73
108
|
cause: err,
|
|
74
109
|
}));
|
|
75
110
|
},
|
|
76
|
-
codec: audioCodec,
|
|
111
|
+
codec: audioOperation.audioCodec,
|
|
77
112
|
signal: controller.signal,
|
|
78
113
|
config: audioEncoderConfig,
|
|
79
114
|
logLevel,
|
|
@@ -81,8 +116,12 @@ const makeAudioTrackHandler = ({ state, audioCodec, convertMediaState, controlle
|
|
|
81
116
|
const audioDecoder = (0, audio_decoder_1.createAudioDecoder)({
|
|
82
117
|
onFrame: async (frame) => {
|
|
83
118
|
await audioEncoder.encodeFrame(frame);
|
|
84
|
-
|
|
85
|
-
|
|
119
|
+
onMediaStateUpdate === null || onMediaStateUpdate === void 0 ? void 0 : onMediaStateUpdate((prevState) => {
|
|
120
|
+
return {
|
|
121
|
+
...prevState,
|
|
122
|
+
decodedAudioFrames: prevState.decodedAudioFrames + 1,
|
|
123
|
+
};
|
|
124
|
+
});
|
|
86
125
|
frame.close();
|
|
87
126
|
},
|
|
88
127
|
onError(error) {
|
package/dist/on-frame.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { VideoTrack } from '@remotion/media-parser';
|
|
2
|
-
import type {
|
|
2
|
+
import type { ConvertMediaVideoCodec } from './codec-id';
|
|
3
|
+
import type { ConvertMediaOnVideoFrame } from './convert-media';
|
|
3
4
|
import type { WebCodecsVideoEncoder } from './video-encoder';
|
|
4
|
-
export declare const onFrame: ({ frame, onVideoFrame, videoEncoder,
|
|
5
|
+
export declare const onFrame: ({ frame, onVideoFrame, videoEncoder, track, outputCodec, }: {
|
|
5
6
|
frame: VideoFrame;
|
|
6
7
|
onVideoFrame: ConvertMediaOnVideoFrame | null;
|
|
7
8
|
videoEncoder: WebCodecsVideoEncoder;
|
|
8
|
-
onMediaStateUpdate: ConvertMediaOnMediaStateUpdate | null;
|
|
9
9
|
track: VideoTrack;
|
|
10
|
-
|
|
10
|
+
outputCodec: ConvertMediaVideoCodec;
|
|
11
11
|
}) => Promise<void>;
|
package/dist/on-frame.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.onFrame = void 0;
|
|
4
|
-
const
|
|
4
|
+
const convert_to_correct_videoframe_1 = require("./convert-to-correct-videoframe");
|
|
5
|
+
const onFrame = async ({ frame, onVideoFrame, videoEncoder, track, outputCodec, }) => {
|
|
5
6
|
const newFrame = onVideoFrame ? await onVideoFrame({ frame, track }) : frame;
|
|
6
|
-
if (newFrame.codedHeight !== frame.
|
|
7
|
-
throw new Error(`Returned VideoFrame of track ${track.trackId} has different codedHeight (${newFrame.codedHeight}) than the input frame (${frame.
|
|
7
|
+
if (newFrame.codedHeight !== frame.displayHeight) {
|
|
8
|
+
throw new Error(`Returned VideoFrame of track ${track.trackId} has different codedHeight (${newFrame.codedHeight}) than the input frame displayHeight (${frame.displayHeight})`);
|
|
8
9
|
}
|
|
9
|
-
if (newFrame.codedWidth !== frame.
|
|
10
|
-
throw new Error(`Returned VideoFrame of track ${track.trackId} has different codedWidth (${newFrame.codedWidth}) than the input frame (${frame.
|
|
10
|
+
if (newFrame.codedWidth !== frame.displayWidth) {
|
|
11
|
+
throw new Error(`Returned VideoFrame of track ${track.trackId} has different codedWidth (${newFrame.codedWidth}) than the input frame displayWidth (${frame.displayWidth})`);
|
|
11
12
|
}
|
|
12
13
|
if (newFrame.displayWidth !== frame.displayWidth) {
|
|
13
14
|
throw new Error(`Returned VideoFrame of track ${track.trackId} has different displayWidth (${newFrame.displayWidth}) than the input frame (${newFrame.displayHeight})`);
|
|
@@ -21,12 +22,17 @@ const onFrame = async ({ frame, onVideoFrame, videoEncoder, onMediaStateUpdate,
|
|
|
21
22
|
if (newFrame.duration !== frame.duration) {
|
|
22
23
|
throw new Error(`Returned VideoFrame of track ${track.trackId} has different duration (${newFrame.duration}) than the input frame (${newFrame.duration}). When calling new VideoFrame(), pass {duration: frame.duration} as second argument`);
|
|
23
24
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
const fixedFrame = (0, convert_to_correct_videoframe_1.convertToCorrectVideoFrame)({
|
|
26
|
+
videoFrame: newFrame,
|
|
27
|
+
outputCodec,
|
|
28
|
+
});
|
|
29
|
+
await videoEncoder.encodeFrame(fixedFrame, fixedFrame.timestamp);
|
|
30
|
+
fixedFrame.close();
|
|
28
31
|
if (frame !== newFrame) {
|
|
29
32
|
frame.close();
|
|
30
33
|
}
|
|
34
|
+
if (fixedFrame !== newFrame) {
|
|
35
|
+
fixedFrame.close();
|
|
36
|
+
}
|
|
31
37
|
};
|
|
32
38
|
exports.onFrame = onFrame;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { LogLevel, VideoTrack } from '@remotion/media-parser';
|
|
2
|
-
import type { ConvertMediaVideoCodec } from './codec-id';
|
|
3
|
-
import type { ConvertMediaContainer } from './convert-media';
|
|
2
|
+
import type { ConvertMediaContainer, ConvertMediaVideoCodec } from './codec-id';
|
|
4
3
|
export type VideoOperation = {
|
|
5
4
|
type: 'reencode';
|
|
6
5
|
videoCodec: ConvertMediaVideoCodec;
|
|
@@ -8,11 +7,12 @@ export type VideoOperation = {
|
|
|
8
7
|
type: 'copy';
|
|
9
8
|
} | {
|
|
10
9
|
type: 'drop';
|
|
10
|
+
} | {
|
|
11
|
+
type: 'fail';
|
|
11
12
|
};
|
|
12
|
-
export type
|
|
13
|
-
|
|
13
|
+
export type ConvertMediaOnVideoTrackHandler = (options: {
|
|
14
|
+
defaultVideoCodec: ConvertMediaVideoCodec | null;
|
|
14
15
|
track: VideoTrack;
|
|
15
16
|
logLevel: LogLevel;
|
|
16
17
|
container: ConvertMediaContainer;
|
|
17
18
|
}) => VideoOperation | Promise<VideoOperation>;
|
|
18
|
-
export declare const defaultResolveVideoAction: ResolveVideoActionFn;
|
package/dist/on-video-track.d.ts
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import type { LogLevel, MediaFn, OnVideoTrack } from '@remotion/media-parser';
|
|
2
|
-
import type { ConvertMediaVideoCodec } from './codec-id';
|
|
3
|
-
import type {
|
|
2
|
+
import type { ConvertMediaContainer, ConvertMediaVideoCodec } from './codec-id';
|
|
3
|
+
import type { ConvertMediaOnVideoFrame } from './convert-media';
|
|
4
4
|
import Error from './error-cause';
|
|
5
|
-
import type {
|
|
6
|
-
|
|
5
|
+
import type { ConvertMediaOnVideoTrackHandler } from './on-video-track-handler';
|
|
6
|
+
import type { ConvertMediaProgressFn } from './throttled-state-update';
|
|
7
|
+
export declare const makeVideoTrackHandler: ({ state, onVideoFrame, onMediaStateUpdate, abortConversion, controller, defaultVideoCodec, onVideoTrack, logLevel, container, }: {
|
|
7
8
|
state: MediaFn;
|
|
8
9
|
onVideoFrame: null | ConvertMediaOnVideoFrame;
|
|
9
|
-
onMediaStateUpdate: null |
|
|
10
|
+
onMediaStateUpdate: null | ConvertMediaProgressFn;
|
|
10
11
|
abortConversion: (errCause: Error) => void;
|
|
11
|
-
convertMediaState: ConvertMediaState;
|
|
12
12
|
controller: AbortController;
|
|
13
|
-
|
|
14
|
-
onVideoTrack:
|
|
13
|
+
defaultVideoCodec: ConvertMediaVideoCodec | null;
|
|
14
|
+
onVideoTrack: ConvertMediaOnVideoTrackHandler | null;
|
|
15
15
|
logLevel: LogLevel;
|
|
16
16
|
container: ConvertMediaContainer;
|
|
17
17
|
}) => OnVideoTrack;
|
package/dist/on-video-track.js
CHANGED
|
@@ -4,28 +4,34 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.makeVideoTrackHandler = void 0;
|
|
7
|
+
const arraybuffer_to_uint8_array_1 = require("./arraybuffer-to-uint8-array");
|
|
7
8
|
const convert_encoded_chunk_1 = require("./convert-encoded-chunk");
|
|
9
|
+
const default_on_video_track_handler_1 = require("./default-on-video-track-handler");
|
|
8
10
|
const error_cause_1 = __importDefault(require("./error-cause"));
|
|
11
|
+
const log_1 = require("./log");
|
|
9
12
|
const on_frame_1 = require("./on-frame");
|
|
10
|
-
const resolve_video_action_1 = require("./resolve-video-action");
|
|
11
13
|
const video_decoder_1 = require("./video-decoder");
|
|
12
14
|
const video_decoder_config_1 = require("./video-decoder-config");
|
|
13
15
|
const video_encoder_1 = require("./video-encoder");
|
|
14
16
|
const video_encoder_config_1 = require("./video-encoder-config");
|
|
15
|
-
const makeVideoTrackHandler = ({ state, onVideoFrame, onMediaStateUpdate, abortConversion,
|
|
17
|
+
const makeVideoTrackHandler = ({ state, onVideoFrame, onMediaStateUpdate, abortConversion, controller, defaultVideoCodec, onVideoTrack, logLevel, container, }) => async (track) => {
|
|
16
18
|
if (controller.signal.aborted) {
|
|
17
19
|
throw new error_cause_1.default('Aborted');
|
|
18
20
|
}
|
|
19
|
-
const videoOperation = await (onVideoTrack !== null && onVideoTrack !== void 0 ? onVideoTrack :
|
|
21
|
+
const videoOperation = await (onVideoTrack !== null && onVideoTrack !== void 0 ? onVideoTrack : default_on_video_track_handler_1.defaultOnVideoTrackHandler)({
|
|
20
22
|
track,
|
|
21
|
-
|
|
23
|
+
defaultVideoCodec,
|
|
22
24
|
logLevel,
|
|
23
25
|
container,
|
|
24
26
|
});
|
|
25
27
|
if (videoOperation.type === 'drop') {
|
|
26
28
|
return null;
|
|
27
29
|
}
|
|
30
|
+
if (videoOperation.type === 'fail') {
|
|
31
|
+
throw new error_cause_1.default(`Video track with ID ${track.trackId} could resolved with {"type": "fail"}. This could mean that this video track could neither be copied to the output container or re-encoded. You have the option to drop the track instead of failing it: https://remotion.dev/docs/webcodecs/track-transformation`);
|
|
32
|
+
}
|
|
28
33
|
if (videoOperation.type === 'copy') {
|
|
34
|
+
log_1.Log.verbose(logLevel, `Copying video track with codec ${track.codec} and timescale ${track.timescale}`);
|
|
29
35
|
const videoTrack = await state.addTrack({
|
|
30
36
|
type: 'video',
|
|
31
37
|
color: track.color,
|
|
@@ -33,17 +39,29 @@ const makeVideoTrackHandler = ({ state, onVideoFrame, onMediaStateUpdate, abortC
|
|
|
33
39
|
height: track.codedHeight,
|
|
34
40
|
codec: track.codecWithoutConfig,
|
|
35
41
|
codecPrivate: track.codecPrivate,
|
|
42
|
+
timescale: track.timescale,
|
|
36
43
|
});
|
|
37
44
|
return async (sample) => {
|
|
38
|
-
await state.addSample(
|
|
39
|
-
|
|
40
|
-
|
|
45
|
+
await state.addSample({
|
|
46
|
+
chunk: sample,
|
|
47
|
+
trackNumber: videoTrack.trackNumber,
|
|
48
|
+
isVideo: true,
|
|
49
|
+
timescale: track.timescale,
|
|
50
|
+
codecPrivate: track.codecPrivate,
|
|
51
|
+
});
|
|
52
|
+
onMediaStateUpdate === null || onMediaStateUpdate === void 0 ? void 0 : onMediaStateUpdate((prevState) => {
|
|
53
|
+
return {
|
|
54
|
+
...prevState,
|
|
55
|
+
decodedVideoFrames: prevState.decodedVideoFrames + 1,
|
|
56
|
+
};
|
|
57
|
+
});
|
|
41
58
|
};
|
|
42
59
|
}
|
|
43
60
|
const videoEncoderConfig = await (0, video_encoder_config_1.getVideoEncoderConfig)({
|
|
44
61
|
codec: videoOperation.videoCodec,
|
|
45
62
|
height: track.displayAspectHeight,
|
|
46
63
|
width: track.displayAspectWidth,
|
|
64
|
+
fps: track.fps,
|
|
47
65
|
});
|
|
48
66
|
const videoDecoderConfig = await (0, video_decoder_config_1.getVideoDecoderConfigWithHardwareAcceleration)(track);
|
|
49
67
|
if (videoEncoderConfig === null) {
|
|
@@ -59,14 +77,27 @@ const makeVideoTrackHandler = ({ state, onVideoFrame, onMediaStateUpdate, abortC
|
|
|
59
77
|
color: track.color,
|
|
60
78
|
width: track.codedWidth,
|
|
61
79
|
height: track.codedHeight,
|
|
62
|
-
codec: videoCodec,
|
|
80
|
+
codec: videoOperation.videoCodec,
|
|
63
81
|
codecPrivate: null,
|
|
82
|
+
timescale: track.timescale,
|
|
64
83
|
});
|
|
84
|
+
log_1.Log.verbose(logLevel, `Created new video track with ID ${trackNumber}, codec ${videoOperation.videoCodec} and timescale ${track.timescale}`);
|
|
65
85
|
const videoEncoder = (0, video_encoder_1.createVideoEncoder)({
|
|
66
|
-
onChunk: async (chunk) => {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
86
|
+
onChunk: async (chunk, metadata) => {
|
|
87
|
+
var _a, _b;
|
|
88
|
+
await state.addSample({
|
|
89
|
+
chunk: (0, convert_encoded_chunk_1.convertEncodedChunk)(chunk, trackNumber),
|
|
90
|
+
trackNumber,
|
|
91
|
+
isVideo: true,
|
|
92
|
+
timescale: track.timescale,
|
|
93
|
+
codecPrivate: (0, arraybuffer_to_uint8_array_1.arrayBufferToUint8Array)(((_b = (_a = metadata === null || metadata === void 0 ? void 0 : metadata.decoderConfig) === null || _a === void 0 ? void 0 : _a.description) !== null && _b !== void 0 ? _b : null)),
|
|
94
|
+
});
|
|
95
|
+
onMediaStateUpdate === null || onMediaStateUpdate === void 0 ? void 0 : onMediaStateUpdate((prevState) => {
|
|
96
|
+
return {
|
|
97
|
+
...prevState,
|
|
98
|
+
encodedVideoFrames: prevState.encodedVideoFrames + 1,
|
|
99
|
+
};
|
|
100
|
+
});
|
|
70
101
|
},
|
|
71
102
|
onError: (err) => {
|
|
72
103
|
abortConversion(new error_cause_1.default(`Video encoder of track ${track.trackId} failed (see .cause of this error)`, {
|
|
@@ -76,17 +107,17 @@ const makeVideoTrackHandler = ({ state, onVideoFrame, onMediaStateUpdate, abortC
|
|
|
76
107
|
signal: controller.signal,
|
|
77
108
|
config: videoEncoderConfig,
|
|
78
109
|
logLevel,
|
|
110
|
+
outputCodec: videoOperation.videoCodec,
|
|
79
111
|
});
|
|
80
112
|
const videoDecoder = (0, video_decoder_1.createVideoDecoder)({
|
|
81
113
|
config: videoDecoderConfig,
|
|
82
114
|
onFrame: async (frame) => {
|
|
83
115
|
await (0, on_frame_1.onFrame)({
|
|
84
|
-
convertMediaState,
|
|
85
116
|
frame,
|
|
86
|
-
onMediaStateUpdate,
|
|
87
117
|
track,
|
|
88
118
|
videoEncoder,
|
|
89
119
|
onVideoFrame,
|
|
120
|
+
outputCodec: videoOperation.videoCodec,
|
|
90
121
|
});
|
|
91
122
|
},
|
|
92
123
|
onError: (err) => {
|
|
@@ -98,10 +129,13 @@ const makeVideoTrackHandler = ({ state, onVideoFrame, onMediaStateUpdate, abortC
|
|
|
98
129
|
logLevel,
|
|
99
130
|
});
|
|
100
131
|
state.addWaitForFinishPromise(async () => {
|
|
132
|
+
log_1.Log.verbose(logLevel, 'Waiting for video decoder to finish');
|
|
101
133
|
await videoDecoder.waitForFinish();
|
|
102
|
-
await videoEncoder.waitForFinish();
|
|
103
134
|
videoDecoder.close();
|
|
135
|
+
log_1.Log.verbose(logLevel, 'Video decoder finished. Waiting for encoder to finish');
|
|
136
|
+
await videoEncoder.waitForFinish();
|
|
104
137
|
videoEncoder.close();
|
|
138
|
+
log_1.Log.verbose(logLevel, 'Encoder finished');
|
|
105
139
|
});
|
|
106
140
|
return async (chunk) => {
|
|
107
141
|
await videoDecoder.processSample(chunk);
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.setRemotionImported = void 0;
|
|
4
|
+
const media_parser_1 = require("@remotion/media-parser");
|
|
5
|
+
// We set the `window.remotion_imported` variable for the sole purpose
|
|
6
|
+
// of being picked up by Wappalyzer.
|
|
7
|
+
// The Wappalyzer Chrome extension is used to detect the technologies
|
|
8
|
+
// used on websites, and it looks for this variable.
|
|
9
|
+
// Remotion is a customer of Wappalyzer and buys a list of domains
|
|
10
|
+
// where Remotion is used from time to time.
|
|
11
|
+
// Remotion uses this data to ensure companies which are required to get
|
|
12
|
+
// a company license for this pacakge are actually doing so.
|
|
13
|
+
const setRemotionImported = () => {
|
|
14
|
+
if (typeof globalThis === 'undefined') {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
if (globalThis.remotion_imported) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
globalThis.remotion_imported = media_parser_1.VERSION;
|
|
21
|
+
if (typeof window !== 'undefined') {
|
|
22
|
+
window.remotion_imported = `${media_parser_1.VERSION}-webcodecs`;
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
exports.setRemotionImported = setRemotionImported;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ConvertMediaOnProgress, ConvertMediaProgress } from './convert-media';
|
|
2
|
+
export type ConvertMediaProgressFn = (state: (prevState: ConvertMediaProgress) => ConvertMediaProgress) => void;
|
|
3
|
+
type ReturnType = {
|
|
4
|
+
get: () => ConvertMediaProgress;
|
|
5
|
+
update: ConvertMediaProgressFn | null;
|
|
6
|
+
stopAndGetLastProgress: () => void;
|
|
7
|
+
};
|
|
8
|
+
export declare const throttledStateUpdate: ({ updateFn, everyMilliseconds, signal, }: {
|
|
9
|
+
updateFn: ConvertMediaOnProgress | null;
|
|
10
|
+
everyMilliseconds: number;
|
|
11
|
+
signal: AbortSignal;
|
|
12
|
+
}) => ReturnType;
|
|
13
|
+
export {};
|