@remotion/webcodecs 4.0.270 → 4.0.272

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 (37) hide show
  1. package/dist/audio-decoder.js +3 -5
  2. package/dist/can-reencode-video-track.js +1 -1
  3. package/dist/choose-correct-avc1-profile.js +1 -1
  4. package/dist/choose-correct-hevc-profile.js +1 -1
  5. package/dist/convert-encoded-chunk.js +1 -2
  6. package/dist/convert-media.d.ts +2 -1
  7. package/dist/convert-media.js +51 -53
  8. package/dist/create/iso-base-media/create-iso-base-media.d.ts +1 -1
  9. package/dist/create/iso-base-media/create-iso-base-media.js +8 -8
  10. package/dist/create/iso-base-media/header-length.d.ts +1 -0
  11. package/dist/create/iso-base-media/header-length.js +21 -0
  12. package/dist/create/iso-base-media/mp4-header.d.ts +4 -1
  13. package/dist/create/iso-base-media/mp4-header.js +11 -4
  14. package/dist/create/iso-base-media/primitives.d.ts +1 -0
  15. package/dist/create/iso-base-media/primitives.js +16 -2
  16. package/dist/create/iso-base-media/trak/mdia/minf/stbl/create-stco.js +8 -2
  17. package/dist/create/iso-base-media/trak/mdia/minf/stbl/create-stts.js +1 -2
  18. package/dist/create/matroska/create-matroska-media.js +8 -9
  19. package/dist/create/matroska/matroska-utils.js +3 -4
  20. package/dist/create/media-fn.d.ts +1 -0
  21. package/dist/create/wav/create-wav.js +1 -2
  22. package/dist/esm/index.mjs +54 -13
  23. package/dist/generate-output-filename.d.ts +2 -1
  24. package/dist/on-audio-track.js +7 -7
  25. package/dist/on-frame.js +1 -2
  26. package/dist/on-video-track.js +9 -11
  27. package/dist/rotate-and-resize-video-frame.js +1 -2
  28. package/dist/select-container-creator.d.ts +1 -1
  29. package/dist/send-telemetry-event.js +1 -2
  30. package/dist/test/mp4-header-length.test.d.ts +1 -0
  31. package/dist/test/mp4-header-length.test.js +12 -0
  32. package/dist/throttled-state-update.js +2 -2
  33. package/dist/video-decoder.js +1 -2
  34. package/dist/video-encoder-config.js +1 -1
  35. package/dist/video-encoder.js +2 -3
  36. package/dist/writers/web-fs.js +2 -2
  37. package/package.json +5 -5
@@ -18,8 +18,7 @@ const createAudioDecoder = ({ onFrame, onError, controller, config, logLevel, tr
18
18
  let outputQueue = Promise.resolve();
19
19
  const audioDecoder = new AudioDecoder({
20
20
  output(frame) {
21
- var _a;
22
- ioSynchronizer.onOutput(frame.timestamp + ((_a = frame.duration) !== null && _a !== void 0 ? _a : 0));
21
+ ioSynchronizer.onOutput(frame.timestamp + (frame.duration ?? 0));
23
22
  const abortHandler = () => {
24
23
  frame.close();
25
24
  };
@@ -61,11 +60,10 @@ const createAudioDecoder = ({ onFrame, onError, controller, config, logLevel, tr
61
60
  controller._internals.signal.addEventListener('abort', onAbort);
62
61
  audioDecoder.configure(config);
63
62
  const processSample = async (audioSample) => {
64
- var _a, _b;
65
63
  if (audioDecoder.state === 'closed') {
66
64
  return;
67
65
  }
68
- progressTracker.setPossibleLowestTimestamp(Math.min(audioSample.timestamp, (_a = audioSample.dts) !== null && _a !== void 0 ? _a : Infinity, (_b = audioSample.cts) !== null && _b !== void 0 ? _b : Infinity));
66
+ progressTracker.setPossibleLowestTimestamp(Math.min(audioSample.timestamp, audioSample.dts ?? Infinity, audioSample.cts ?? Infinity));
69
67
  await ioSynchronizer.waitFor({
70
68
  unemitted: 20,
71
69
  unprocessed: 20,
@@ -95,7 +93,7 @@ const createAudioDecoder = ({ onFrame, onError, controller, config, logLevel, tr
95
93
  try {
96
94
  await audioDecoder.flush();
97
95
  }
98
- catch (_a) { }
96
+ catch { }
99
97
  await queue;
100
98
  await ioSynchronizer.waitForFinish(controller);
101
99
  await outputQueue;
@@ -8,7 +8,7 @@ const canReencodeVideoTrack = async ({ videoCodec, track, resizeOperation, rotat
8
8
  const { height, width } = (0, rotation_1.calculateNewDimensionsFromRotateAndScale)({
9
9
  height: track.displayAspectHeight,
10
10
  resizeOperation,
11
- rotation: rotate !== null && rotate !== void 0 ? rotate : 0,
11
+ rotation: rotate ?? 0,
12
12
  videoCodec,
13
13
  width: track.displayAspectWidth,
14
14
  });
@@ -43,7 +43,7 @@ const chooseCorrectAvc1Profile = ({ width, height, fps, }) => {
43
43
  return false;
44
44
  }
45
45
  // if has no fps, use 60 as a conservative fallback
46
- const fallbackFps = fps !== null && fps !== void 0 ? fps : 60;
46
+ const fallbackFps = fps ?? 60;
47
47
  return fallbackFps <= p.fps;
48
48
  });
49
49
  if (!profile) {
@@ -12,7 +12,7 @@ const chooseCorrectHevcProfile = ({ width, height, fps, }) => {
12
12
  return false;
13
13
  }
14
14
  // if has no fps, use 60 as a conservative fallback
15
- const fallbackFps = fps !== null && fps !== void 0 ? fps : 60;
15
+ const fallbackFps = fps ?? 60;
16
16
  return fallbackFps <= max.fps;
17
17
  });
18
18
  });
@@ -2,12 +2,11 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.convertEncodedChunk = void 0;
4
4
  const convertEncodedChunk = (chunk, trackId) => {
5
- var _a;
6
5
  const arr = new Uint8Array(chunk.byteLength);
7
6
  chunk.copyTo(arr);
8
7
  return {
9
8
  data: arr,
10
- duration: (_a = chunk.duration) !== null && _a !== void 0 ? _a : undefined,
9
+ duration: chunk.duration ?? undefined,
11
10
  timestamp: chunk.timestamp,
12
11
  type: chunk.type,
13
12
  cts: chunk.timestamp,
@@ -35,7 +35,7 @@ export type ConvertMediaOnAudioData = (options: {
35
35
  audioData: AudioData;
36
36
  track: AudioTrack;
37
37
  }) => Promise<AudioData> | AudioData;
38
- export declare const convertMedia: <F extends Options<ParseMediaFields>>({ src, onVideoFrame, onAudioData, onProgress: onProgressDoNotCallDirectly, audioCodec, container, videoCodec, controller, onAudioTrack: userAudioResolver, onVideoTrack: userVideoResolver, reader, fields, logLevel, writer, progressIntervalInMs, rotate, apiKey, resize, onAudioCodec, onContainer, onDimensions, onDurationInSeconds, onFps, onImages, onInternalStats, onIsHdr, onKeyframes, onLocation, onMetadata, onMimeType, onName, onNumberOfAudioChannels, onRotation, onSampleRate, onSize, onSlowAudioBitrate, onSlowDurationInSeconds, onSlowFps, onSlowKeyframes, onSlowNumberOfFrames, onSlowVideoBitrate, onStructure, onTracks, onUnrotatedDimensions, onVideoCodec, onM3uStreams, selectM3uStream, selectM3uAssociatedPlaylists, ...more }: {
38
+ export declare const convertMedia: <F extends Options<ParseMediaFields>>({ src, onVideoFrame, onAudioData, onProgress: onProgressDoNotCallDirectly, audioCodec, container, videoCodec, controller, onAudioTrack: userAudioResolver, onVideoTrack: userVideoResolver, reader, fields, logLevel, writer, progressIntervalInMs, rotate, apiKey, resize, onAudioCodec, onContainer, onDimensions, onDurationInSeconds, onFps, onImages, onInternalStats, onIsHdr, onKeyframes, onLocation, onMetadata, onMimeType, onName, onNumberOfAudioChannels, onRotation, onSampleRate, onSize, onSlowAudioBitrate, onSlowDurationInSeconds, onSlowFps, onSlowKeyframes, onSlowNumberOfFrames, onSlowVideoBitrate, onStructure, onTracks, onUnrotatedDimensions, onVideoCodec, onM3uStreams, selectM3uStream, selectM3uAssociatedPlaylists, expectedDurationInSeconds, ...more }: {
39
39
  src: ParseMediaOptions<F>["src"];
40
40
  container: ConvertMediaContainer;
41
41
  onVideoFrame?: ConvertMediaOnVideoFrame;
@@ -48,6 +48,7 @@ export declare const convertMedia: <F extends Options<ParseMediaFields>>({ src,
48
48
  onVideoTrack?: ConvertMediaOnVideoTrackHandler;
49
49
  selectM3uStream?: ParseMediaOptions<F>["selectM3uStream"];
50
50
  selectM3uAssociatedPlaylists?: ParseMediaOptions<F>["selectM3uAssociatedPlaylists"];
51
+ expectedDurationInSeconds?: number | null;
51
52
  reader?: ParseMediaOptions<F>["reader"];
52
53
  logLevel?: LogLevel;
53
54
  writer?: WriterInterface;
@@ -6,7 +6,7 @@
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  exports.convertMedia = void 0;
8
8
  const media_parser_1 = require("@remotion/media-parser");
9
- const fetch_1 = require("@remotion/media-parser/fetch");
9
+ const web_1 = require("@remotion/media-parser/web");
10
10
  const auto_select_writer_1 = require("./auto-select-writer");
11
11
  const calculate_progress_1 = require("./calculate-progress");
12
12
  const progress_tracker_1 = require("./create/progress-tracker");
@@ -21,8 +21,7 @@ const select_container_creator_1 = require("./select-container-creator");
21
21
  const send_telemetry_event_1 = require("./send-telemetry-event");
22
22
  const throttled_state_update_1 = require("./throttled-state-update");
23
23
  const webcodecs_controller_1 = require("./webcodecs-controller");
24
- const convertMedia = async function ({ src, onVideoFrame, onAudioData, onProgress: onProgressDoNotCallDirectly, audioCodec, container, videoCodec, controller = (0, webcodecs_controller_1.webcodecsController)(), onAudioTrack: userAudioResolver, onVideoTrack: userVideoResolver, reader, fields, logLevel = 'info', writer, progressIntervalInMs, rotate, apiKey, resize, onAudioCodec, onContainer, onDimensions, onDurationInSeconds, onFps, onImages, onInternalStats, onIsHdr, onKeyframes, onLocation, onMetadata, onMimeType, onName, onNumberOfAudioChannels, onRotation, onSampleRate, onSize, onSlowAudioBitrate, onSlowDurationInSeconds, onSlowFps, onSlowKeyframes, onSlowNumberOfFrames, onSlowVideoBitrate, onStructure, onTracks, onUnrotatedDimensions, onVideoCodec, onM3uStreams, selectM3uStream, selectM3uAssociatedPlaylists, ...more }) {
25
- var _a, _b;
24
+ const convertMedia = async function ({ src, onVideoFrame, onAudioData, onProgress: onProgressDoNotCallDirectly, audioCodec, container, videoCodec, controller = (0, webcodecs_controller_1.webcodecsController)(), onAudioTrack: userAudioResolver, onVideoTrack: userVideoResolver, reader, fields, logLevel = 'info', writer, progressIntervalInMs, rotate, apiKey, resize, onAudioCodec, onContainer, onDimensions, onDurationInSeconds, onFps, onImages, onInternalStats, onIsHdr, onKeyframes, onLocation, onMetadata, onMimeType, onName, onNumberOfAudioChannels, onRotation, onSampleRate, onSize, onSlowAudioBitrate, onSlowDurationInSeconds, onSlowFps, onSlowKeyframes, onSlowNumberOfFrames, onSlowVideoBitrate, onStructure, onTracks, onUnrotatedDimensions, onVideoCodec, onM3uStreams, selectM3uStream, selectM3uAssociatedPlaylists, expectedDurationInSeconds, ...more }) {
26
25
  if (controller._internals.signal.aborted) {
27
26
  return Promise.reject(new media_parser_1.MediaParserAbortError('Aborted'));
28
27
  }
@@ -45,8 +44,8 @@ const convertMedia = async function ({ src, onVideoFrame, onAudioData, onProgres
45
44
  controller._internals.signal.addEventListener('abort', onUserAbort);
46
45
  const creator = (0, select_container_creator_1.selectContainerCreator)(container);
47
46
  const throttledState = (0, throttled_state_update_1.throttledStateUpdate)({
48
- updateFn: onProgressDoNotCallDirectly !== null && onProgressDoNotCallDirectly !== void 0 ? onProgressDoNotCallDirectly : null,
49
- everyMilliseconds: progressIntervalInMs !== null && progressIntervalInMs !== void 0 ? progressIntervalInMs : 100,
47
+ updateFn: onProgressDoNotCallDirectly ?? null,
48
+ everyMilliseconds: progressIntervalInMs ?? 100,
50
49
  signal: controller._internals.signal,
51
50
  });
52
51
  const progressTracker = (0, progress_tracker_1.makeProgressTracker)();
@@ -54,8 +53,7 @@ const convertMedia = async function ({ src, onVideoFrame, onAudioData, onProgres
54
53
  filename: (0, generate_output_filename_1.generateOutputFilename)(src, container),
55
54
  writer: await (0, auto_select_writer_1.autoSelectWriter)(writer, logLevel),
56
55
  onBytesProgress: (bytesWritten) => {
57
- var _a;
58
- (_a = throttledState.update) === null || _a === void 0 ? void 0 : _a.call(throttledState, (prevState) => {
56
+ throttledState.update?.((prevState) => {
59
57
  return {
60
58
  ...prevState,
61
59
  bytesWritten,
@@ -63,8 +61,7 @@ const convertMedia = async function ({ src, onVideoFrame, onAudioData, onProgres
63
61
  });
64
62
  },
65
63
  onMillisecondsProgress: (millisecondsWritten) => {
66
- var _a;
67
- (_a = throttledState.update) === null || _a === void 0 ? void 0 : _a.call(throttledState, (prevState) => {
64
+ throttledState.update?.((prevState) => {
68
65
  if (millisecondsWritten > prevState.millisecondsWritten) {
69
66
  return {
70
67
  ...prevState,
@@ -80,32 +77,33 @@ const convertMedia = async function ({ src, onVideoFrame, onAudioData, onProgres
80
77
  },
81
78
  logLevel,
82
79
  progressTracker,
80
+ expectedDurationInSeconds: expectedDurationInSeconds ?? null,
83
81
  });
84
82
  const onVideoTrack = (0, on_video_track_1.makeVideoTrackHandler)({
85
83
  state,
86
- onVideoFrame: onVideoFrame !== null && onVideoFrame !== void 0 ? onVideoFrame : null,
87
- onMediaStateUpdate: (_a = throttledState.update) !== null && _a !== void 0 ? _a : null,
84
+ onVideoFrame: onVideoFrame ?? null,
85
+ onMediaStateUpdate: throttledState.update ?? null,
88
86
  abortConversion,
89
87
  controller,
90
- defaultVideoCodec: videoCodec !== null && videoCodec !== void 0 ? videoCodec : null,
91
- onVideoTrack: userVideoResolver !== null && userVideoResolver !== void 0 ? userVideoResolver : null,
88
+ defaultVideoCodec: videoCodec ?? null,
89
+ onVideoTrack: userVideoResolver ?? null,
92
90
  logLevel,
93
91
  outputContainer: container,
94
- rotate: rotate !== null && rotate !== void 0 ? rotate : 0,
92
+ rotate: rotate ?? 0,
95
93
  progress: progressTracker,
96
- resizeOperation: resize !== null && resize !== void 0 ? resize : null,
94
+ resizeOperation: resize ?? null,
97
95
  });
98
96
  const onAudioTrack = (0, on_audio_track_1.makeAudioTrackHandler)({
99
97
  abortConversion,
100
- defaultAudioCodec: audioCodec !== null && audioCodec !== void 0 ? audioCodec : null,
98
+ defaultAudioCodec: audioCodec ?? null,
101
99
  controller,
102
- onMediaStateUpdate: (_b = throttledState.update) !== null && _b !== void 0 ? _b : null,
100
+ onMediaStateUpdate: throttledState.update ?? null,
103
101
  state,
104
- onAudioTrack: userAudioResolver !== null && userAudioResolver !== void 0 ? userAudioResolver : null,
102
+ onAudioTrack: userAudioResolver ?? null,
105
103
  logLevel,
106
104
  outputContainer: container,
107
105
  progressTracker,
108
- onAudioData: onAudioData !== null && onAudioData !== void 0 ? onAudioData : null,
106
+ onAudioData: onAudioData ?? null,
109
107
  });
110
108
  media_parser_1.MediaParserInternals.internalParseMedia({
111
109
  logLevel,
@@ -117,10 +115,9 @@ const convertMedia = async function ({ src, onVideoFrame, onAudioData, onProgres
117
115
  ...fields,
118
116
  durationInSeconds: true,
119
117
  },
120
- reader: reader !== null && reader !== void 0 ? reader : fetch_1.fetchReader,
118
+ reader: reader ?? web_1.webReader,
121
119
  ...more,
122
120
  onDurationInSeconds: (durationInSeconds) => {
123
- var _a;
124
121
  if (durationInSeconds === null) {
125
122
  return null;
126
123
  }
@@ -129,7 +126,7 @@ const convertMedia = async function ({ src, onVideoFrame, onAudioData, onProgres
129
126
  casted.onDurationInSeconds(durationInSeconds);
130
127
  }
131
128
  const expectedOutputDurationInMs = durationInSeconds * 1000;
132
- (_a = throttledState.update) === null || _a === void 0 ? void 0 : _a.call(throttledState, (prevState) => {
129
+ throttledState.update?.((prevState) => {
133
130
  return {
134
131
  ...prevState,
135
132
  expectedOutputDurationInMs,
@@ -146,36 +143,37 @@ const convertMedia = async function ({ src, onVideoFrame, onAudioData, onProgres
146
143
  onError: () => ({ action: 'fail' }),
147
144
  onParseProgress: null,
148
145
  progressIntervalInMs: null,
149
- onAudioCodec: onAudioCodec !== null && onAudioCodec !== void 0 ? onAudioCodec : null,
150
- onContainer: onContainer !== null && onContainer !== void 0 ? onContainer : null,
151
- onDimensions: onDimensions !== null && onDimensions !== void 0 ? onDimensions : null,
152
- onFps: onFps !== null && onFps !== void 0 ? onFps : null,
153
- onImages: onImages !== null && onImages !== void 0 ? onImages : null,
154
- onInternalStats: onInternalStats !== null && onInternalStats !== void 0 ? onInternalStats : null,
155
- onIsHdr: onIsHdr !== null && onIsHdr !== void 0 ? onIsHdr : null,
156
- onKeyframes: onKeyframes !== null && onKeyframes !== void 0 ? onKeyframes : null,
157
- onLocation: onLocation !== null && onLocation !== void 0 ? onLocation : null,
158
- onMetadata: onMetadata !== null && onMetadata !== void 0 ? onMetadata : null,
159
- onMimeType: onMimeType !== null && onMimeType !== void 0 ? onMimeType : null,
160
- onName: onName !== null && onName !== void 0 ? onName : null,
161
- onNumberOfAudioChannels: onNumberOfAudioChannels !== null && onNumberOfAudioChannels !== void 0 ? onNumberOfAudioChannels : null,
162
- onRotation: onRotation !== null && onRotation !== void 0 ? onRotation : null,
163
- onSampleRate: onSampleRate !== null && onSampleRate !== void 0 ? onSampleRate : null,
164
- onSize: onSize !== null && onSize !== void 0 ? onSize : null,
165
- onSlowAudioBitrate: onSlowAudioBitrate !== null && onSlowAudioBitrate !== void 0 ? onSlowAudioBitrate : null,
166
- onSlowDurationInSeconds: onSlowDurationInSeconds !== null && onSlowDurationInSeconds !== void 0 ? onSlowDurationInSeconds : null,
167
- onSlowFps: onSlowFps !== null && onSlowFps !== void 0 ? onSlowFps : null,
168
- onSlowKeyframes: onSlowKeyframes !== null && onSlowKeyframes !== void 0 ? onSlowKeyframes : null,
169
- onSlowNumberOfFrames: onSlowNumberOfFrames !== null && onSlowNumberOfFrames !== void 0 ? onSlowNumberOfFrames : null,
170
- onSlowVideoBitrate: onSlowVideoBitrate !== null && onSlowVideoBitrate !== void 0 ? onSlowVideoBitrate : null,
171
- onStructure: onStructure !== null && onStructure !== void 0 ? onStructure : null,
172
- onTracks: onTracks !== null && onTracks !== void 0 ? onTracks : null,
173
- onUnrotatedDimensions: onUnrotatedDimensions !== null && onUnrotatedDimensions !== void 0 ? onUnrotatedDimensions : null,
174
- onVideoCodec: onVideoCodec !== null && onVideoCodec !== void 0 ? onVideoCodec : null,
146
+ onAudioCodec: onAudioCodec ?? null,
147
+ onContainer: onContainer ?? null,
148
+ onDimensions: onDimensions ?? null,
149
+ onFps: onFps ?? null,
150
+ onImages: onImages ?? null,
151
+ onInternalStats: onInternalStats ?? null,
152
+ onIsHdr: onIsHdr ?? null,
153
+ onKeyframes: onKeyframes ?? null,
154
+ onLocation: onLocation ?? null,
155
+ onMetadata: onMetadata ?? null,
156
+ onMimeType: onMimeType ?? null,
157
+ onName: onName ?? null,
158
+ onNumberOfAudioChannels: onNumberOfAudioChannels ?? null,
159
+ onRotation: onRotation ?? null,
160
+ onSampleRate: onSampleRate ?? null,
161
+ onSize: onSize ?? null,
162
+ onSlowAudioBitrate: onSlowAudioBitrate ?? null,
163
+ onSlowDurationInSeconds: onSlowDurationInSeconds ?? null,
164
+ onSlowFps: onSlowFps ?? null,
165
+ onSlowKeyframes: onSlowKeyframes ?? null,
166
+ onSlowNumberOfFrames: onSlowNumberOfFrames ?? null,
167
+ onSlowVideoBitrate: onSlowVideoBitrate ?? null,
168
+ onStructure: onStructure ?? null,
169
+ onTracks: onTracks ?? null,
170
+ onUnrotatedDimensions: onUnrotatedDimensions ?? null,
171
+ onVideoCodec: onVideoCodec ?? null,
175
172
  apiName: 'convertMedia()',
176
- onM3uStreams: onM3uStreams !== null && onM3uStreams !== void 0 ? onM3uStreams : null,
177
- selectM3uStream: selectM3uStream !== null && selectM3uStream !== void 0 ? selectM3uStream : media_parser_1.defaultSelectM3uStreamFn,
178
- selectM3uAssociatedPlaylists: selectM3uAssociatedPlaylists !== null && selectM3uAssociatedPlaylists !== void 0 ? selectM3uAssociatedPlaylists : media_parser_1.defaultSelectM3uAssociatedPlaylists,
173
+ onM3uStreams: onM3uStreams ?? null,
174
+ selectM3uStream: selectM3uStream ?? media_parser_1.defaultSelectM3uStreamFn,
175
+ selectM3uAssociatedPlaylists: selectM3uAssociatedPlaylists ?? media_parser_1.defaultSelectM3uAssociatedPlaylists,
176
+ mp4HeaderSegment: null,
179
177
  })
180
178
  .then(() => {
181
179
  return state.waitForFinish();
@@ -188,12 +186,12 @@ const convertMedia = async function ({ src, onVideoFrame, onAudioData, onProgres
188
186
  });
189
187
  })
190
188
  .then(() => {
191
- (0, send_telemetry_event_1.sendUsageEvent)({ succeeded: true, apiKey: apiKey !== null && apiKey !== void 0 ? apiKey : null }).catch((err) => {
189
+ (0, send_telemetry_event_1.sendUsageEvent)({ succeeded: true, apiKey: apiKey ?? null }).catch((err) => {
192
190
  log_1.Log.error('Failed to send usage event', err);
193
191
  });
194
192
  })
195
193
  .catch((err) => {
196
- (0, send_telemetry_event_1.sendUsageEvent)({ succeeded: false, apiKey: apiKey !== null && apiKey !== void 0 ? apiKey : null }).catch((err2) => {
194
+ (0, send_telemetry_event_1.sendUsageEvent)({ succeeded: false, apiKey: apiKey ?? null }).catch((err2) => {
197
195
  log_1.Log.error('Failed to send usage event', err2);
198
196
  });
199
197
  reject(err);
@@ -1,2 +1,2 @@
1
1
  import type { MediaFn, MediaFnGeneratorInput } from '../media-fn';
2
- export declare const createIsoBaseMedia: ({ writer, onBytesProgress, onMillisecondsProgress, logLevel, filename, progressTracker, }: MediaFnGeneratorInput) => Promise<MediaFn>;
2
+ export declare const createIsoBaseMedia: ({ writer, onBytesProgress, onMillisecondsProgress, logLevel, filename, progressTracker, expectedDurationInSeconds, }: MediaFnGeneratorInput) => Promise<MediaFn>;
@@ -7,7 +7,7 @@ const create_ftyp_1 = require("./create-ftyp");
7
7
  const mp4_header_1 = require("./mp4-header");
8
8
  const primitives_1 = require("./primitives");
9
9
  const CONTAINER_TIMESCALE = 1000;
10
- const createIsoBaseMedia = async ({ writer, onBytesProgress, onMillisecondsProgress, logLevel, filename, progressTracker, }) => {
10
+ const createIsoBaseMedia = async ({ writer, onBytesProgress, onMillisecondsProgress, logLevel, filename, progressTracker, expectedDurationInSeconds, }) => {
11
11
  const header = (0, create_ftyp_1.createIsoBaseMediaFtyp)({
12
12
  compatibleBrands: ['isom', 'iso2', 'avc1', 'mp42'],
13
13
  majorBrand: 'isom',
@@ -30,15 +30,16 @@ const createIsoBaseMedia = async ({ writer, onBytesProgress, onMillisecondsProgr
30
30
  return (0, mp4_header_1.createPaddedMoovAtom)({
31
31
  durationInUnits: globalDurationInUnits,
32
32
  trackInfo: currentTracks.map((track) => {
33
- var _a, _b;
34
33
  return {
35
34
  track,
36
- durationInUnits: (_a = trackDurations[track.trackNumber]) !== null && _a !== void 0 ? _a : 0,
37
- samplePositions: (_b = samplePositions[track.trackNumber]) !== null && _b !== void 0 ? _b : [],
35
+ durationInUnits: trackDurations[track.trackNumber] ?? 0,
36
+ samplePositions: samplePositions[track.trackNumber] ?? [],
38
37
  timescale: track.timescale,
39
38
  };
40
39
  }),
41
40
  timescale: CONTAINER_TIMESCALE,
41
+ expectedDurationInSeconds,
42
+ logLevel,
42
43
  });
43
44
  };
44
45
  await w.write(getPaddedMoovAtom());
@@ -68,12 +69,11 @@ const createIsoBaseMedia = async ({ writer, onBytesProgress, onMillisecondsProgr
68
69
  };
69
70
  let lastChunkWasVideo = false;
70
71
  const addSample = async ({ chunk, trackNumber, isVideo, codecPrivate, }) => {
71
- var _a, _b, _c, _d;
72
72
  const position = w.getWrittenByteCount();
73
73
  await w.write(chunk.data);
74
74
  mdatSize += chunk.data.length;
75
75
  onBytesProgress(w.getWrittenByteCount());
76
- progressTracker.setPossibleLowestTimestamp(Math.min(chunk.timestamp, (_a = chunk.cts) !== null && _a !== void 0 ? _a : Infinity, (_b = chunk.dts) !== null && _b !== void 0 ? _b : Infinity));
76
+ progressTracker.setPossibleLowestTimestamp(Math.min(chunk.timestamp, chunk.cts ?? Infinity, chunk.dts ?? Infinity));
77
77
  progressTracker.updateTrackProgress(trackNumber, chunk.timestamp);
78
78
  if (codecPrivate) {
79
79
  addCodecPrivateToTrack({ trackNumber, codecPrivate });
@@ -90,7 +90,7 @@ const createIsoBaseMedia = async ({ writer, onBytesProgress, onMillisecondsProgr
90
90
  throw new Error(`Tried to add sample to track ${trackNumber}, but it has no timestamp`);
91
91
  }
92
92
  const newDurationInMicroSeconds = chunk.timestamp +
93
- ((_c = chunk.duration) !== null && _c !== void 0 ? _c : 0) -
93
+ (chunk.duration ?? 0) -
94
94
  lowestTrackTimestamps[trackNumber];
95
95
  const newDurationInTrackTimeUnits = Math.round(newDurationInMicroSeconds / (1000000 / currentTrack.timescale));
96
96
  trackDurations[trackNumber] = newDurationInTrackTimeUnits;
@@ -125,7 +125,7 @@ const createIsoBaseMedia = async ({ writer, onBytesProgress, onMillisecondsProgr
125
125
  chunk: sampleChunkIndices[trackNumber],
126
126
  cts: Math.round((chunk.cts / 1000000) * currentTrack.timescale),
127
127
  dts: Math.round((chunk.dts / 1000000) * currentTrack.timescale),
128
- duration: Math.round((((_d = chunk.duration) !== null && _d !== void 0 ? _d : 0) / 1000000) * currentTrack.timescale),
128
+ duration: Math.round(((chunk.duration ?? 0) / 1000000) * currentTrack.timescale),
129
129
  size: chunk.data.length,
130
130
  };
131
131
  lastChunkWasVideo = isVideo;
@@ -0,0 +1 @@
1
+ export declare const calculateAReasonableMp4HeaderLength: (expectedDurationInSeconds: number | null) => number;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.calculateAReasonableMp4HeaderLength = void 0;
4
+ const calculateAReasonableMp4HeaderLength = (expectedDurationInSeconds) => {
5
+ if (expectedDurationInSeconds === null) {
6
+ return 2048000;
7
+ }
8
+ /**
9
+ * we had a video that was 1 hour 40 minutes long and the header ended up being 3.7MB. the header approximately grows linearly to the video length in seconds, but we should reserve enough, like at least 50KB in any case.
10
+ * it's better to be safe than to fail, so let's add a 30% safety margin
11
+ */
12
+ // 1h40m = 6000 seconds resulted in 3.7MB header
13
+ // So bytes per second = 3.7MB / 6000 = ~616 bytes/second
14
+ const bytesPerSecond = (3.7 * 1024 * 1024) / 6000;
15
+ // Add 20% safety margin
16
+ const bytesWithSafetyMargin = bytesPerSecond * 1.2;
17
+ // Calculate based on duration, with minimum 50KB
18
+ const calculatedBytes = Math.max(50 * 1024, Math.ceil(expectedDurationInSeconds * bytesWithSafetyMargin));
19
+ return calculatedBytes;
20
+ };
21
+ exports.calculateAReasonableMp4HeaderLength = calculateAReasonableMp4HeaderLength;
@@ -1,6 +1,9 @@
1
+ import type { LogLevel } from '@remotion/media-parser';
1
2
  import type { IsoBaseMediaTrackData } from './serialize-track';
2
- export declare const createPaddedMoovAtom: ({ durationInUnits, trackInfo, timescale, }: {
3
+ export declare const createPaddedMoovAtom: ({ durationInUnits, trackInfo, timescale, expectedDurationInSeconds, logLevel, }: {
3
4
  durationInUnits: number;
4
5
  trackInfo: IsoBaseMediaTrackData[];
5
6
  timescale: number;
7
+ expectedDurationInSeconds: number | null;
8
+ logLevel: LogLevel;
6
9
  }) => Uint8Array;
@@ -2,19 +2,26 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createPaddedMoovAtom = void 0;
4
4
  const media_parser_1 = require("@remotion/media-parser");
5
+ const log_1 = require("../../log");
5
6
  const create_ilst_1 = require("./create-ilst");
6
7
  const create_moov_1 = require("./create-moov");
7
8
  const create_mvhd_1 = require("./create-mvhd");
8
9
  const create_udta_1 = require("./create-udta");
10
+ const header_length_1 = require("./header-length");
9
11
  const create_cmt_1 = require("./ilst/create-cmt");
10
12
  const create_too_1 = require("./ilst/create-too");
11
13
  const primitives_1 = require("./primitives");
12
14
  const serialize_track_1 = require("./serialize-track");
13
15
  const create_meta_1 = require("./udta/create-meta");
14
16
  const create_hdlr_1 = require("./udta/meta/create-hdlr");
15
- // TODO: Creates a header that is way too large
16
- const HEADER_LENGTH = 2048000;
17
- const createPaddedMoovAtom = ({ durationInUnits, trackInfo, timescale, }) => {
17
+ const createPaddedMoovAtom = ({ durationInUnits, trackInfo, timescale, expectedDurationInSeconds, logLevel, }) => {
18
+ const headerLength = (0, header_length_1.calculateAReasonableMp4HeaderLength)(expectedDurationInSeconds);
19
+ if (expectedDurationInSeconds !== null) {
20
+ log_1.Log.verbose(logLevel, `Expecting duration of the video to be ${expectedDurationInSeconds} seconds, allocating ${headerLength} bytes for the MP4 header.`);
21
+ }
22
+ else {
23
+ log_1.Log.verbose(logLevel, `No duration was provided, allocating ${headerLength} bytes for the MP4 header.`);
24
+ }
18
25
  return (0, primitives_1.padIsoBaseMediaBytes)((0, create_moov_1.createMoov)({
19
26
  mvhd: (0, create_mvhd_1.createMvhd)({
20
27
  timescale,
@@ -43,6 +50,6 @@ const createPaddedMoovAtom = ({ durationInUnits, trackInfo, timescale, }) => {
43
50
  (0, create_cmt_1.createCmt)(`Made with @remotion/webcodecs ${media_parser_1.VERSION}`),
44
51
  ]),
45
52
  })),
46
- }), HEADER_LENGTH);
53
+ }), headerLength);
47
54
  };
48
55
  exports.createPaddedMoovAtom = createPaddedMoovAtom;
@@ -1,5 +1,6 @@
1
1
  export declare const stringsToUint8Array: (str: string) => Uint8Array;
2
2
  export declare const numberTo32BitUIntOrInt: (num: number) => Uint8Array;
3
+ export declare const numberTo64BitUIntOrInt: (num: number | bigint) => Uint8Array;
3
4
  export declare const numberTo32BitUIntOrIntLeading128: (num: number) => Uint8Array;
4
5
  export declare const numberTo16BitUIntOrInt: (num: number) => Uint8Array;
5
6
  export declare const setFixedPointSignedOrUnsigned1616Number: (num: number) => Uint8Array;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.IDENTITY_MATRIX = exports.padIsoBaseMediaBytes = exports.stringToPascalString = exports.serializeMatrix = exports.floatTo16Point16_16Bit = exports.floatTo16Point1632Bit = exports.addLeading128Size = exports.addSize = exports.setFixedPointSigned230Number = exports.setFixedPointSignedOrUnsigned1616Number = exports.numberTo16BitUIntOrInt = exports.numberTo32BitUIntOrIntLeading128 = exports.numberTo32BitUIntOrInt = exports.stringsToUint8Array = void 0;
3
+ exports.IDENTITY_MATRIX = exports.padIsoBaseMediaBytes = exports.stringToPascalString = exports.serializeMatrix = exports.floatTo16Point16_16Bit = exports.floatTo16Point1632Bit = exports.addLeading128Size = exports.addSize = exports.setFixedPointSigned230Number = exports.setFixedPointSignedOrUnsigned1616Number = exports.numberTo16BitUIntOrInt = exports.numberTo32BitUIntOrIntLeading128 = exports.numberTo64BitUIntOrInt = exports.numberTo32BitUIntOrInt = exports.stringsToUint8Array = void 0;
4
4
  const matroska_utils_1 = require("../matroska/matroska-utils");
5
5
  const stringsToUint8Array = (str) => {
6
6
  return new TextEncoder().encode(str);
@@ -15,6 +15,20 @@ const numberTo32BitUIntOrInt = (num) => {
15
15
  ]);
16
16
  };
17
17
  exports.numberTo32BitUIntOrInt = numberTo32BitUIntOrInt;
18
+ const numberTo64BitUIntOrInt = (num) => {
19
+ const bigNum = BigInt(num);
20
+ return new Uint8Array([
21
+ Number((bigNum >> 56n) & 0xffn),
22
+ Number((bigNum >> 48n) & 0xffn),
23
+ Number((bigNum >> 40n) & 0xffn),
24
+ Number((bigNum >> 32n) & 0xffn),
25
+ Number((bigNum >> 24n) & 0xffn),
26
+ Number((bigNum >> 16n) & 0xffn),
27
+ Number((bigNum >> 8n) & 0xffn),
28
+ Number(bigNum & 0xffn),
29
+ ]);
30
+ };
31
+ exports.numberTo64BitUIntOrInt = numberTo64BitUIntOrInt;
18
32
  const numberTo32BitUIntOrIntLeading128 = (num) => {
19
33
  const arr = [
20
34
  (num >> 24) & 0xff,
@@ -116,7 +130,7 @@ const stringToPascalString = (str) => {
116
130
  exports.stringToPascalString = stringToPascalString;
117
131
  const padIsoBaseMediaBytes = (data, totalLength) => {
118
132
  if (data.length - 8 > totalLength) {
119
- throw new Error(`Data is longer than the total length: ${data.length - 8} > ${totalLength}`);
133
+ throw new Error(`Data is longer than the total length: ${data.length - 8} > ${totalLength}. Set the 'expectedDurationInSeconds' value to avoid this problem: https://www.remotion.dev/docs/webcodecs/convert-media#expecteddurationinseconds`);
120
134
  }
121
135
  if (data.length - 8 === totalLength) {
122
136
  return data;
@@ -6,15 +6,19 @@ const primitives_1 = require("../../../../primitives");
6
6
  const createStcoAtom = (samplePositions) => {
7
7
  const chunkOffsets = [];
8
8
  let lastChunk;
9
+ let needs64Bit = false;
9
10
  for (const sample of samplePositions) {
10
11
  if (lastChunk !== sample.chunk) {
11
12
  chunkOffsets.push(sample.offset);
12
13
  }
14
+ if (sample.offset > 2 ** 32) {
15
+ needs64Bit = true;
16
+ }
13
17
  lastChunk = sample.chunk;
14
18
  }
15
19
  return (0, primitives_1.addSize)((0, matroska_utils_1.combineUint8Arrays)([
16
20
  // type
17
- (0, primitives_1.stringsToUint8Array)('stco'),
21
+ (0, primitives_1.stringsToUint8Array)(needs64Bit ? 'co64' : 'stco'),
18
22
  // version
19
23
  new Uint8Array([0]),
20
24
  // flags
@@ -22,7 +26,9 @@ const createStcoAtom = (samplePositions) => {
22
26
  // number of entries
23
27
  (0, primitives_1.numberTo32BitUIntOrInt)(chunkOffsets.length),
24
28
  // chunk offsets
25
- ...chunkOffsets.map((offset) => (0, primitives_1.numberTo32BitUIntOrInt)(offset)),
29
+ (0, matroska_utils_1.combineUint8Arrays)(chunkOffsets.map((offset) => needs64Bit
30
+ ? (0, primitives_1.numberTo64BitUIntOrInt)(offset)
31
+ : (0, primitives_1.numberTo32BitUIntOrInt)(offset))),
26
32
  ]));
27
33
  };
28
34
  exports.createStcoAtom = createStcoAtom;
@@ -15,11 +15,10 @@ const makeEntry = (entry) => {
15
15
  const createSttsAtom = (samplePositions) => {
16
16
  let lastDuration = null;
17
17
  const durations = samplePositions.map((_, i, a) => {
18
- var _a, _b;
19
18
  // TODO: Why does 0 appear here?
20
19
  if (a[i].duration === undefined || a[i].duration === 0) {
21
20
  if (a[i + 1] === undefined) {
22
- return a[i].dts - ((_b = (_a = a[i - 1]) === null || _a === void 0 ? void 0 : _a.dts) !== null && _b !== void 0 ? _b : a[i].dts);
21
+ return a[i].dts - (a[i - 1]?.dts ?? a[i].dts);
23
22
  }
24
23
  return a[i + 1].dts - a[i].dts;
25
24
  }
@@ -14,7 +14,6 @@ const matroska_utils_1 = require("./matroska-utils");
14
14
  const { matroskaElements } = media_parser_1.MediaParserInternals;
15
15
  const timescale = 1000000;
16
16
  const createMatroskaMedia = async ({ writer, onBytesProgress, onMillisecondsProgress, filename, logLevel, progressTracker, }) => {
17
- var _a, _b, _c, _d, _e, _f, _g;
18
17
  const header = (0, matroska_header_1.makeMatroskaHeader)();
19
18
  const w = await writer.createContent({
20
19
  filename,
@@ -35,11 +34,13 @@ const createMatroskaMedia = async ({ writer, onBytesProgress, onMillisecondsProg
35
34
  ...(0, matroska_trackentry_1.makeMatroskaTracks)(currentTracks),
36
35
  ]);
37
36
  const infoSegment = matroskaSegment.offsets.children.find((o) => o.field === 'Info');
38
- const durationOffset = ((_b = (_a = infoSegment === null || infoSegment === void 0 ? void 0 : infoSegment.children.find((c) => c.field === 'Duration')) === null || _a === void 0 ? void 0 : _a.offset) !== null && _b !== void 0 ? _b : 0) +
37
+ const durationOffset = (infoSegment?.children.find((c) => c.field === 'Duration')?.offset ?? 0) +
39
38
  w.getWrittenByteCount();
40
- const tracksOffset = ((_d = (_c = matroskaSegment.offsets.children.find((o) => o.field === 'Tracks')) === null || _c === void 0 ? void 0 : _c.offset) !== null && _d !== void 0 ? _d : 0) + w.getWrittenByteCount();
41
- const seekHeadOffset = ((_f = (_e = matroskaSegment.offsets.children.find((o) => o.field === 'SeekHead')) === null || _e === void 0 ? void 0 : _e.offset) !== null && _f !== void 0 ? _f : 0) + w.getWrittenByteCount();
42
- const infoOffset = ((_g = infoSegment === null || infoSegment === void 0 ? void 0 : infoSegment.offset) !== null && _g !== void 0 ? _g : 0) + w.getWrittenByteCount();
39
+ const tracksOffset = (matroskaSegment.offsets.children.find((o) => o.field === 'Tracks')
40
+ ?.offset ?? 0) + w.getWrittenByteCount();
41
+ const seekHeadOffset = (matroskaSegment.offsets.children.find((o) => o.field === 'SeekHead')
42
+ ?.offset ?? 0) + w.getWrittenByteCount();
43
+ const infoOffset = (infoSegment?.offset ?? 0) + w.getWrittenByteCount();
43
44
  if (!seekHeadOffset) {
44
45
  throw new Error('could not get seek offset');
45
46
  }
@@ -87,8 +88,7 @@ const createMatroskaMedia = async ({ writer, onBytesProgress, onMillisecondsProg
87
88
  // In Safari, samples can arrive out of order, e.g public/bigbuckbunny.mp4
88
89
  // Therefore, only updating track number progress if it is a keyframe
89
90
  // to allow for timestamps to be lower than the previous one
90
- var _a, _b;
91
- progressTracker.setPossibleLowestTimestamp(Math.min(chunk.timestamp, (_a = chunk.cts) !== null && _a !== void 0 ? _a : Infinity, (_b = chunk.dts) !== null && _b !== void 0 ? _b : Infinity));
91
+ progressTracker.setPossibleLowestTimestamp(Math.min(chunk.timestamp, chunk.cts ?? Infinity, chunk.dts ?? Infinity));
92
92
  const smallestProgress = progressTracker.getSmallestProgress();
93
93
  if (!currentCluster.shouldMakeNewCluster({
94
94
  newT: smallestProgress,
@@ -111,12 +111,11 @@ const createMatroskaMedia = async ({ writer, onBytesProgress, onMillisecondsProg
111
111
  onBytesProgress(w.getWrittenByteCount());
112
112
  };
113
113
  const addSample = async ({ chunk, trackNumber, isVideo, }) => {
114
- var _a;
115
114
  const { cluster, isNew, smallestProgress } = await getClusterOrMakeNew({
116
115
  chunk,
117
116
  isVideo,
118
117
  });
119
- const newDuration = Math.round((chunk.timestamp + ((_a = chunk.duration) !== null && _a !== void 0 ? _a : 0)) / 1000);
118
+ const newDuration = Math.round((chunk.timestamp + (chunk.duration ?? 0)) / 1000);
120
119
  await updateDuration(newDuration);
121
120
  const { timecodeRelativeToCluster } = await cluster.addSample(chunk, trackNumber);
122
121
  if (isNew) {
@@ -4,8 +4,7 @@ exports.padMatroskaBytes = exports.makeMatroskaBytes = exports.getVariableInt =
4
4
  exports.serializeUint16 = serializeUint16;
5
5
  const media_parser_1 = require("@remotion/media-parser");
6
6
  const getIdForName = (name) => {
7
- var _a;
8
- const value = (_a = Object.entries(media_parser_1.MediaParserInternals.matroskaElements).find(([key]) => key === name)) === null || _a === void 0 ? void 0 : _a[1];
7
+ const value = Object.entries(media_parser_1.MediaParserInternals.matroskaElements).find(([key]) => key === name)?.[1];
9
8
  if (!value) {
10
9
  throw new Error(`Could not find id for name ${name}`);
11
10
  }
@@ -17,7 +16,7 @@ function putUintDynamic(number, minimumLength) {
17
16
  throw new Error('This function is designed for non-negative integers only.');
18
17
  }
19
18
  // Calculate the minimum number of bytes needed to store the integer
20
- const length = Math.max(minimumLength !== null && minimumLength !== void 0 ? minimumLength : 0, Math.ceil(Math.log2(number + 1) / 8));
19
+ const length = Math.max(minimumLength ?? 0, Math.ceil(Math.log2(number + 1) / 8));
21
20
  const bytes = new Uint8Array(length);
22
21
  for (let i = 0; i < length; i++) {
23
22
  // Extract each byte from the number
@@ -179,7 +178,7 @@ const measureEBMLVarInt = (value) => {
179
178
  };
180
179
  exports.measureEBMLVarInt = measureEBMLVarInt;
181
180
  const getVariableInt = (value, minWidth) => {
182
- const width = Math.max((0, exports.measureEBMLVarInt)(value), minWidth !== null && minWidth !== void 0 ? minWidth : 0);
181
+ const width = Math.max((0, exports.measureEBMLVarInt)(value), minWidth ?? 0);
183
182
  switch (width) {
184
183
  case 1:
185
184
  return new Uint8Array([(1 << 7) | value]);
@@ -28,4 +28,5 @@ export type MediaFnGeneratorInput = {
28
28
  logLevel: LogLevel;
29
29
  filename: string;
30
30
  progressTracker: ProgressTracker;
31
+ expectedDurationInSeconds: number | null;
31
32
  };
@@ -60,10 +60,9 @@ const createWav = async ({ filename, logLevel, onBytesProgress, onMillisecondsPr
60
60
  await w.updateDataAt(blockAlignPosition, new Uint8Array(numberTo16BitLittleEndian(numberOfChannels * BYTES_PER_SAMPLE)));
61
61
  };
62
62
  const addSample = async (chunk) => {
63
- var _a;
64
63
  log_1.Log.trace(logLevel, 'Adding sample', chunk);
65
64
  await w.write(chunk.data);
66
- onMillisecondsProgress((chunk.timestamp + ((_a = chunk.duration) !== null && _a !== void 0 ? _a : 0)) / 1000);
65
+ onMillisecondsProgress((chunk.timestamp + (chunk.duration ?? 0)) / 1000);
67
66
  onBytesProgress(w.getWrittenByteCount());
68
67
  };
69
68
  const waitForFinishPromises = [];
@@ -1434,7 +1434,7 @@ import {
1434
1434
  MediaParserAbortError as MediaParserAbortError3,
1435
1435
  MediaParserInternals as MediaParserInternals9
1436
1436
  } from "@remotion/media-parser";
1437
- import { fetchReader } from "@remotion/media-parser/fetch";
1437
+ import { webReader } from "@remotion/media-parser/web";
1438
1438
 
1439
1439
  // src/auto-select-writer.ts
1440
1440
  var autoSelectWriter = async (writer, logLevel) => {
@@ -1753,7 +1753,7 @@ var makeAudioTrackHandler = ({
1753
1753
  });
1754
1754
  },
1755
1755
  onError: (err) => {
1756
- abortConversion(new Error(`Audio encoder of ${track.trackId} failed (see .cause of this error)`, {
1756
+ abortConversion(new Error(`Audio encoder of track ${track.trackId} failed (see .cause of this error)`, {
1757
1757
  cause: err
1758
1758
  }));
1759
1759
  },
@@ -2659,6 +2659,19 @@ var numberTo32BitUIntOrInt = (num) => {
2659
2659
  num & 255
2660
2660
  ]);
2661
2661
  };
2662
+ var numberTo64BitUIntOrInt = (num) => {
2663
+ const bigNum = BigInt(num);
2664
+ return new Uint8Array([
2665
+ Number(bigNum >> 56n & 0xffn),
2666
+ Number(bigNum >> 48n & 0xffn),
2667
+ Number(bigNum >> 40n & 0xffn),
2668
+ Number(bigNum >> 32n & 0xffn),
2669
+ Number(bigNum >> 24n & 0xffn),
2670
+ Number(bigNum >> 16n & 0xffn),
2671
+ Number(bigNum >> 8n & 0xffn),
2672
+ Number(bigNum & 0xffn)
2673
+ ]);
2674
+ };
2662
2675
  var numberTo32BitUIntOrIntLeading128 = (num) => {
2663
2676
  const arr = [
2664
2677
  num >> 24 & 255,
@@ -2739,7 +2752,7 @@ var stringToPascalString = (str) => {
2739
2752
  };
2740
2753
  var padIsoBaseMediaBytes = (data, totalLength) => {
2741
2754
  if (data.length - 8 > totalLength) {
2742
- throw new Error(`Data is longer than the total length: ${data.length - 8} > ${totalLength}`);
2755
+ throw new Error(`Data is longer than the total length: ${data.length - 8} > ${totalLength}. Set the 'expectedDurationInSeconds' value to avoid this problem: https://www.remotion.dev/docs/webcodecs/convert-media#expecteddurationinseconds`);
2743
2756
  }
2744
2757
  if (data.length - 8 === totalLength) {
2745
2758
  return data;
@@ -2855,6 +2868,17 @@ var createUdta = (children) => {
2855
2868
  ]));
2856
2869
  };
2857
2870
 
2871
+ // src/create/iso-base-media/header-length.ts
2872
+ var calculateAReasonableMp4HeaderLength = (expectedDurationInSeconds) => {
2873
+ if (expectedDurationInSeconds === null) {
2874
+ return 2048000;
2875
+ }
2876
+ const bytesPerSecond = 3.7 * 1024 * 1024 / 6000;
2877
+ const bytesWithSafetyMargin = bytesPerSecond * 1.2;
2878
+ const calculatedBytes = Math.max(50 * 1024, Math.ceil(expectedDurationInSeconds * bytesWithSafetyMargin));
2879
+ return calculatedBytes;
2880
+ };
2881
+
2858
2882
  // src/create/iso-base-media/ilst/create-cmt.ts
2859
2883
  var createCmt = (comment) => {
2860
2884
  return addSize(combineUint8Arrays([
@@ -3279,18 +3303,22 @@ var createCttsBox = (samplePositions) => {
3279
3303
  var createStcoAtom = (samplePositions) => {
3280
3304
  const chunkOffsets = [];
3281
3305
  let lastChunk;
3306
+ let needs64Bit = false;
3282
3307
  for (const sample of samplePositions) {
3283
3308
  if (lastChunk !== sample.chunk) {
3284
3309
  chunkOffsets.push(sample.offset);
3285
3310
  }
3311
+ if (sample.offset > 2 ** 32) {
3312
+ needs64Bit = true;
3313
+ }
3286
3314
  lastChunk = sample.chunk;
3287
3315
  }
3288
3316
  return addSize(combineUint8Arrays([
3289
- stringsToUint8Array("stco"),
3317
+ stringsToUint8Array(needs64Bit ? "co64" : "stco"),
3290
3318
  new Uint8Array([0]),
3291
3319
  new Uint8Array([0, 0, 0]),
3292
3320
  numberTo32BitUIntOrInt(chunkOffsets.length),
3293
- ...chunkOffsets.map((offset) => numberTo32BitUIntOrInt(offset))
3321
+ combineUint8Arrays(chunkOffsets.map((offset) => needs64Bit ? numberTo64BitUIntOrInt(offset) : numberTo32BitUIntOrInt(offset)))
3294
3322
  ]));
3295
3323
  };
3296
3324
 
@@ -3581,12 +3609,19 @@ var createMeta = ({
3581
3609
  };
3582
3610
 
3583
3611
  // src/create/iso-base-media/mp4-header.ts
3584
- var HEADER_LENGTH = 2048000;
3585
3612
  var createPaddedMoovAtom = ({
3586
3613
  durationInUnits,
3587
3614
  trackInfo,
3588
- timescale
3615
+ timescale,
3616
+ expectedDurationInSeconds,
3617
+ logLevel
3589
3618
  }) => {
3619
+ const headerLength = calculateAReasonableMp4HeaderLength(expectedDurationInSeconds);
3620
+ if (expectedDurationInSeconds !== null) {
3621
+ Log.verbose(logLevel, `Expecting duration of the video to be ${expectedDurationInSeconds} seconds, allocating ${headerLength} bytes for the MP4 header.`);
3622
+ } else {
3623
+ Log.verbose(logLevel, `No duration was provided, allocating ${headerLength} bytes for the MP4 header.`);
3624
+ }
3590
3625
  return padIsoBaseMediaBytes(createMoov({
3591
3626
  mvhd: createMvhd({
3592
3627
  timescale,
@@ -3613,7 +3648,7 @@ var createPaddedMoovAtom = ({
3613
3648
  createCmt(`Made with @remotion/webcodecs ${VERSION2}`)
3614
3649
  ])
3615
3650
  }))
3616
- }), HEADER_LENGTH);
3651
+ }), headerLength);
3617
3652
  };
3618
3653
 
3619
3654
  // src/create/iso-base-media/create-iso-base-media.ts
@@ -3624,7 +3659,8 @@ var createIsoBaseMedia = async ({
3624
3659
  onMillisecondsProgress,
3625
3660
  logLevel,
3626
3661
  filename,
3627
- progressTracker
3662
+ progressTracker,
3663
+ expectedDurationInSeconds
3628
3664
  }) => {
3629
3665
  const header = createIsoBaseMediaFtyp({
3630
3666
  compatibleBrands: ["isom", "iso2", "avc1", "mp42"],
@@ -3655,7 +3691,9 @@ var createIsoBaseMedia = async ({
3655
3691
  timescale: track.timescale
3656
3692
  };
3657
3693
  }),
3658
- timescale: CONTAINER_TIMESCALE
3694
+ timescale: CONTAINER_TIMESCALE,
3695
+ expectedDurationInSeconds,
3696
+ logLevel
3659
3697
  });
3660
3698
  };
3661
3699
  await w.write(getPaddedMoovAtom());
@@ -4871,6 +4909,7 @@ var convertMedia = async function({
4871
4909
  onM3uStreams,
4872
4910
  selectM3uStream,
4873
4911
  selectM3uAssociatedPlaylists,
4912
+ expectedDurationInSeconds,
4874
4913
  ...more
4875
4914
  }) {
4876
4915
  if (controller._internals.signal.aborted) {
@@ -4927,7 +4966,8 @@ var convertMedia = async function({
4927
4966
  });
4928
4967
  },
4929
4968
  logLevel,
4930
- progressTracker
4969
+ progressTracker,
4970
+ expectedDurationInSeconds: expectedDurationInSeconds ?? null
4931
4971
  });
4932
4972
  const onVideoTrack = makeVideoTrackHandler({
4933
4973
  state,
@@ -4965,7 +5005,7 @@ var convertMedia = async function({
4965
5005
  ...fields,
4966
5006
  durationInSeconds: true
4967
5007
  },
4968
- reader: reader ?? fetchReader,
5008
+ reader: reader ?? webReader,
4969
5009
  ...more,
4970
5010
  onDurationInSeconds: (durationInSeconds) => {
4971
5011
  if (durationInSeconds === null) {
@@ -5022,7 +5062,8 @@ var convertMedia = async function({
5022
5062
  apiName: "convertMedia()",
5023
5063
  onM3uStreams: onM3uStreams ?? null,
5024
5064
  selectM3uStream: selectM3uStream ?? defaultSelectM3uStreamFn,
5025
- selectM3uAssociatedPlaylists: selectM3uAssociatedPlaylists ?? defaultSelectM3uAssociatedPlaylists
5065
+ selectM3uAssociatedPlaylists: selectM3uAssociatedPlaylists ?? defaultSelectM3uAssociatedPlaylists,
5066
+ mp4HeaderSegment: null
5026
5067
  }).then(() => {
5027
5068
  return state.waitForFinish();
5028
5069
  }).then(() => {
@@ -1,2 +1,3 @@
1
+ import type { ParseMediaSrc } from '@remotion/media-parser';
1
2
  import type { ConvertMediaContainer } from './get-available-containers';
2
- export declare const generateOutputFilename: (source: string | Blob, container: ConvertMediaContainer) => string;
3
+ export declare const generateOutputFilename: (source: ParseMediaSrc, container: ConvertMediaContainer) => string;
@@ -17,8 +17,8 @@ const makeAudioTrackHandler = ({ state, defaultAudioCodec: audioCodec, controlle
17
17
  outputContainer,
18
18
  inputContainer,
19
19
  });
20
- const audioOperation = await (onAudioTrack !== null && onAudioTrack !== void 0 ? onAudioTrack : default_on_audio_track_handler_1.defaultOnAudioTrackHandler)({
21
- defaultAudioCodec: audioCodec !== null && audioCodec !== void 0 ? audioCodec : (0, get_default_audio_codec_1.getDefaultAudioCodec)({ container: outputContainer }),
20
+ const audioOperation = await (onAudioTrack ?? default_on_audio_track_handler_1.defaultOnAudioTrackHandler)({
21
+ defaultAudioCodec: audioCodec ?? (0, get_default_audio_codec_1.getDefaultAudioCodec)({ container: outputContainer }),
22
22
  track,
23
23
  logLevel,
24
24
  outputContainer,
@@ -48,7 +48,7 @@ const makeAudioTrackHandler = ({ state, defaultAudioCodec: audioCodec, controlle
48
48
  isVideo: false,
49
49
  codecPrivate: track.codecPrivate,
50
50
  });
51
- onMediaStateUpdate === null || onMediaStateUpdate === void 0 ? void 0 : onMediaStateUpdate((prevState) => {
51
+ onMediaStateUpdate?.((prevState) => {
52
52
  return {
53
53
  ...prevState,
54
54
  encodedAudioFrames: prevState.encodedAudioFrames + 1,
@@ -109,7 +109,7 @@ const makeAudioTrackHandler = ({ state, defaultAudioCodec: audioCodec, controlle
109
109
  isVideo: false,
110
110
  codecPrivate,
111
111
  });
112
- onMediaStateUpdate === null || onMediaStateUpdate === void 0 ? void 0 : onMediaStateUpdate((prevState) => {
112
+ onMediaStateUpdate?.((prevState) => {
113
113
  return {
114
114
  ...prevState,
115
115
  encodedAudioFrames: prevState.encodedAudioFrames + 1,
@@ -117,7 +117,7 @@ const makeAudioTrackHandler = ({ state, defaultAudioCodec: audioCodec, controlle
117
117
  });
118
118
  },
119
119
  onError: (err) => {
120
- abortConversion(new Error(`Audio encoder of ${track.trackId} failed (see .cause of this error)`, {
120
+ abortConversion(new Error(`Audio encoder of track ${track.trackId} failed (see .cause of this error)`, {
121
121
  cause: err,
122
122
  }));
123
123
  },
@@ -130,7 +130,7 @@ const makeAudioTrackHandler = ({ state, defaultAudioCodec: audioCodec, controlle
130
130
  const audioDecoder = (0, audio_decoder_1.createAudioDecoder)({
131
131
  onFrame: async (audioData) => {
132
132
  const newAudioData = onAudioData
133
- ? await (onAudioData === null || onAudioData === void 0 ? void 0 : onAudioData({ audioData, track }))
133
+ ? await onAudioData?.({ audioData, track })
134
134
  : audioData;
135
135
  if (newAudioData !== audioData) {
136
136
  if (newAudioData.duration !== audioData.duration) {
@@ -151,7 +151,7 @@ const makeAudioTrackHandler = ({ state, defaultAudioCodec: audioCodec, controlle
151
151
  audioData.close();
152
152
  }
153
153
  await audioEncoder.encodeFrame(newAudioData);
154
- onMediaStateUpdate === null || onMediaStateUpdate === void 0 ? void 0 : onMediaStateUpdate((prevState) => {
154
+ onMediaStateUpdate?.((prevState) => {
155
155
  return {
156
156
  ...prevState,
157
157
  decodedAudioFrames: prevState.decodedAudioFrames + 1,
package/dist/on-frame.js CHANGED
@@ -5,7 +5,6 @@ const browser_quirks_1 = require("./browser-quirks");
5
5
  const convert_to_correct_videoframe_1 = require("./convert-to-correct-videoframe");
6
6
  const rotate_and_resize_video_frame_1 = require("./rotate-and-resize-video-frame");
7
7
  const onFrame = async ({ frame: unrotatedFrame, onVideoFrame, videoEncoder, track, outputCodec, rotation, resizeOperation, }) => {
8
- var _a, _b;
9
8
  const rotated = (0, rotate_and_resize_video_frame_1.rotateAndResizeVideoFrame)({
10
9
  rotation,
11
10
  frame: unrotatedFrame,
@@ -29,7 +28,7 @@ const onFrame = async ({ frame: unrotatedFrame, onVideoFrame, videoEncoder, trac
29
28
  if (userProcessedFrame.timestamp !== rotated.timestamp && !(0, browser_quirks_1.isSafari)()) {
30
29
  throw new Error(`Returned VideoFrame of track ${track.trackId} has different timestamp (${userProcessedFrame.timestamp}) than the input frame (${rotated.timestamp}). When calling new VideoFrame(), pass {timestamp: frame.timestamp} as second argument`);
31
30
  }
32
- if (((_a = userProcessedFrame.duration) !== null && _a !== void 0 ? _a : 0) !== ((_b = rotated.duration) !== null && _b !== void 0 ? _b : 0)) {
31
+ if ((userProcessedFrame.duration ?? 0) !== (rotated.duration ?? 0)) {
33
32
  throw new Error(`Returned VideoFrame of track ${track.trackId} has different duration (${userProcessedFrame.duration}) than the input frame (${rotated.duration}). When calling new VideoFrame(), pass {duration: frame.duration} as second argument`);
34
33
  }
35
34
  const fixedFrame = (0, convert_to_correct_videoframe_1.convertToCorrectVideoFrame)({
@@ -14,7 +14,6 @@ const video_decoder_config_1 = require("./video-decoder-config");
14
14
  const video_encoder_1 = require("./video-encoder");
15
15
  const video_encoder_config_1 = require("./video-encoder-config");
16
16
  const makeVideoTrackHandler = ({ state, onVideoFrame, onMediaStateUpdate, abortConversion, controller, defaultVideoCodec, onVideoTrack, logLevel, outputContainer, rotate, progress, resizeOperation, }) => async ({ track, container: inputContainer }) => {
17
- var _a, _b;
18
17
  if (controller._internals.signal.aborted) {
19
18
  throw new Error('Aborted');
20
19
  }
@@ -25,9 +24,9 @@ const makeVideoTrackHandler = ({ state, onVideoFrame, onMediaStateUpdate, abortC
25
24
  inputTrack: track,
26
25
  resizeOperation,
27
26
  });
28
- const videoOperation = await (onVideoTrack !== null && onVideoTrack !== void 0 ? onVideoTrack : default_on_video_track_handler_1.defaultOnVideoTrackHandler)({
27
+ const videoOperation = await (onVideoTrack ?? default_on_video_track_handler_1.defaultOnVideoTrackHandler)({
29
28
  track,
30
- defaultVideoCodec: defaultVideoCodec !== null && defaultVideoCodec !== void 0 ? defaultVideoCodec : (0, get_default_video_codec_1.getDefaultVideoCodec)({ container: outputContainer }),
29
+ defaultVideoCodec: defaultVideoCodec ?? (0, get_default_video_codec_1.getDefaultVideoCodec)({ container: outputContainer }),
31
30
  logLevel,
32
31
  outputContainer,
33
32
  rotate,
@@ -59,7 +58,7 @@ const makeVideoTrackHandler = ({ state, onVideoFrame, onMediaStateUpdate, abortC
59
58
  isVideo: true,
60
59
  codecPrivate: track.codecPrivate,
61
60
  });
62
- onMediaStateUpdate === null || onMediaStateUpdate === void 0 ? void 0 : onMediaStateUpdate((prevState) => {
61
+ onMediaStateUpdate?.((prevState) => {
63
62
  return {
64
63
  ...prevState,
65
64
  decodedVideoFrames: prevState.decodedVideoFrames + 1,
@@ -70,13 +69,13 @@ const makeVideoTrackHandler = ({ state, onVideoFrame, onMediaStateUpdate, abortC
70
69
  if (videoOperation.type !== 'reencode') {
71
70
  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"`);
72
71
  }
73
- const rotation = ((_a = videoOperation.rotate) !== null && _a !== void 0 ? _a : rotate) - track.rotation;
72
+ const rotation = (videoOperation.rotate ?? rotate) - track.rotation;
74
73
  const { height: newHeight, width: newWidth } = (0, rotation_1.calculateNewDimensionsFromRotateAndScale)({
75
74
  width: track.codedWidth,
76
75
  height: track.codedHeight,
77
76
  rotation,
78
77
  videoCodec: videoOperation.videoCodec,
79
- resizeOperation: (_b = videoOperation.resize) !== null && _b !== void 0 ? _b : null,
78
+ resizeOperation: videoOperation.resize ?? null,
80
79
  });
81
80
  const videoEncoderConfig = await (0, video_encoder_config_1.getVideoEncoderConfig)({
82
81
  codec: videoOperation.videoCodec,
@@ -105,14 +104,14 @@ const makeVideoTrackHandler = ({ state, onVideoFrame, onMediaStateUpdate, abortC
105
104
  log_1.Log.verbose(logLevel, `Created new video track with ID ${trackNumber}, codec ${videoOperation.videoCodec} and timescale ${track.timescale}`);
106
105
  const videoEncoder = (0, video_encoder_1.createVideoEncoder)({
107
106
  onChunk: async (chunk, metadata) => {
108
- var _a, _b;
109
107
  await state.addSample({
110
108
  chunk: (0, convert_encoded_chunk_1.convertEncodedChunk)(chunk, trackNumber),
111
109
  trackNumber,
112
110
  isVideo: true,
113
- 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)),
111
+ codecPrivate: (0, arraybuffer_to_uint8_array_1.arrayBufferToUint8Array)((metadata?.decoderConfig?.description ??
112
+ null)),
114
113
  });
115
- onMediaStateUpdate === null || onMediaStateUpdate === void 0 ? void 0 : onMediaStateUpdate((prevState) => {
114
+ onMediaStateUpdate?.((prevState) => {
116
115
  return {
117
116
  ...prevState,
118
117
  encodedVideoFrames: prevState.encodedVideoFrames + 1,
@@ -133,7 +132,6 @@ const makeVideoTrackHandler = ({ state, onVideoFrame, onMediaStateUpdate, abortC
133
132
  const videoDecoder = (0, video_decoder_1.createVideoDecoder)({
134
133
  config: videoDecoderConfig,
135
134
  onFrame: async (frame) => {
136
- var _a;
137
135
  await (0, on_frame_1.onFrame)({
138
136
  frame,
139
137
  track,
@@ -141,7 +139,7 @@ const makeVideoTrackHandler = ({ state, onVideoFrame, onMediaStateUpdate, abortC
141
139
  onVideoFrame,
142
140
  outputCodec: videoOperation.videoCodec,
143
141
  rotation,
144
- resizeOperation: (_a = videoOperation.resize) !== null && _a !== void 0 ? _a : null,
142
+ resizeOperation: videoOperation.resize ?? null,
145
143
  });
146
144
  },
147
145
  onError: (err) => {
@@ -7,7 +7,6 @@ const normalizeVideoRotation = (rotation) => {
7
7
  };
8
8
  exports.normalizeVideoRotation = normalizeVideoRotation;
9
9
  const rotateAndResizeVideoFrame = ({ frame, rotation, videoCodec, resizeOperation, }) => {
10
- var _a;
11
10
  const normalized = ((rotation % 360) + 360) % 360;
12
11
  // No resize, no rotation
13
12
  if (normalized === 0 && resizeOperation === null) {
@@ -60,7 +59,7 @@ const rotateAndResizeVideoFrame = ({ frame, rotation, videoCodec, resizeOperatio
60
59
  return new VideoFrame(canvas, {
61
60
  displayHeight: height,
62
61
  displayWidth: width,
63
- duration: (_a = frame.duration) !== null && _a !== void 0 ? _a : undefined,
62
+ duration: frame.duration ?? undefined,
64
63
  timestamp: frame.timestamp,
65
64
  });
66
65
  };
@@ -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) => ({ writer, onBytesProgress, onMillisecondsProgress, logLevel, filename, progressTracker, expectedDurationInSeconds, }: import("./create/media-fn").MediaFnGeneratorInput) => Promise<import("./create/media-fn").MediaFn>;
@@ -3,12 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.sendUsageEvent = void 0;
4
4
  const licensing_1 = require("@remotion/licensing");
5
5
  const sendUsageEvent = async ({ apiKey, succeeded, }) => {
6
- var _a;
7
6
  const host = typeof window === 'undefined'
8
7
  ? null
9
8
  : typeof window.location === 'undefined'
10
9
  ? null
11
- : ((_a = window.location.origin) !== null && _a !== void 0 ? _a : null);
10
+ : (window.location.origin ?? null);
12
11
  if (host === null) {
13
12
  return;
14
13
  }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const bun_test_1 = require("bun:test");
4
+ const header_length_1 = require("../create/iso-base-media/header-length");
5
+ (0, bun_test_1.test)('should calculate good header length', () => {
6
+ const result = (0, header_length_1.calculateAReasonableMp4HeaderLength)(60 * 110);
7
+ (0, bun_test_1.expect)(result).toBe(5121246);
8
+ });
9
+ (0, bun_test_1.test)('should calculate good header length for null', () => {
10
+ const result = (0, header_length_1.calculateAReasonableMp4HeaderLength)(0);
11
+ (0, bun_test_1.expect)(result).toBe(51200);
12
+ });
@@ -33,7 +33,7 @@ const throttledStateUpdate = ({ updateFn, everyMilliseconds, signal, }) => {
33
33
  const onAbort = () => {
34
34
  clearInterval(interval);
35
35
  };
36
- signal === null || signal === void 0 ? void 0 : signal.addEventListener('abort', onAbort, { once: true });
36
+ 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 === null || signal === void 0 ? void 0 : signal.removeEventListener('abort', onAbort);
44
+ signal?.removeEventListener('abort', onAbort);
45
45
  return currentState;
46
46
  },
47
47
  };
@@ -66,7 +66,6 @@ const createVideoDecoder = ({ onFrame, onError, controller, config, logLevel, pr
66
66
  controller._internals.signal.addEventListener('abort', onAbort);
67
67
  videoDecoder.configure(config);
68
68
  const processSample = async (sample) => {
69
- var _a, _b;
70
69
  if (videoDecoder.state === 'closed') {
71
70
  return;
72
71
  }
@@ -74,7 +73,7 @@ const createVideoDecoder = ({ onFrame, onError, controller, config, logLevel, pr
74
73
  if (videoDecoder.state === 'closed') {
75
74
  return;
76
75
  }
77
- progress.setPossibleLowestTimestamp(Math.min(sample.timestamp, (_a = sample.dts) !== null && _a !== void 0 ? _a : Infinity, (_b = sample.cts) !== null && _b !== void 0 ? _b : Infinity));
76
+ progress.setPossibleLowestTimestamp(Math.min(sample.timestamp, sample.dts ?? Infinity, sample.cts ?? Infinity));
78
77
  await ioSynchronizer.waitFor({
79
78
  unemitted: 20,
80
79
  unprocessed: 10,
@@ -13,7 +13,7 @@ const getVideoEncoderConfig = async ({ codec, height, width, fps, }) => {
13
13
  width,
14
14
  bitrate: (0, browser_quirks_1.isSafari)() ? 3000000 : undefined,
15
15
  bitrateMode: codec === 'vp9' && !(0, browser_quirks_1.isSafari)() ? 'quantizer' : undefined,
16
- framerate: fps !== null && fps !== void 0 ? fps : undefined,
16
+ framerate: fps ?? undefined,
17
17
  };
18
18
  const hardware = {
19
19
  ...config,
@@ -20,15 +20,14 @@ const createVideoEncoder = ({ onChunk, onError, controller, config, logLevel, ou
20
20
  onError(error);
21
21
  },
22
22
  output(chunk, metadata) {
23
- var _a;
24
- const timestamp = chunk.timestamp + ((_a = chunk.duration) !== null && _a !== void 0 ? _a : 0);
23
+ const timestamp = chunk.timestamp + (chunk.duration ?? 0);
25
24
  ioSynchronizer.onOutput(timestamp);
26
25
  outputQueue = outputQueue
27
26
  .then(() => {
28
27
  if (controller._internals.signal.aborted) {
29
28
  return;
30
29
  }
31
- return onChunk(chunk, metadata !== null && metadata !== void 0 ? metadata : null);
30
+ return onChunk(chunk, metadata ?? null);
32
31
  })
33
32
  .then(() => {
34
33
  ioSynchronizer.onProcessed();
@@ -10,7 +10,7 @@ const createContent = async ({ filename }) => {
10
10
  recursive: true,
11
11
  });
12
12
  }
13
- catch (_a) { }
13
+ catch { }
14
14
  };
15
15
  await remove();
16
16
  const fileHandle = await directoryHandle.getFileHandle(actualFilename, {
@@ -38,7 +38,7 @@ const createContent = async ({ filename }) => {
38
38
  try {
39
39
  await writable.close();
40
40
  }
41
- catch (_a) {
41
+ catch {
42
42
  // Ignore, could already be closed
43
43
  }
44
44
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remotion/webcodecs",
3
- "version": "4.0.270",
3
+ "version": "4.0.272",
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.270",
21
- "@remotion/licensing": "4.0.270"
20
+ "@remotion/media-parser": "4.0.272",
21
+ "@remotion/licensing": "4.0.272"
22
22
  },
23
23
  "peerDependencies": {},
24
24
  "devDependencies": {
25
25
  "@types/dom-webcodecs": "0.1.11",
26
26
  "eslint": "9.19.0",
27
- "@remotion/eslint-config-internal": "4.0.270",
28
- "@remotion/example-videos": "4.0.270"
27
+ "@remotion/eslint-config-internal": "4.0.272",
28
+ "@remotion/example-videos": "4.0.272"
29
29
  },
30
30
  "keywords": [],
31
31
  "publishConfig": {