@remotion/webcodecs 4.0.227 → 4.0.229

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 (61) hide show
  1. package/dist/audio-decoder-config.js +3 -0
  2. package/dist/audio-decoder.d.ts +3 -3
  3. package/dist/audio-decoder.js +23 -29
  4. package/dist/audio-encoder.d.ts +3 -2
  5. package/dist/audio-encoder.js +17 -29
  6. package/dist/auto-select-writer.d.ts +3 -0
  7. package/dist/auto-select-writer.js +20 -0
  8. package/dist/calculate-progress.d.ts +4 -0
  9. package/dist/calculate-progress.js +10 -0
  10. package/dist/can-copy-audio-track.d.ts +8 -0
  11. package/dist/can-copy-audio-track.js +10 -0
  12. package/dist/can-copy-video-track.d.ts +8 -0
  13. package/dist/can-copy-video-track.js +13 -0
  14. package/dist/can-reencode-audio-track.d.ts +7 -0
  15. package/dist/can-reencode-audio-track.js +21 -0
  16. package/dist/can-reencode-audio.d.ts +7 -0
  17. package/dist/can-reencode-audio.js +21 -0
  18. package/dist/can-reencode-video-track.d.ts +6 -0
  19. package/dist/can-reencode-video-track.js +15 -0
  20. package/dist/can-reencode-video.d.ts +6 -0
  21. package/dist/can-reencode-video.js +15 -0
  22. package/dist/codec-id.d.ts +7 -2
  23. package/dist/codec-id.js +7 -0
  24. package/dist/convert-encoded-chunk.d.ts +2 -0
  25. package/dist/convert-encoded-chunk.js +15 -0
  26. package/dist/convert-media.d.ts +25 -9
  27. package/dist/convert-media.js +69 -15
  28. package/dist/esm/index.mjs +602 -297
  29. package/dist/event-emitter.d.ts +25 -0
  30. package/dist/event-emitter.js +23 -0
  31. package/dist/index.d.ts +8 -1
  32. package/dist/index.js +12 -1
  33. package/dist/io-manager/event-emitter.d.ts +27 -0
  34. package/dist/io-manager/event-emitter.js +24 -0
  35. package/dist/io-manager/io-synchronizer.d.ts +12 -0
  36. package/dist/io-manager/io-synchronizer.js +95 -0
  37. package/dist/log.d.ts +10 -0
  38. package/dist/log.js +6 -0
  39. package/dist/on-audio-track.d.ts +6 -5
  40. package/dist/on-audio-track.js +23 -21
  41. package/dist/on-frame.d.ts +11 -0
  42. package/dist/on-frame.js +32 -0
  43. package/dist/on-video-track.d.ts +8 -6
  44. package/dist/on-video-track.js +30 -21
  45. package/dist/polyfill-encoded-audio-chunk.d.ts +3 -0
  46. package/dist/polyfill-encoded-audio-chunk.js +5 -0
  47. package/dist/resolve-audio-action.d.ts +15 -11
  48. package/dist/resolve-audio-action.js +23 -21
  49. package/dist/resolve-video-action.d.ts +14 -11
  50. package/dist/resolve-video-action.js +17 -24
  51. package/dist/video-decoder.d.ts +3 -3
  52. package/dist/video-decoder.js +23 -28
  53. package/dist/video-encoder-config.d.ts +6 -1
  54. package/dist/video-encoder-config.js +6 -1
  55. package/dist/video-encoder.d.ts +4 -3
  56. package/dist/video-encoder.js +26 -29
  57. package/dist/wait-until-return.d.ts +4 -0
  58. package/dist/wait-until-return.js +14 -0
  59. package/dist/with-resolvers.d.ts +5 -0
  60. package/dist/with-resolvers.js +16 -1
  61. package/package.json +4 -4
@@ -0,0 +1,25 @@
1
+ type Input = {
2
+ timestamp: number;
3
+ keyframe: boolean;
4
+ };
5
+ type Output = {
6
+ timestamp: number;
7
+ };
8
+ type IoEventMap = {
9
+ input: Input;
10
+ output: Output;
11
+ };
12
+ export type IoEventTypes = keyof IoEventMap;
13
+ export type CallbackListener<T extends IoEventTypes> = (data: {
14
+ detail: IoEventMap[T];
15
+ }) => void;
16
+ type IoListeners = {
17
+ [EventType in IoEventTypes]: CallbackListener<EventType>[];
18
+ };
19
+ export declare class IoEventEmitter {
20
+ listeners: IoListeners;
21
+ addEventListener<Q extends IoEventTypes>(name: Q, callback: CallbackListener<Q>): void;
22
+ removeEventListener<Q extends IoEventTypes>(name: Q, callback: CallbackListener<Q>): void;
23
+ dispatchEvent<T extends IoEventTypes>(dispatchName: T, context: IoEventMap[T]): void;
24
+ }
25
+ export {};
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.IoEventEmitter = void 0;
4
+ class IoEventEmitter {
5
+ constructor() {
6
+ this.listeners = {
7
+ input: [],
8
+ output: [],
9
+ };
10
+ }
11
+ addEventListener(name, callback) {
12
+ this.listeners[name].push(callback);
13
+ }
14
+ removeEventListener(name, callback) {
15
+ this.listeners[name] = this.listeners[name].filter((l) => l !== callback);
16
+ }
17
+ dispatchEvent(dispatchName, context) {
18
+ this.listeners[dispatchName].forEach((callback) => {
19
+ callback({ detail: context });
20
+ });
21
+ }
22
+ }
23
+ exports.IoEventEmitter = IoEventEmitter;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,12 @@
1
1
  export { WebCodecsAudioDecoder, createAudioDecoder } from './audio-decoder';
2
2
  export { WebCodecsAudioEncoder, createAudioEncoder } from './audio-encoder';
3
- export { ConvertMediaState, ConvertMediaTo, convertMedia } from './convert-media';
3
+ export { canCopyAudioTrack } from './can-copy-audio-track';
4
+ export { canCopyVideoTrack } from './can-copy-video-track';
5
+ export { canReencodeAudioTrack } from './can-reencode-audio-track';
6
+ export { canReencodeVideoTrack } from './can-reencode-video-track';
7
+ export { ConvertMediaAudioCodec, ConvertMediaVideoCodec, getAvailableAudioCodecs, getAvailableVideoCodecs, } from './codec-id';
8
+ export { ConvertMediaContainer, ConvertMediaOnMediaStateUpdate, ConvertMediaOnVideoFrame, ConvertMediaResult, ConvertMediaState, convertMedia, } from './convert-media';
9
+ export { AudioOperation, ResolveAudioActionFn } from './resolve-audio-action';
10
+ export { ResolveVideoActionFn, VideoOperation } from './resolve-video-action';
4
11
  export { WebCodecsVideoDecoder, createVideoDecoder } from './video-decoder';
5
12
  export { WebCodecsVideoEncoder, createVideoEncoder } from './video-encoder';
package/dist/index.js CHANGED
@@ -1,10 +1,21 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createVideoEncoder = exports.createVideoDecoder = exports.convertMedia = exports.createAudioEncoder = exports.createAudioDecoder = void 0;
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;
4
4
  var audio_decoder_1 = require("./audio-decoder");
5
5
  Object.defineProperty(exports, "createAudioDecoder", { enumerable: true, get: function () { return audio_decoder_1.createAudioDecoder; } });
6
6
  var audio_encoder_1 = require("./audio-encoder");
7
7
  Object.defineProperty(exports, "createAudioEncoder", { enumerable: true, get: function () { return audio_encoder_1.createAudioEncoder; } });
8
+ var can_copy_audio_track_1 = require("./can-copy-audio-track");
9
+ Object.defineProperty(exports, "canCopyAudioTrack", { enumerable: true, get: function () { return can_copy_audio_track_1.canCopyAudioTrack; } });
10
+ var can_copy_video_track_1 = require("./can-copy-video-track");
11
+ Object.defineProperty(exports, "canCopyVideoTrack", { enumerable: true, get: function () { return can_copy_video_track_1.canCopyVideoTrack; } });
12
+ var can_reencode_audio_track_1 = require("./can-reencode-audio-track");
13
+ Object.defineProperty(exports, "canReencodeAudioTrack", { enumerable: true, get: function () { return can_reencode_audio_track_1.canReencodeAudioTrack; } });
14
+ var can_reencode_video_track_1 = require("./can-reencode-video-track");
15
+ Object.defineProperty(exports, "canReencodeVideoTrack", { enumerable: true, get: function () { return can_reencode_video_track_1.canReencodeVideoTrack; } });
16
+ var codec_id_1 = require("./codec-id");
17
+ Object.defineProperty(exports, "getAvailableAudioCodecs", { enumerable: true, get: function () { return codec_id_1.getAvailableAudioCodecs; } });
18
+ Object.defineProperty(exports, "getAvailableVideoCodecs", { enumerable: true, get: function () { return codec_id_1.getAvailableVideoCodecs; } });
8
19
  var convert_media_1 = require("./convert-media");
9
20
  Object.defineProperty(exports, "convertMedia", { enumerable: true, get: function () { return convert_media_1.convertMedia; } });
10
21
  var video_decoder_1 = require("./video-decoder");
@@ -0,0 +1,27 @@
1
+ type Input = {
2
+ timestamp: number;
3
+ keyFrame: boolean;
4
+ };
5
+ type Output = {
6
+ timestamp: number;
7
+ };
8
+ type Processed = {};
9
+ type IoEventMap = {
10
+ input: Input;
11
+ output: Output;
12
+ processed: Processed;
13
+ };
14
+ export type IoEventTypes = keyof IoEventMap;
15
+ export type CallbackListener<T extends IoEventTypes> = (data: {
16
+ detail: IoEventMap[T];
17
+ }) => void;
18
+ type IoListeners = {
19
+ [EventType in IoEventTypes]: CallbackListener<EventType>[];
20
+ };
21
+ export declare class IoEventEmitter {
22
+ listeners: IoListeners;
23
+ addEventListener<Q extends IoEventTypes>(name: Q, callback: CallbackListener<Q>): void;
24
+ removeEventListener<Q extends IoEventTypes>(name: Q, callback: CallbackListener<Q>): void;
25
+ dispatchEvent<T extends IoEventTypes>(dispatchName: T, context: IoEventMap[T]): void;
26
+ }
27
+ export {};
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.IoEventEmitter = void 0;
4
+ class IoEventEmitter {
5
+ constructor() {
6
+ this.listeners = {
7
+ input: [],
8
+ output: [],
9
+ processed: [],
10
+ };
11
+ }
12
+ addEventListener(name, callback) {
13
+ this.listeners[name].push(callback);
14
+ }
15
+ removeEventListener(name, callback) {
16
+ this.listeners[name] = this.listeners[name].filter((l) => l !== callback);
17
+ }
18
+ dispatchEvent(dispatchName, context) {
19
+ this.listeners[dispatchName].forEach((callback) => {
20
+ callback({ detail: context });
21
+ });
22
+ }
23
+ }
24
+ exports.IoEventEmitter = IoEventEmitter;
@@ -0,0 +1,12 @@
1
+ import type { LogLevel } from '../log';
2
+ export declare const makeIoSynchronizer: (logLevel: LogLevel, label: string) => {
3
+ inputItem: (timestamp: number, keyFrame: boolean) => void;
4
+ onOutput: (timestamp: number) => void;
5
+ waitFor: ({ _unprocessed, unemitted, }: {
6
+ unemitted: number;
7
+ _unprocessed: number;
8
+ }) => Promise<void>;
9
+ waitForFinish: () => Promise<void>;
10
+ onProcessed: () => void;
11
+ getUnprocessed: () => number;
12
+ };
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.makeIoSynchronizer = void 0;
4
+ const log_1 = require("../log");
5
+ const with_resolvers_1 = require("../with-resolvers");
6
+ const event_emitter_1 = require("./event-emitter");
7
+ const makeIoSynchronizer = (logLevel, label) => {
8
+ const eventEmitter = new event_emitter_1.IoEventEmitter();
9
+ let lastInput = 0;
10
+ let lastInputKeyframe = 0;
11
+ let lastOutput = 0;
12
+ let inputsSinceLastOutput = 0;
13
+ let inputs = [];
14
+ let keyframes = [];
15
+ // Once WebCodecs emits items, the user has to handle them
16
+ // Let's keep count of how many items are unprocessed
17
+ let unprocessed = 0;
18
+ const getUnprocessed = () => unprocessed;
19
+ const getUnemittedItems = () => {
20
+ inputs = inputs.filter((input) => input > lastOutput);
21
+ return inputs.length;
22
+ };
23
+ const getUnemittedKeyframes = () => {
24
+ keyframes = keyframes.filter((keyframe) => keyframe > lastOutput);
25
+ return keyframes.length;
26
+ };
27
+ const printState = (prefix) => {
28
+ log_1.Log.trace(logLevel, `[${label}] ${prefix}, state: Last input = ${lastInput} Last input keyframe = ${lastInputKeyframe} Last output = ${lastOutput} Inputs since last output = ${inputsSinceLastOutput}, Queue = ${getUnemittedItems()} (${getUnemittedKeyframes()} keyframes), Unprocessed = ${getUnprocessed()}`);
29
+ };
30
+ const inputItem = (timestamp, keyFrame) => {
31
+ lastInput = timestamp;
32
+ if (keyFrame) {
33
+ lastInputKeyframe = timestamp;
34
+ keyframes.push(timestamp);
35
+ }
36
+ inputsSinceLastOutput++;
37
+ inputs.push(timestamp);
38
+ eventEmitter.dispatchEvent('input', {
39
+ timestamp,
40
+ keyFrame,
41
+ });
42
+ printState('Input item');
43
+ };
44
+ const onOutput = (timestamp) => {
45
+ lastOutput = timestamp;
46
+ inputsSinceLastOutput = 0;
47
+ eventEmitter.dispatchEvent('output', {
48
+ timestamp,
49
+ });
50
+ unprocessed++;
51
+ printState('Got output');
52
+ };
53
+ const waitForOutput = () => {
54
+ const { promise, resolve } = (0, with_resolvers_1.withResolvers)();
55
+ const on = () => {
56
+ eventEmitter.removeEventListener('output', on);
57
+ resolve();
58
+ };
59
+ eventEmitter.addEventListener('output', on);
60
+ return promise;
61
+ };
62
+ const waitForProcessed = () => {
63
+ const { promise, resolve } = (0, with_resolvers_1.withResolvers)();
64
+ const on = () => {
65
+ eventEmitter.removeEventListener('processed', on);
66
+ resolve();
67
+ };
68
+ eventEmitter.addEventListener('processed', on);
69
+ return promise;
70
+ };
71
+ const waitFor = async ({ _unprocessed, unemitted, }) => {
72
+ while (getUnemittedItems() > unemitted) {
73
+ await waitForOutput();
74
+ }
75
+ while (getUnprocessed() > _unprocessed) {
76
+ await waitForProcessed();
77
+ }
78
+ };
79
+ const waitForFinish = async () => {
80
+ await waitFor({ _unprocessed: 0, unemitted: 0 });
81
+ };
82
+ const onProcessed = () => {
83
+ eventEmitter.dispatchEvent('processed', {});
84
+ unprocessed--;
85
+ };
86
+ return {
87
+ inputItem,
88
+ onOutput,
89
+ waitFor,
90
+ waitForFinish,
91
+ onProcessed,
92
+ getUnprocessed,
93
+ };
94
+ };
95
+ exports.makeIoSynchronizer = makeIoSynchronizer;
package/dist/log.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ import type { LogLevel } from '@remotion/media-parser';
2
+ declare const Log: {
3
+ trace: (logLevel: LogLevel, ...args: Parameters<typeof console.log>) => void;
4
+ verbose: (logLevel: LogLevel, ...args: Parameters<typeof console.log>) => void;
5
+ info: (logLevel: LogLevel, ...args: Parameters<typeof console.log>) => void;
6
+ warn: (logLevel: LogLevel, ...args: Parameters<typeof console.log>) => void;
7
+ error: (...args: Parameters<typeof console.log>) => void;
8
+ };
9
+ export { Log };
10
+ export type { LogLevel };
package/dist/log.js ADDED
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Log = void 0;
4
+ const media_parser_1 = require("@remotion/media-parser");
5
+ const { Log } = media_parser_1.MediaParserInternals;
6
+ exports.Log = Log;
@@ -1,15 +1,16 @@
1
- import type { MediaFn, OnAudioTrack } from '@remotion/media-parser';
1
+ import type { LogLevel, MediaFn, OnAudioTrack } from '@remotion/media-parser';
2
2
  import type { ConvertMediaAudioCodec } from './codec-id';
3
- import type { ConvertMediaState } from './convert-media';
3
+ import type { ConvertMediaContainer, ConvertMediaState } from './convert-media';
4
4
  import Error from './error-cause';
5
5
  import type { ResolveAudioActionFn } from './resolve-audio-action';
6
- export declare const makeAudioTrackHandler: ({ state, audioCodec, convertMediaState, controller, abortConversion, onMediaStateUpdate, onAudioTrack, bitrate, }: {
6
+ export declare const makeAudioTrackHandler: ({ state, audioCodec, convertMediaState, controller, abortConversion, onMediaStateUpdate, onAudioTrack, logLevel, container, }: {
7
7
  state: MediaFn;
8
8
  audioCodec: ConvertMediaAudioCodec;
9
9
  convertMediaState: ConvertMediaState;
10
10
  controller: AbortController;
11
11
  abortConversion: (errCause: Error) => void;
12
12
  onMediaStateUpdate: null | ((state: ConvertMediaState) => void);
13
- onAudioTrack: ResolveAudioActionFn;
14
- bitrate: number;
13
+ onAudioTrack: ResolveAudioActionFn | null;
14
+ logLevel: LogLevel;
15
+ container: ConvertMediaContainer;
15
16
  }) => OnAudioTrack;
@@ -8,32 +8,20 @@ const audio_decoder_1 = require("./audio-decoder");
8
8
  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
+ const convert_encoded_chunk_1 = require("./convert-encoded-chunk");
11
12
  const error_cause_1 = __importDefault(require("./error-cause"));
12
13
  const resolve_audio_action_1 = require("./resolve-audio-action");
13
- const makeAudioTrackHandler = ({ state, audioCodec, convertMediaState, controller, abortConversion, onMediaStateUpdate, onAudioTrack, bitrate, }) => async (track) => {
14
- const audioEncoderConfig = await (0, audio_encoder_config_1.getAudioEncoderConfig)({
15
- codec: audioCodec,
16
- numberOfChannels: track.numberOfChannels,
17
- sampleRate: track.sampleRate,
18
- bitrate,
19
- });
20
- const audioDecoderConfig = await (0, audio_decoder_config_1.getAudioDecoderConfig)({
21
- codec: track.codec,
22
- numberOfChannels: track.numberOfChannels,
23
- sampleRate: track.sampleRate,
24
- description: track.description,
25
- });
26
- const audioOperation = await (0, resolve_audio_action_1.resolveAudioAction)({
27
- audioDecoderConfig,
28
- audioEncoderConfig,
14
+ const makeAudioTrackHandler = ({ state, audioCodec, convertMediaState, controller, abortConversion, onMediaStateUpdate, onAudioTrack, logLevel, container, }) => async (track) => {
15
+ const audioOperation = await (onAudioTrack !== null && onAudioTrack !== void 0 ? onAudioTrack : resolve_audio_action_1.defaultResolveAudioAction)({
29
16
  audioCodec,
30
17
  track,
31
- resolverFunction: onAudioTrack,
18
+ logLevel,
19
+ container,
32
20
  });
33
- if (audioOperation === 'drop') {
21
+ if (audioOperation.type === 'drop') {
34
22
  return null;
35
23
  }
36
- if (audioOperation === 'copy') {
24
+ if (audioOperation.type === 'copy') {
37
25
  const addedTrack = await state.addTrack({
38
26
  type: 'audio',
39
27
  codec: audioCodec,
@@ -42,11 +30,23 @@ const makeAudioTrackHandler = ({ state, audioCodec, convertMediaState, controlle
42
30
  codecPrivate: track.codecPrivate,
43
31
  });
44
32
  return async (audioSample) => {
45
- await state.addSample(new EncodedAudioChunk(audioSample), addedTrack.trackNumber, false);
33
+ await state.addSample(audioSample, addedTrack.trackNumber, false);
46
34
  convertMediaState.encodedAudioFrames++;
47
35
  onMediaStateUpdate === null || onMediaStateUpdate === void 0 ? void 0 : onMediaStateUpdate({ ...convertMediaState });
48
36
  };
49
37
  }
38
+ const audioEncoderConfig = await (0, audio_encoder_config_1.getAudioEncoderConfig)({
39
+ numberOfChannels: track.numberOfChannels,
40
+ sampleRate: track.sampleRate,
41
+ codec: audioOperation.audioCodec,
42
+ bitrate: audioOperation.bitrate,
43
+ });
44
+ const audioDecoderConfig = await (0, audio_decoder_config_1.getAudioDecoderConfig)({
45
+ codec: track.codec,
46
+ numberOfChannels: track.numberOfChannels,
47
+ sampleRate: track.sampleRate,
48
+ description: track.description,
49
+ });
50
50
  if (!audioEncoderConfig) {
51
51
  abortConversion(new error_cause_1.default(`Could not configure audio encoder of track ${track.trackId}`));
52
52
  return null;
@@ -64,7 +64,7 @@ const makeAudioTrackHandler = ({ state, audioCodec, convertMediaState, controlle
64
64
  });
65
65
  const audioEncoder = (0, audio_encoder_1.createAudioEncoder)({
66
66
  onChunk: async (chunk) => {
67
- await state.addSample(chunk, trackNumber, false);
67
+ await state.addSample((0, convert_encoded_chunk_1.convertEncodedChunk)(chunk), trackNumber, false);
68
68
  convertMediaState.encodedAudioFrames++;
69
69
  onMediaStateUpdate === null || onMediaStateUpdate === void 0 ? void 0 : onMediaStateUpdate({ ...convertMediaState });
70
70
  },
@@ -76,6 +76,7 @@ const makeAudioTrackHandler = ({ state, audioCodec, convertMediaState, controlle
76
76
  codec: audioCodec,
77
77
  signal: controller.signal,
78
78
  config: audioEncoderConfig,
79
+ logLevel,
79
80
  });
80
81
  const audioDecoder = (0, audio_decoder_1.createAudioDecoder)({
81
82
  onFrame: async (frame) => {
@@ -91,6 +92,7 @@ const makeAudioTrackHandler = ({ state, audioCodec, convertMediaState, controlle
91
92
  },
92
93
  signal: controller.signal,
93
94
  config: audioDecoderConfig,
95
+ logLevel,
94
96
  });
95
97
  state.addWaitForFinishPromise(async () => {
96
98
  await audioDecoder.waitForFinish();
@@ -0,0 +1,11 @@
1
+ import type { VideoTrack } from '@remotion/media-parser';
2
+ import type { ConvertMediaOnMediaStateUpdate, ConvertMediaOnVideoFrame, ConvertMediaState } from './convert-media';
3
+ import type { WebCodecsVideoEncoder } from './video-encoder';
4
+ export declare const onFrame: ({ frame, onVideoFrame, videoEncoder, onMediaStateUpdate, track, convertMediaState, }: {
5
+ frame: VideoFrame;
6
+ onVideoFrame: ConvertMediaOnVideoFrame | null;
7
+ videoEncoder: WebCodecsVideoEncoder;
8
+ onMediaStateUpdate: ConvertMediaOnMediaStateUpdate | null;
9
+ track: VideoTrack;
10
+ convertMediaState: ConvertMediaState;
11
+ }) => Promise<void>;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.onFrame = void 0;
4
+ const onFrame = async ({ frame, onVideoFrame, videoEncoder, onMediaStateUpdate, track, convertMediaState, }) => {
5
+ const newFrame = onVideoFrame ? await onVideoFrame({ frame, track }) : frame;
6
+ if (newFrame.codedHeight !== frame.codedHeight) {
7
+ throw new Error(`Returned VideoFrame of track ${track.trackId} has different codedHeight (${newFrame.codedHeight}) than the input frame (${frame.codedHeight})`);
8
+ }
9
+ if (newFrame.codedWidth !== frame.codedWidth) {
10
+ throw new Error(`Returned VideoFrame of track ${track.trackId} has different codedWidth (${newFrame.codedWidth}) than the input frame (${frame.codedWidth})`);
11
+ }
12
+ if (newFrame.displayWidth !== frame.displayWidth) {
13
+ throw new Error(`Returned VideoFrame of track ${track.trackId} has different displayWidth (${newFrame.displayWidth}) than the input frame (${newFrame.displayHeight})`);
14
+ }
15
+ if (newFrame.displayHeight !== frame.displayHeight) {
16
+ throw new Error(`Returned VideoFrame of track ${track.trackId} has different displayHeight (${newFrame.displayHeight}) than the input frame (${newFrame.displayHeight})`);
17
+ }
18
+ if (newFrame.timestamp !== frame.timestamp) {
19
+ throw new Error(`Returned VideoFrame of track ${track.trackId} has different timestamp (${newFrame.timestamp}) than the input frame (${newFrame.timestamp}). When calling new VideoFrame(), pass {timestamp: frame.timestamp} as second argument`);
20
+ }
21
+ if (newFrame.duration !== frame.duration) {
22
+ 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
+ await videoEncoder.encodeFrame(newFrame, newFrame.timestamp);
25
+ convertMediaState.decodedVideoFrames++;
26
+ onMediaStateUpdate === null || onMediaStateUpdate === void 0 ? void 0 : onMediaStateUpdate({ ...convertMediaState });
27
+ newFrame.close();
28
+ if (frame !== newFrame) {
29
+ frame.close();
30
+ }
31
+ };
32
+ exports.onFrame = onFrame;
@@ -1,15 +1,17 @@
1
- import type { MediaFn, OnVideoTrack, VideoTrack } from '@remotion/media-parser';
1
+ import type { LogLevel, MediaFn, OnVideoTrack } from '@remotion/media-parser';
2
2
  import type { ConvertMediaVideoCodec } from './codec-id';
3
- import type { ConvertMediaState } from './convert-media';
3
+ import type { ConvertMediaContainer, ConvertMediaOnMediaStateUpdate, ConvertMediaOnVideoFrame, ConvertMediaState } from './convert-media';
4
4
  import Error from './error-cause';
5
5
  import type { ResolveVideoActionFn } from './resolve-video-action';
6
- export declare const makeVideoTrackHandler: ({ state, onVideoFrame, onMediaStateUpdate, abortConversion, convertMediaState, controller, videoCodec, onVideoTrack, }: {
6
+ export declare const makeVideoTrackHandler: ({ state, onVideoFrame, onMediaStateUpdate, abortConversion, convertMediaState, controller, videoCodec, onVideoTrack, logLevel, container, }: {
7
7
  state: MediaFn;
8
- onVideoFrame: null | ((frame: VideoFrame, track: VideoTrack) => Promise<void>);
9
- onMediaStateUpdate: null | ((state: ConvertMediaState) => void);
8
+ onVideoFrame: null | ConvertMediaOnVideoFrame;
9
+ onMediaStateUpdate: null | ConvertMediaOnMediaStateUpdate;
10
10
  abortConversion: (errCause: Error) => void;
11
11
  convertMediaState: ConvertMediaState;
12
12
  controller: AbortController;
13
13
  videoCodec: ConvertMediaVideoCodec;
14
- onVideoTrack: ResolveVideoActionFn;
14
+ onVideoTrack: ResolveVideoActionFn | null;
15
+ logLevel: LogLevel;
16
+ container: ConvertMediaContainer;
15
17
  }) => OnVideoTrack;
@@ -4,30 +4,28 @@ 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 convert_encoded_chunk_1 = require("./convert-encoded-chunk");
7
8
  const error_cause_1 = __importDefault(require("./error-cause"));
9
+ const on_frame_1 = require("./on-frame");
8
10
  const resolve_video_action_1 = require("./resolve-video-action");
9
11
  const video_decoder_1 = require("./video-decoder");
10
12
  const video_decoder_config_1 = require("./video-decoder-config");
11
13
  const video_encoder_1 = require("./video-encoder");
12
14
  const video_encoder_config_1 = require("./video-encoder-config");
13
- const makeVideoTrackHandler = ({ state, onVideoFrame, onMediaStateUpdate, abortConversion, convertMediaState, controller, videoCodec, onVideoTrack, }) => async (track) => {
14
- const videoEncoderConfig = await (0, video_encoder_config_1.getVideoEncoderConfig)({
15
- codec: videoCodec === 'vp9' ? 'vp09.00.10.08' : videoCodec,
16
- height: track.displayAspectHeight,
17
- width: track.displayAspectWidth,
18
- });
19
- const videoDecoderConfig = await (0, video_decoder_config_1.getVideoDecoderConfigWithHardwareAcceleration)(track);
20
- const videoOperation = await (0, resolve_video_action_1.resolveVideoAction)({
21
- videoDecoderConfig,
22
- videoEncoderConfig,
15
+ const makeVideoTrackHandler = ({ state, onVideoFrame, onMediaStateUpdate, abortConversion, convertMediaState, controller, videoCodec, onVideoTrack, logLevel, container, }) => async (track) => {
16
+ if (controller.signal.aborted) {
17
+ throw new error_cause_1.default('Aborted');
18
+ }
19
+ const videoOperation = await (onVideoTrack !== null && onVideoTrack !== void 0 ? onVideoTrack : resolve_video_action_1.defaultResolveVideoAction)({
23
20
  track,
24
21
  videoCodec,
25
- resolverFunction: onVideoTrack,
22
+ logLevel,
23
+ container,
26
24
  });
27
- if (videoOperation === 'drop') {
25
+ if (videoOperation.type === 'drop') {
28
26
  return null;
29
27
  }
30
- if (videoOperation === 'copy') {
28
+ if (videoOperation.type === 'copy') {
31
29
  const videoTrack = await state.addTrack({
32
30
  type: 'video',
33
31
  color: track.color,
@@ -36,12 +34,18 @@ const makeVideoTrackHandler = ({ state, onVideoFrame, onMediaStateUpdate, abortC
36
34
  codec: track.codecWithoutConfig,
37
35
  codecPrivate: track.codecPrivate,
38
36
  });
39
- return (sample) => {
40
- state.addSample(new EncodedVideoChunk(sample), videoTrack.trackNumber, true);
37
+ return async (sample) => {
38
+ await state.addSample(sample, videoTrack.trackNumber, true);
41
39
  convertMediaState.decodedVideoFrames++;
42
40
  onMediaStateUpdate === null || onMediaStateUpdate === void 0 ? void 0 : onMediaStateUpdate({ ...convertMediaState });
43
41
  };
44
42
  }
43
+ const videoEncoderConfig = await (0, video_encoder_config_1.getVideoEncoderConfig)({
44
+ codec: videoOperation.videoCodec,
45
+ height: track.displayAspectHeight,
46
+ width: track.displayAspectWidth,
47
+ });
48
+ const videoDecoderConfig = await (0, video_decoder_config_1.getVideoDecoderConfigWithHardwareAcceleration)(track);
45
49
  if (videoEncoderConfig === null) {
46
50
  abortConversion(new error_cause_1.default(`Could not configure video encoder of track ${track.trackId}`));
47
51
  return null;
@@ -60,7 +64,7 @@ const makeVideoTrackHandler = ({ state, onVideoFrame, onMediaStateUpdate, abortC
60
64
  });
61
65
  const videoEncoder = (0, video_encoder_1.createVideoEncoder)({
62
66
  onChunk: async (chunk) => {
63
- await state.addSample(chunk, trackNumber, true);
67
+ await state.addSample((0, convert_encoded_chunk_1.convertEncodedChunk)(chunk), trackNumber, true);
64
68
  convertMediaState.encodedVideoFrames++;
65
69
  onMediaStateUpdate === null || onMediaStateUpdate === void 0 ? void 0 : onMediaStateUpdate({ ...convertMediaState });
66
70
  },
@@ -71,15 +75,19 @@ const makeVideoTrackHandler = ({ state, onVideoFrame, onMediaStateUpdate, abortC
71
75
  },
72
76
  signal: controller.signal,
73
77
  config: videoEncoderConfig,
78
+ logLevel,
74
79
  });
75
80
  const videoDecoder = (0, video_decoder_1.createVideoDecoder)({
76
81
  config: videoDecoderConfig,
77
82
  onFrame: async (frame) => {
78
- await (onVideoFrame === null || onVideoFrame === void 0 ? void 0 : onVideoFrame(frame, track));
79
- await videoEncoder.encodeFrame(frame);
80
- convertMediaState.decodedVideoFrames++;
81
- onMediaStateUpdate === null || onMediaStateUpdate === void 0 ? void 0 : onMediaStateUpdate({ ...convertMediaState });
82
- frame.close();
83
+ await (0, on_frame_1.onFrame)({
84
+ convertMediaState,
85
+ frame,
86
+ onMediaStateUpdate,
87
+ track,
88
+ videoEncoder,
89
+ onVideoFrame,
90
+ });
83
91
  },
84
92
  onError: (err) => {
85
93
  abortConversion(new error_cause_1.default(`Video decoder of track ${track.trackId} failed (see .cause of this error)`, {
@@ -87,6 +95,7 @@ const makeVideoTrackHandler = ({ state, onVideoFrame, onMediaStateUpdate, abortC
87
95
  }));
88
96
  },
89
97
  signal: controller.signal,
98
+ logLevel,
90
99
  });
91
100
  state.addWaitForFinishPromise(async () => {
92
101
  await videoDecoder.waitForFinish();
@@ -0,0 +1,3 @@
1
+ import type { AudioSample } from '@remotion/media-parser';
2
+ import type { AudioOrVideoSample } from '@remotion/media-parser/src/create/cluster';
3
+ export declare const polyfillAudioChunk: (audioSample: AudioSample) => AudioOrVideoSample;
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.polyfillAudioChunk = void 0;
4
+ const polyfillAudioChunk = (audioSample) => { };
5
+ exports.polyfillAudioChunk = polyfillAudioChunk;
@@ -1,15 +1,19 @@
1
- import type { AudioTrack } from '@remotion/media-parser';
1
+ import type { AudioTrack, LogLevel } from '@remotion/media-parser';
2
2
  import type { ConvertMediaAudioCodec } from './codec-id';
3
- export type AudioOperation = 'reencode' | 'copy' | 'drop';
3
+ import type { ConvertMediaContainer } from './convert-media';
4
+ export type AudioOperation = {
5
+ type: 'reencode';
6
+ bitrate: number;
7
+ audioCodec: ConvertMediaAudioCodec;
8
+ } | {
9
+ type: 'copy';
10
+ } | {
11
+ type: 'drop';
12
+ };
4
13
  export type ResolveAudioActionFn = (options: {
5
- canReencode: boolean;
6
- canCopy: boolean;
7
- }) => AudioOperation | Promise<AudioOperation>;
8
- export declare const defaultResolveAudioAction: ResolveAudioActionFn;
9
- export declare const resolveAudioAction: ({ audioDecoderConfig, audioEncoderConfig, track, audioCodec, resolverFunction, }: {
10
- audioDecoderConfig: AudioDecoderConfig | null;
11
- audioEncoderConfig: AudioEncoderConfig | null;
12
14
  track: AudioTrack;
13
15
  audioCodec: ConvertMediaAudioCodec;
14
- resolverFunction: ResolveAudioActionFn;
15
- }) => Promise<AudioOperation>;
16
+ logLevel: LogLevel;
17
+ container: ConvertMediaContainer;
18
+ }) => AudioOperation | Promise<AudioOperation>;
19
+ export declare const defaultResolveAudioAction: ResolveAudioActionFn;