@remotion/webcodecs 4.0.251 → 4.0.253

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 (68) hide show
  1. package/dist/audio-decoder.d.ts +3 -2
  2. package/dist/audio-decoder.js +11 -9
  3. package/dist/audio-encoder.d.ts +4 -3
  4. package/dist/audio-encoder.js +10 -9
  5. package/dist/auto-select-writer.d.ts +1 -1
  6. package/dist/can-copy-video-track.js +2 -1
  7. package/dist/choose-correct-hevc-profile.d.ts +5 -0
  8. package/dist/choose-correct-hevc-profile.js +42 -0
  9. package/dist/controller.d.ts +16 -0
  10. package/dist/controller.js +16 -0
  11. package/dist/convert-media.d.ts +6 -6
  12. package/dist/convert-media.js +53 -21
  13. package/dist/create/iso-base-media/codec-specific/create-codec-specific-data.d.ts +11 -0
  14. package/dist/create/iso-base-media/codec-specific/create-codec-specific-data.js +29 -11
  15. package/dist/create/iso-base-media/codec-specific/hvc1.d.ts +2 -0
  16. package/dist/create/iso-base-media/codec-specific/hvc1.js +48 -0
  17. package/dist/create/iso-base-media/create-iso-base-media.js +8 -4
  18. package/dist/create/iso-base-media/serialize-track.js +3 -1
  19. package/dist/create/iso-base-media/trak/mdia/minf/stbl/stsd/create-hvcc.d.ts +1 -0
  20. package/dist/create/iso-base-media/trak/mdia/minf/stbl/stsd/create-hvcc.js +16 -0
  21. package/dist/create/matroska/cluster.d.ts +1 -1
  22. package/dist/create/matroska/create-matroska-media.js +8 -4
  23. package/dist/create/matroska/matroska-trackentry.js +3 -0
  24. package/dist/create/matroska/matroska-utils.d.ts +1 -1
  25. package/dist/create/media-fn.d.ts +2 -3
  26. package/dist/create/wav/create-wav.js +8 -4
  27. package/dist/emitter.d.ts +20 -0
  28. package/dist/emitter.js +29 -0
  29. package/dist/esm/buffer.mjs +5 -22
  30. package/dist/esm/index.mjs +633 -159
  31. package/dist/esm/web-fs.mjs +4 -22
  32. package/dist/get-available-containers.d.ts +1 -2
  33. package/dist/get-available-containers.js +3 -3
  34. package/dist/get-available-video-codecs.d.ts +1 -2
  35. package/dist/get-available-video-codecs.js +3 -4
  36. package/dist/get-codec-string.d.ts +7 -0
  37. package/dist/get-codec-string.js +21 -0
  38. package/dist/hevc-levels.d.ts +13 -0
  39. package/dist/hevc-levels.js +233 -0
  40. package/dist/index.d.ts +1 -1
  41. package/dist/index.js +3 -1
  42. package/dist/io-manager/io-synchronizer.d.ts +4 -3
  43. package/dist/io-manager/io-synchronizer.js +19 -14
  44. package/dist/io-manager/make-timeout-promise.d.ts +6 -1
  45. package/dist/io-manager/make-timeout-promise.js +23 -5
  46. package/dist/on-audio-track.d.ts +2 -2
  47. package/dist/on-audio-track.js +13 -16
  48. package/dist/on-video-track.d.ts +2 -2
  49. package/dist/on-video-track.js +10 -14
  50. package/dist/select-container-creator.d.ts +1 -1
  51. package/dist/test/remux-serverside.test.js +2 -2
  52. package/dist/throttled-state-update.d.ts +1 -1
  53. package/dist/throttled-state-update.js +2 -2
  54. package/dist/video-decoder.d.ts +3 -2
  55. package/dist/video-decoder.js +10 -8
  56. package/dist/video-encoder-config.js +4 -6
  57. package/dist/video-encoder.d.ts +4 -3
  58. package/dist/video-encoder.js +13 -8
  59. package/dist/wav-audio-encoder.d.ts +1 -1
  60. package/dist/wav-audio-encoder.js +2 -2
  61. package/dist/webcodecs-controller.d.ts +16 -0
  62. package/dist/webcodecs-controller.js +16 -0
  63. package/dist/writers/buffer-implementation/writer.d.ts +1 -1
  64. package/dist/writers/buffer-implementation/writer.js +5 -4
  65. package/dist/writers/buffer.d.ts +1 -1
  66. package/dist/writers/web-fs.d.ts +1 -1
  67. package/dist/writers/web-fs.js +4 -4
  68. package/package.json +5 -5
@@ -2,18 +2,18 @@ import type { LogLevel, OnVideoTrack } from '@remotion/media-parser';
2
2
  import type { ConvertMediaOnVideoFrame } from './convert-media';
3
3
  import type { MediaFn } from './create/media-fn';
4
4
  import type { ProgressTracker } from './create/progress-tracker';
5
- import Error from './error-cause';
6
5
  import type { ConvertMediaContainer } from './get-available-containers';
7
6
  import type { ConvertMediaVideoCodec } from './get-available-video-codecs';
8
7
  import type { ConvertMediaOnVideoTrackHandler } from './on-video-track-handler';
9
8
  import type { ResizeOperation } from './resizing/mode';
10
9
  import type { ConvertMediaProgressFn } from './throttled-state-update';
10
+ import type { WebCodecsController } from './webcodecs-controller';
11
11
  export declare const makeVideoTrackHandler: ({ state, onVideoFrame, onMediaStateUpdate, abortConversion, controller, defaultVideoCodec, onVideoTrack, logLevel, outputContainer, rotate, progress, resizeOperation, }: {
12
12
  state: MediaFn;
13
13
  onVideoFrame: null | ConvertMediaOnVideoFrame;
14
14
  onMediaStateUpdate: null | ConvertMediaProgressFn;
15
15
  abortConversion: (errCause: Error) => void;
16
- controller: AbortController;
16
+ controller: WebCodecsController;
17
17
  defaultVideoCodec: ConvertMediaVideoCodec | null;
18
18
  onVideoTrack: ConvertMediaOnVideoTrackHandler | null;
19
19
  logLevel: LogLevel;
@@ -1,14 +1,10 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.makeVideoTrackHandler = void 0;
7
4
  const arraybuffer_to_uint8_array_1 = require("./arraybuffer-to-uint8-array");
8
5
  const can_copy_video_track_1 = require("./can-copy-video-track");
9
6
  const convert_encoded_chunk_1 = require("./convert-encoded-chunk");
10
7
  const default_on_video_track_handler_1 = require("./default-on-video-track-handler");
11
- const error_cause_1 = __importDefault(require("./error-cause"));
12
8
  const get_default_video_codec_1 = require("./get-default-video-codec");
13
9
  const log_1 = require("./log");
14
10
  const on_frame_1 = require("./on-frame");
@@ -19,8 +15,8 @@ const video_encoder_1 = require("./video-encoder");
19
15
  const video_encoder_config_1 = require("./video-encoder-config");
20
16
  const makeVideoTrackHandler = ({ state, onVideoFrame, onMediaStateUpdate, abortConversion, controller, defaultVideoCodec, onVideoTrack, logLevel, outputContainer, rotate, progress, resizeOperation, }) => async ({ track, container: inputContainer }) => {
21
17
  var _a, _b;
22
- if (controller.signal.aborted) {
23
- throw new error_cause_1.default('Aborted');
18
+ if (controller._internals.signal.aborted) {
19
+ throw new Error('Aborted');
24
20
  }
25
21
  const canCopyTrack = (0, can_copy_video_track_1.canCopyVideoTrack)({
26
22
  inputContainer,
@@ -43,7 +39,7 @@ const makeVideoTrackHandler = ({ state, onVideoFrame, onMediaStateUpdate, abortC
43
39
  return null;
44
40
  }
45
41
  if (videoOperation.type === 'fail') {
46
- throw new error_cause_1.default(`Video track with ID ${track.trackId} 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`);
42
+ throw new Error(`Video track with ID ${track.trackId} 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`);
47
43
  }
48
44
  if (videoOperation.type === 'copy') {
49
45
  log_1.Log.verbose(logLevel, `Copying video track with codec ${track.codec} and timescale ${track.timescale}`);
@@ -72,7 +68,7 @@ const makeVideoTrackHandler = ({ state, onVideoFrame, onMediaStateUpdate, abortC
72
68
  };
73
69
  }
74
70
  if (videoOperation.type !== 'reencode') {
75
- throw new error_cause_1.default(`Video track with ID ${track.trackId} could not be resolved with a valid operation. Received ${JSON.stringify(videoOperation)}, but must be either "copy", "reencode", "drop" or "fail"`);
71
+ throw new Error(`Video track with ID ${track.trackId} could not be resolved with a valid operation. Received ${JSON.stringify(videoOperation)}, but must be either "copy", "reencode", "drop" or "fail"`);
76
72
  }
77
73
  const rotation = ((_a = videoOperation.rotate) !== null && _a !== void 0 ? _a : rotate) - track.rotation;
78
74
  const { height: newHeight, width: newWidth } = (0, rotation_1.calculateNewDimensionsFromRotateAndScale)({
@@ -90,11 +86,11 @@ const makeVideoTrackHandler = ({ state, onVideoFrame, onMediaStateUpdate, abortC
90
86
  });
91
87
  const videoDecoderConfig = await (0, video_decoder_config_1.getVideoDecoderConfigWithHardwareAcceleration)(track);
92
88
  if (videoEncoderConfig === null) {
93
- abortConversion(new error_cause_1.default(`Could not configure video encoder of track ${track.trackId}`));
89
+ abortConversion(new Error(`Could not configure video encoder of track ${track.trackId}`));
94
90
  return null;
95
91
  }
96
92
  if (videoDecoderConfig === null) {
97
- abortConversion(new error_cause_1.default(`Could not configure video decoder of track ${track.trackId}`));
93
+ abortConversion(new Error(`Could not configure video decoder of track ${track.trackId}`));
98
94
  return null;
99
95
  }
100
96
  const { trackNumber } = await state.addTrack({
@@ -124,11 +120,11 @@ const makeVideoTrackHandler = ({ state, onVideoFrame, onMediaStateUpdate, abortC
124
120
  });
125
121
  },
126
122
  onError: (err) => {
127
- abortConversion(new error_cause_1.default(`Video encoder of track ${track.trackId} failed (see .cause of this error)`, {
123
+ abortConversion(new Error(`Video encoder of track ${track.trackId} failed (see .cause of this error)`, {
128
124
  cause: err,
129
125
  }));
130
126
  },
131
- signal: controller.signal,
127
+ controller,
132
128
  config: videoEncoderConfig,
133
129
  logLevel,
134
130
  outputCodec: videoOperation.videoCodec,
@@ -149,11 +145,11 @@ const makeVideoTrackHandler = ({ state, onVideoFrame, onMediaStateUpdate, abortC
149
145
  });
150
146
  },
151
147
  onError: (err) => {
152
- abortConversion(new error_cause_1.default(`Video decoder of track ${track.trackId} failed (see .cause of this error)`, {
148
+ abortConversion(new Error(`Video decoder of track ${track.trackId} failed (see .cause of this error)`, {
153
149
  cause: err,
154
150
  }));
155
151
  },
156
- signal: controller.signal,
152
+ controller,
157
153
  logLevel,
158
154
  progress,
159
155
  });
@@ -1,2 +1,2 @@
1
1
  import type { ConvertMediaContainer } from './get-available-containers';
2
- export declare const selectContainerCreator: (container: ConvertMediaContainer) => ({ writer, onBytesProgress, onMillisecondsProgress, logLevel, filename, progressTracker, }: import("./create/media-fn").MediaFnGeneratorInput) => Promise<import("./create/media-fn").MediaFn>;
2
+ export declare const selectContainerCreator: (container: ConvertMediaContainer) => ({ filename, logLevel, onBytesProgress, onMillisecondsProgress, writer, progressTracker, }: import("./create/media-fn").MediaFnGeneratorInput) => Promise<import("./create/media-fn").MediaFn>;
@@ -2,10 +2,10 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const example_videos_1 = require("@remotion/example-videos");
4
4
  const node_1 = require("@remotion/media-parser/node");
5
+ const node_writer_1 = require("@remotion/media-parser/node-writer");
5
6
  const bun_test_1 = require("bun:test");
6
7
  const node_fs_1 = require("node:fs");
7
8
  const convert_media_1 = require("../convert-media");
8
- const node_2 = require("../writers/node");
9
9
  (0, bun_test_1.test)('should be able to remux server side', async () => {
10
10
  // bun file descriptor problem
11
11
  if (process.platform === 'win32') {
@@ -15,7 +15,7 @@ const node_2 = require("../writers/node");
15
15
  src: example_videos_1.exampleVideos.bigBuckBunny,
16
16
  reader: node_1.nodeReader,
17
17
  container: 'mp4',
18
- writer: (0, node_2.nodeWriter)('outputbun.mp4'),
18
+ writer: (0, node_writer_1.nodeWriter)('outputbun.mp4'),
19
19
  });
20
20
  const data = await save();
21
21
  (0, bun_test_1.expect)(data.size).toBe(15306323);
@@ -8,6 +8,6 @@ type ReturnType = {
8
8
  export declare const throttledStateUpdate: ({ updateFn, everyMilliseconds, signal, }: {
9
9
  updateFn: ConvertMediaOnProgress | null;
10
10
  everyMilliseconds: number;
11
- signal: AbortSignal;
11
+ signal: AbortSignal | null;
12
12
  }) => ReturnType;
13
13
  export {};
@@ -33,7 +33,7 @@ const throttledStateUpdate = ({ updateFn, everyMilliseconds, signal, }) => {
33
33
  const onAbort = () => {
34
34
  clearInterval(interval);
35
35
  };
36
- signal.addEventListener('abort', onAbort, { once: true });
36
+ signal === null || signal === void 0 ? void 0 : signal.addEventListener('abort', onAbort, { once: true });
37
37
  return {
38
38
  get: () => currentState,
39
39
  update: (fn) => {
@@ -41,7 +41,7 @@ const throttledStateUpdate = ({ updateFn, everyMilliseconds, signal, }) => {
41
41
  },
42
42
  stopAndGetLastProgress: () => {
43
43
  clearInterval(interval);
44
- signal.removeEventListener('abort', onAbort);
44
+ signal === null || signal === void 0 ? void 0 : signal.removeEventListener('abort', onAbort);
45
45
  return currentState;
46
46
  },
47
47
  };
@@ -1,15 +1,16 @@
1
1
  import type { AudioOrVideoSample, LogLevel } from '@remotion/media-parser';
2
2
  import type { ProgressTracker } from './create/progress-tracker';
3
+ import type { WebCodecsController } from './webcodecs-controller';
3
4
  export type WebCodecsVideoDecoder = {
4
5
  processSample: (videoSample: AudioOrVideoSample) => Promise<void>;
5
6
  waitForFinish: () => Promise<void>;
6
7
  close: () => void;
7
8
  flush: () => Promise<void>;
8
9
  };
9
- export declare const createVideoDecoder: ({ onFrame, onError, signal, config, logLevel, progress, }: {
10
+ export declare const createVideoDecoder: ({ onFrame, onError, controller, config, logLevel, progress, }: {
10
11
  onFrame: (frame: VideoFrame) => Promise<void>;
11
12
  onError: (error: DOMException) => void;
12
- signal: AbortSignal;
13
+ controller: WebCodecsController;
13
14
  config: VideoDecoderConfig;
14
15
  logLevel: LogLevel;
15
16
  progress: ProgressTracker;
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createVideoDecoder = void 0;
4
4
  const io_synchronizer_1 = require("./io-manager/io-synchronizer");
5
5
  const log_1 = require("./log");
6
- const createVideoDecoder = ({ onFrame, onError, signal, config, logLevel, progress, }) => {
6
+ const createVideoDecoder = ({ onFrame, onError, controller, config, logLevel, progress, }) => {
7
7
  const ioSynchronizer = (0, io_synchronizer_1.makeIoSynchronizer)({
8
8
  logLevel,
9
9
  label: 'Video decoder',
@@ -16,17 +16,19 @@ const createVideoDecoder = ({ onFrame, onError, signal, config, logLevel, progre
16
16
  const abortHandler = () => {
17
17
  inputFrame.close();
18
18
  };
19
- signal.addEventListener('abort', abortHandler, { once: true });
19
+ controller._internals.signal.addEventListener('abort', abortHandler, {
20
+ once: true,
21
+ });
20
22
  outputQueue = outputQueue
21
23
  .then(() => {
22
- if (signal.aborted) {
24
+ if (controller._internals.signal.aborted) {
23
25
  return;
24
26
  }
25
27
  return onFrame(inputFrame);
26
28
  })
27
29
  .then(() => {
28
30
  ioSynchronizer.onProcessed();
29
- signal.removeEventListener('abort', abortHandler);
31
+ controller._internals.signal.removeEventListener('abort', abortHandler);
30
32
  return Promise.resolve();
31
33
  })
32
34
  .catch((err) => {
@@ -40,7 +42,7 @@ const createVideoDecoder = ({ onFrame, onError, signal, config, logLevel, progre
40
42
  });
41
43
  const close = () => {
42
44
  // eslint-disable-next-line @typescript-eslint/no-use-before-define
43
- signal.removeEventListener('abort', onAbort);
45
+ controller._internals.signal.removeEventListener('abort', onAbort);
44
46
  if (videoDecoder.state === 'closed') {
45
47
  return;
46
48
  }
@@ -49,7 +51,7 @@ const createVideoDecoder = ({ onFrame, onError, signal, config, logLevel, progre
49
51
  const onAbort = () => {
50
52
  close();
51
53
  };
52
- signal.addEventListener('abort', onAbort);
54
+ controller._internals.signal.addEventListener('abort', onAbort);
53
55
  videoDecoder.configure(config);
54
56
  const processSample = async (sample) => {
55
57
  var _a, _b;
@@ -65,7 +67,7 @@ const createVideoDecoder = ({ onFrame, onError, signal, config, logLevel, progre
65
67
  unemitted: 20,
66
68
  unprocessed: 2,
67
69
  minimumProgress: sample.timestamp - 10000000,
68
- signal,
70
+ controller,
69
71
  });
70
72
  if (sample.type === 'key') {
71
73
  await videoDecoder.flush();
@@ -82,7 +84,7 @@ const createVideoDecoder = ({ onFrame, onError, signal, config, logLevel, progre
82
84
  waitForFinish: async () => {
83
85
  await videoDecoder.flush();
84
86
  log_1.Log.verbose(logLevel, 'Flushed video decoder');
85
- await ioSynchronizer.waitForFinish(signal);
87
+ await ioSynchronizer.waitForFinish(controller);
86
88
  log_1.Log.verbose(logLevel, 'IO synchro finished');
87
89
  await outputQueue;
88
90
  log_1.Log.verbose(logLevel, 'Output queue finished');
@@ -2,20 +2,18 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getVideoEncoderConfig = void 0;
4
4
  const browser_quirks_1 = require("./browser-quirks");
5
- const choose_correct_avc1_profile_1 = require("./choose-correct-avc1-profile");
5
+ const get_codec_string_1 = require("./get-codec-string");
6
6
  const getVideoEncoderConfig = async ({ codec, height, width, fps, }) => {
7
7
  if (typeof VideoEncoder === 'undefined') {
8
8
  return null;
9
9
  }
10
10
  const config = {
11
- codec: codec === 'h264'
12
- ? (0, choose_correct_avc1_profile_1.chooseCorrectAvc1Profile)({ fps, height, width })
13
- : codec === 'vp9'
14
- ? 'vp09.00.10.08'
15
- : codec,
11
+ codec: (0, get_codec_string_1.getCodecStringForEncoder)({ codec, fps, height, width }),
16
12
  height,
17
13
  width,
18
14
  bitrate: (0, browser_quirks_1.isSafari)() ? 3000000 : undefined,
15
+ bitrateMode: codec === 'vp9' && !(0, browser_quirks_1.isSafari)() ? 'quantizer' : undefined,
16
+ framerate: fps !== null && fps !== void 0 ? fps : undefined,
19
17
  };
20
18
  const hardware = {
21
19
  ...config,
@@ -1,16 +1,17 @@
1
- import type { LogLevel } from '@remotion/media-parser';
1
+ import { type LogLevel } from '@remotion/media-parser';
2
2
  import type { ProgressTracker } from './create/progress-tracker';
3
3
  import type { ConvertMediaVideoCodec } from './get-available-video-codecs';
4
+ import type { WebCodecsController } from './webcodecs-controller';
4
5
  export type WebCodecsVideoEncoder = {
5
6
  encodeFrame: (videoFrame: VideoFrame, timestamp: number) => Promise<void>;
6
7
  waitForFinish: () => Promise<void>;
7
8
  close: () => void;
8
9
  flush: () => Promise<void>;
9
10
  };
10
- export declare const createVideoEncoder: ({ onChunk, onError, signal, config, logLevel, outputCodec, progress, }: {
11
+ export declare const createVideoEncoder: ({ onChunk, onError, controller, config, logLevel, outputCodec, progress, }: {
11
12
  onChunk: (chunk: EncodedVideoChunk, metadata: EncodedVideoChunkMetadata | null) => Promise<void>;
12
13
  onError: (error: DOMException) => void;
13
- signal: AbortSignal;
14
+ controller: WebCodecsController;
14
15
  config: VideoEncoderConfig;
15
16
  logLevel: LogLevel;
16
17
  outputCodec: ConvertMediaVideoCodec;
@@ -1,12 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createVideoEncoder = void 0;
4
+ const media_parser_1 = require("@remotion/media-parser");
4
5
  const convert_to_correct_videoframe_1 = require("./convert-to-correct-videoframe");
5
6
  const io_synchronizer_1 = require("./io-manager/io-synchronizer");
6
7
  const log_1 = require("./log");
7
- const createVideoEncoder = ({ onChunk, onError, signal, config, logLevel, outputCodec, progress, }) => {
8
- if (signal.aborted) {
9
- throw new Error('Not creating video encoder, already aborted');
8
+ const createVideoEncoder = ({ onChunk, onError, controller, config, logLevel, outputCodec, progress, }) => {
9
+ if (controller._internals.signal.aborted) {
10
+ throw new media_parser_1.MediaParserAbortError('Not creating video encoder, already aborted');
10
11
  }
11
12
  const ioSynchronizer = (0, io_synchronizer_1.makeIoSynchronizer)({
12
13
  logLevel,
@@ -24,7 +25,7 @@ const createVideoEncoder = ({ onChunk, onError, signal, config, logLevel, output
24
25
  ioSynchronizer.onOutput(timestamp);
25
26
  outputQueue = outputQueue
26
27
  .then(() => {
27
- if (signal.aborted) {
28
+ if (controller._internals.signal.aborted) {
28
29
  return;
29
30
  }
30
31
  return onChunk(chunk, metadata !== null && metadata !== void 0 ? metadata : null);
@@ -40,7 +41,7 @@ const createVideoEncoder = ({ onChunk, onError, signal, config, logLevel, output
40
41
  });
41
42
  const close = () => {
42
43
  // eslint-disable-next-line @typescript-eslint/no-use-before-define
43
- signal.removeEventListener('abort', onAbort);
44
+ controller._internals.signal.removeEventListener('abort', onAbort);
44
45
  if (encoder.state === 'closed') {
45
46
  return;
46
47
  }
@@ -49,7 +50,7 @@ const createVideoEncoder = ({ onChunk, onError, signal, config, logLevel, output
49
50
  const onAbort = () => {
50
51
  close();
51
52
  };
52
- signal.addEventListener('abort', onAbort);
53
+ controller._internals.signal.addEventListener('abort', onAbort);
53
54
  log_1.Log.verbose(logLevel, 'Configuring video encoder', config);
54
55
  encoder.configure(config);
55
56
  let framesProcessed = 0;
@@ -63,7 +64,7 @@ const createVideoEncoder = ({ onChunk, onError, signal, config, logLevel, output
63
64
  unemitted: 10,
64
65
  unprocessed: 10,
65
66
  minimumProgress: frame.timestamp - 10000000,
66
- signal,
67
+ controller,
67
68
  });
68
69
  // @ts-expect-error - can have changed in the meanwhile
69
70
  if (encoder.state === 'closed') {
@@ -72,6 +73,10 @@ const createVideoEncoder = ({ onChunk, onError, signal, config, logLevel, output
72
73
  const keyFrame = framesProcessed % 40 === 0;
73
74
  encoder.encode((0, convert_to_correct_videoframe_1.convertToCorrectVideoFrame)({ videoFrame: frame, outputCodec }), {
74
75
  keyFrame,
76
+ // @ts-expect-error
77
+ vp9: {
78
+ quantizer: 36,
79
+ },
75
80
  });
76
81
  ioSynchronizer.inputItem(frame.timestamp, keyFrame);
77
82
  framesProcessed++;
@@ -85,7 +90,7 @@ const createVideoEncoder = ({ onChunk, onError, signal, config, logLevel, output
85
90
  waitForFinish: async () => {
86
91
  await encoder.flush();
87
92
  await outputQueue;
88
- await ioSynchronizer.waitForFinish(signal);
93
+ await ioSynchronizer.waitForFinish(controller);
89
94
  },
90
95
  close,
91
96
  flush: async () => {
@@ -1,2 +1,2 @@
1
1
  import type { AudioEncoderInit, WebCodecsAudioEncoder } from './audio-encoder';
2
- export declare const getWaveAudioEncoder: ({ onChunk, signal, }: Pick<AudioEncoderInit, "onChunk" | "signal">) => WebCodecsAudioEncoder;
2
+ export declare const getWaveAudioEncoder: ({ onChunk, controller, }: Pick<AudioEncoderInit, "onChunk" | "controller">) => WebCodecsAudioEncoder;
@@ -1,13 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getWaveAudioEncoder = void 0;
4
- const getWaveAudioEncoder = ({ onChunk, signal, }) => {
4
+ const getWaveAudioEncoder = ({ onChunk, controller, }) => {
5
5
  return {
6
6
  close: () => {
7
7
  return Promise.resolve();
8
8
  },
9
9
  encodeFrame: (audioData) => {
10
- if (signal.aborted) {
10
+ if (controller._internals.signal.aborted) {
11
11
  return Promise.resolve();
12
12
  }
13
13
  const chunk = {
@@ -0,0 +1,16 @@
1
+ import type { MediaParserController } from '@remotion/media-parser';
2
+ export type WebCodecsController = {
3
+ abort: (reason?: any) => void;
4
+ pause: MediaParserController['pause'];
5
+ resume: MediaParserController['resume'];
6
+ addEventListener: MediaParserController['addEventListener'];
7
+ removeEventListener: MediaParserController['removeEventListener'];
8
+ /**
9
+ * @deprecated Not public API
10
+ */
11
+ _internals: {
12
+ signal: AbortSignal;
13
+ checkForAbortAndPause: MediaParserController['_internals']['checkForAbortAndPause'];
14
+ };
15
+ };
16
+ export declare const webcodecsController: () => WebCodecsController;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.webcodecsController = void 0;
4
+ const media_parser_1 = require("@remotion/media-parser");
5
+ const webcodecsController = () => {
6
+ const controller = (0, media_parser_1.mediaParserController)();
7
+ return {
8
+ abort: controller.abort,
9
+ pause: controller.pause,
10
+ resume: controller.resume,
11
+ addEventListener: controller.addEventListener,
12
+ removeEventListener: controller.removeEventListener,
13
+ _internals: controller._internals,
14
+ };
15
+ };
16
+ exports.webcodecsController = webcodecsController;
@@ -1,2 +1,2 @@
1
- import type { CreateContent } from '../writer';
1
+ import type { CreateContent } from '@remotion/media-parser';
2
2
  export declare const createContent: CreateContent;
@@ -27,10 +27,14 @@ const createContent = ({ filename, mimeType }) => {
27
27
  writPromise = writPromise.then(() => write(arr));
28
28
  return writPromise;
29
29
  },
30
- save: () => {
30
+ finish: async () => {
31
+ await writPromise;
31
32
  if (removed) {
32
33
  return Promise.reject(new Error('Already called .remove() on the result'));
33
34
  }
35
+ return Promise.resolve();
36
+ },
37
+ getBlob() {
34
38
  const arr = new Uint8Array(buf);
35
39
  return Promise.resolve(
36
40
  // TODO: Unhardcode MIME type and file name
@@ -45,9 +49,6 @@ const createContent = ({ filename, mimeType }) => {
45
49
  writPromise = writPromise.then(() => updateDataAt(position, newData));
46
50
  return writPromise;
47
51
  },
48
- waitForFinish: async () => {
49
- await writPromise;
50
- },
51
52
  };
52
53
  return Promise.resolve(writer);
53
54
  };
@@ -1,2 +1,2 @@
1
- import type { WriterInterface } from './writer';
1
+ import type { WriterInterface } from '@remotion/media-parser';
2
2
  export declare const bufferWriter: WriterInterface;
@@ -1,3 +1,3 @@
1
- import type { WriterInterface } from './writer';
1
+ import type { WriterInterface } from '@remotion/media-parser';
2
2
  export declare const webFsWriter: WriterInterface;
3
3
  export declare const canUseWebFsWriter: () => Promise<boolean>;
@@ -33,13 +33,16 @@ const createContent = async ({ filename }) => {
33
33
  writPromise = writPromise.then(() => write(arr));
34
34
  return writPromise;
35
35
  },
36
- save: async () => {
36
+ finish: async () => {
37
+ await writPromise;
37
38
  try {
38
39
  await writable.close();
39
40
  }
40
41
  catch (_a) {
41
42
  // Ignore, could already be closed
42
43
  }
44
+ },
45
+ async getBlob() {
43
46
  const newHandle = await directoryHandle.getFileHandle(actualFilename, {
44
47
  create: true,
45
48
  });
@@ -51,9 +54,6 @@ const createContent = async ({ filename }) => {
51
54
  writPromise = writPromise.then(() => updateDataAt(position, data));
52
55
  return writPromise;
53
56
  },
54
- waitForFinish: async () => {
55
- await writPromise;
56
- },
57
57
  remove,
58
58
  };
59
59
  return writer;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remotion/webcodecs",
3
- "version": "4.0.251",
3
+ "version": "4.0.253",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "module": "dist/esm/index.mjs",
@@ -17,15 +17,15 @@
17
17
  "author": "Jonny Burger <jonny@remotion.dev>",
18
18
  "license": "Remotion License (See https://remotion.dev/docs/webcodecs#license)",
19
19
  "dependencies": {
20
- "@remotion/media-parser": "4.0.251",
21
- "@remotion/licensing": "4.0.251"
20
+ "@remotion/media-parser": "4.0.253",
21
+ "@remotion/licensing": "4.0.253"
22
22
  },
23
23
  "peerDependencies": {},
24
24
  "devDependencies": {
25
25
  "@types/dom-webcodecs": "0.1.11",
26
26
  "eslint": "9.14.0",
27
- "@remotion/example-videos": "4.0.251",
28
- "@remotion/eslint-config-internal": "4.0.251"
27
+ "@remotion/eslint-config-internal": "4.0.253",
28
+ "@remotion/example-videos": "4.0.253"
29
29
  },
30
30
  "keywords": [],
31
31
  "publishConfig": {