@remotion/webcodecs 4.0.250 → 4.0.252

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 (54) hide show
  1. package/dist/auto-select-writer.d.ts +1 -1
  2. package/dist/can-copy-audio-track.d.ts +2 -2
  3. package/dist/can-copy-video-track.d.ts +2 -2
  4. package/dist/can-copy-video-track.js +2 -1
  5. package/dist/choose-correct-hevc-profile.d.ts +5 -0
  6. package/dist/choose-correct-hevc-profile.js +42 -0
  7. package/dist/convert-media.d.ts +6 -5
  8. package/dist/convert-media.js +7 -5
  9. package/dist/create/iso-base-media/codec-specific/create-codec-specific-data.d.ts +11 -0
  10. package/dist/create/iso-base-media/codec-specific/create-codec-specific-data.js +29 -11
  11. package/dist/create/iso-base-media/codec-specific/hvc1.d.ts +2 -0
  12. package/dist/create/iso-base-media/codec-specific/hvc1.js +48 -0
  13. package/dist/create/iso-base-media/create-iso-base-media.js +8 -4
  14. package/dist/create/iso-base-media/serialize-track.js +3 -1
  15. package/dist/create/iso-base-media/trak/mdia/minf/stbl/stsd/create-hvcc.d.ts +1 -0
  16. package/dist/create/iso-base-media/trak/mdia/minf/stbl/stsd/create-hvcc.js +16 -0
  17. package/dist/create/matroska/cluster.d.ts +1 -1
  18. package/dist/create/matroska/create-matroska-media.js +8 -4
  19. package/dist/create/matroska/matroska-trackentry.js +6 -0
  20. package/dist/create/media-fn.d.ts +2 -3
  21. package/dist/create/wav/create-wav.js +8 -4
  22. package/dist/esm/buffer.mjs +5 -22
  23. package/dist/esm/index.mjs +435 -65
  24. package/dist/esm/web-fs.mjs +10 -25
  25. package/dist/get-available-containers.d.ts +1 -2
  26. package/dist/get-available-containers.js +3 -3
  27. package/dist/get-available-video-codecs.d.ts +1 -2
  28. package/dist/get-available-video-codecs.js +3 -4
  29. package/dist/get-codec-string.d.ts +7 -0
  30. package/dist/get-codec-string.js +21 -0
  31. package/dist/hevc-levels.d.ts +13 -0
  32. package/dist/hevc-levels.js +233 -0
  33. package/dist/index.d.ts +0 -1
  34. package/dist/on-audio-track-handler.d.ts +2 -2
  35. package/dist/on-audio-track.js +1 -0
  36. package/dist/on-video-track-handler.d.ts +2 -2
  37. package/dist/test/create-matroska.test.js +13 -13
  38. package/dist/test/remux-serverside.test.js +6 -2
  39. package/dist/test/stsd.test.js +2 -4
  40. package/dist/video-encoder-config.js +4 -6
  41. package/dist/video-encoder.js +4 -0
  42. package/dist/writers/buffer-implementation/writer.d.ts +1 -1
  43. package/dist/writers/buffer-implementation/writer.js +5 -4
  44. package/dist/writers/buffer.d.ts +1 -1
  45. package/dist/writers/web-fs.d.ts +1 -1
  46. package/dist/writers/web-fs.js +10 -7
  47. package/package.json +5 -5
  48. package/dist/esm/node-writer.mjs +0 -92
  49. package/dist/test/remux-serverside.d.ts +0 -1
  50. package/dist/test/remux-serverside.js +0 -12
  51. package/dist/writers/fs.d.ts +0 -4
  52. package/dist/writers/fs.js +0 -78
  53. package/dist/writers/node-writer.d.ts +0 -4
  54. package/dist/writers/node-writer.js +0 -77
@@ -1,3 +1,3 @@
1
+ import type { WriterInterface } from '@remotion/media-parser';
1
2
  import type { LogLevel } from './log';
2
- import type { WriterInterface } from './writers/writer';
3
3
  export declare const autoSelectWriter: (writer: WriterInterface | undefined, logLevel: LogLevel) => Promise<WriterInterface>;
@@ -1,7 +1,7 @@
1
- import type { MediaParserAudioCodec, ParseMediaContainer } from '@remotion/media-parser';
1
+ import type { MediaParserAudioCodec, MediaParserContainer } from '@remotion/media-parser';
2
2
  import type { ConvertMediaContainer } from './get-available-containers';
3
3
  export declare const canCopyAudioTrack: ({ inputCodec, outputContainer, inputContainer, }: {
4
4
  inputCodec: MediaParserAudioCodec;
5
5
  outputContainer: ConvertMediaContainer;
6
- inputContainer: ParseMediaContainer;
6
+ inputContainer: MediaParserContainer;
7
7
  }) => boolean;
@@ -1,8 +1,8 @@
1
- import type { ParseMediaContainer, VideoTrack } from '@remotion/media-parser';
1
+ import type { MediaParserContainer, VideoTrack } from '@remotion/media-parser';
2
2
  import type { ConvertMediaContainer } from './get-available-containers';
3
3
  import type { ResizeOperation } from './resizing/mode';
4
4
  export declare const canCopyVideoTrack: ({ outputContainer, rotationToApply, inputContainer, resizeOperation, inputTrack, }: {
5
- inputContainer: ParseMediaContainer;
5
+ inputContainer: MediaParserContainer;
6
6
  inputTrack: VideoTrack;
7
7
  rotationToApply: number;
8
8
  outputContainer: ConvertMediaContainer;
@@ -24,7 +24,8 @@ const canCopyVideoTrack = ({ outputContainer, rotationToApply, inputContainer, r
24
24
  inputTrack.codecWithoutConfig === 'vp9');
25
25
  }
26
26
  if (outputContainer === 'mp4') {
27
- return (inputTrack.codecWithoutConfig === 'h264' &&
27
+ return ((inputTrack.codecWithoutConfig === 'h264' ||
28
+ inputTrack.codecWithoutConfig === 'h265') &&
28
29
  (inputContainer === 'mp4' || inputContainer === 'avi'));
29
30
  }
30
31
  if (outputContainer === 'wav') {
@@ -0,0 +1,5 @@
1
+ export declare const chooseCorrectHevcProfile: ({ width, height, fps, }: {
2
+ width: number;
3
+ height: number;
4
+ fps: number | null;
5
+ }) => string;
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.chooseCorrectHevcProfile = void 0;
4
+ const hevc_levels_1 = require("./hevc-levels");
5
+ const chooseCorrectHevcProfile = ({ width, height, fps, }) => {
6
+ const profile = hevc_levels_1.hevcLevels.find((p) => {
7
+ return p.maxResolutionsAndFrameRates.some((max) => {
8
+ if (width > max.width) {
9
+ return false;
10
+ }
11
+ if (height > max.height) {
12
+ return false;
13
+ }
14
+ // if has no fps, use 60 as a conservative fallback
15
+ const fallbackFps = fps !== null && fps !== void 0 ? fps : 60;
16
+ return fallbackFps <= max.fps;
17
+ });
18
+ });
19
+ if (!profile) {
20
+ throw new Error(`No suitable HEVC profile found for ${width}x${height}@${fps}fps`);
21
+ }
22
+ // HEVC codec string format: hev1.2.${level_hex} or hvc1.2.${level_hex}
23
+ // We'll use hvc1 as it's more widely supported
24
+ return `hvc1.${
25
+ // Profile
26
+ // 1 = Main
27
+ // 2 = Main 10
28
+ // Chrome seems to support only Main
29
+ 1}.${
30
+ // Profile space
31
+ // Unclear which value to set, but 0 works
32
+ 0}.${
33
+ // L = Main tier
34
+ // H = High tier
35
+ // TODO: Select high tier if resolution is big
36
+ 'L'}${
37
+ // Level
38
+ Math.round(Number(profile.level) * 30)}.${
39
+ // Bit depth
40
+ 'b0'}`;
41
+ };
42
+ exports.chooseCorrectHevcProfile = chooseCorrectHevcProfile;
@@ -2,14 +2,14 @@
2
2
  * Copyright (c) 2025 Remotion AG
3
3
  * For licensing, see: https://remotion.dev/docs/webcodecs#license
4
4
  */
5
- import type { AudioTrack, LogLevel, Options, ParseMediaDynamicOptions, ParseMediaFields, ParseMediaOptions, VideoTrack } from '@remotion/media-parser';
5
+ import type { AudioTrack, LogLevel, Options, ParseMediaFields, ParseMediaOptions, VideoTrack, WriterInterface } from '@remotion/media-parser';
6
+ import type { ParseMediaCallbacks } from '@remotion/media-parser';
6
7
  import type { ConvertMediaAudioCodec } from './get-available-audio-codecs';
7
- import type { ConvertMediaContainer } from './get-available-containers';
8
- import type { ConvertMediaVideoCodec } from './get-available-video-codecs';
8
+ import { type ConvertMediaContainer } from './get-available-containers';
9
+ import { type ConvertMediaVideoCodec } from './get-available-video-codecs';
9
10
  import { type ConvertMediaOnAudioTrackHandler } from './on-audio-track-handler';
10
11
  import { type ConvertMediaOnVideoTrackHandler } from './on-video-track-handler';
11
12
  import type { ResizeOperation } from './resizing/mode';
12
- import type { WriterInterface } from './writers/writer';
13
13
  export type ConvertMediaProgress = {
14
14
  decodedVideoFrames: number;
15
15
  decodedAudioFrames: number;
@@ -52,4 +52,5 @@ export declare const convertMedia: <F extends Options<ParseMediaFields>>({ src,
52
52
  rotate?: number;
53
53
  resize?: ResizeOperation;
54
54
  apiKey?: string | null;
55
- } & ParseMediaDynamicOptions<F>) => Promise<ConvertMediaResult>;
55
+ fields?: F;
56
+ } & ParseMediaCallbacks) => Promise<ConvertMediaResult>;
@@ -15,6 +15,8 @@ const progress_tracker_1 = require("./create/progress-tracker");
15
15
  const with_resolvers_1 = require("./create/with-resolvers");
16
16
  const error_cause_1 = __importDefault(require("./error-cause"));
17
17
  const generate_output_filename_1 = require("./generate-output-filename");
18
+ const get_available_containers_1 = require("./get-available-containers");
19
+ const get_available_video_codecs_1 = require("./get-available-video-codecs");
18
20
  const log_1 = require("./log");
19
21
  const on_audio_track_1 = require("./on-audio-track");
20
22
  const on_video_track_1 = require("./on-video-track");
@@ -26,11 +28,11 @@ const convertMedia = async function ({ src, onVideoFrame, onAudioData, onProgres
26
28
  if (userPassedAbortSignal === null || userPassedAbortSignal === void 0 ? void 0 : userPassedAbortSignal.aborted) {
27
29
  return Promise.reject(new error_cause_1.default('Aborted'));
28
30
  }
29
- if (container !== 'webm' && container !== 'mp4' && container !== 'wav') {
30
- return Promise.reject(new TypeError('Only `to: "webm"`, `to: "mp4"` and `to: "wav"` is supported currently'));
31
+ if (container !== 'webm' && get_available_containers_1.availableContainers.indexOf(container) === -1) {
32
+ return Promise.reject(new TypeError(`Only the following values for "container" are supported currently: ${JSON.stringify(get_available_containers_1.availableContainers)}`));
31
33
  }
32
- if (videoCodec && videoCodec !== 'vp8' && videoCodec !== 'vp9') {
33
- return Promise.reject(new TypeError('Only `videoCodec: "vp8"` and `videoCodec: "vp9"` are supported currently'));
34
+ if (videoCodec && get_available_video_codecs_1.availableVideoCodecs.indexOf(videoCodec) === -1) {
35
+ return Promise.reject(new TypeError(`Only the following values for "videoCodec" are supported currently: ${JSON.stringify(get_available_video_codecs_1.availableVideoCodecs)}`));
34
36
  }
35
37
  const { resolve, reject, getPromiseToImmediatelyReturn } = (0, with_resolvers_1.withResolversAndWaitForReturn)();
36
38
  const controller = new AbortController();
@@ -147,7 +149,7 @@ const convertMedia = async function ({ src, onVideoFrame, onAudioData, onProgres
147
149
  })
148
150
  .then(() => {
149
151
  resolve({
150
- save: state.save,
152
+ save: state.getBlob,
151
153
  remove: state.remove,
152
154
  finalState: throttledState.get(),
153
155
  });
@@ -10,6 +10,17 @@ export type Avc1Data = {
10
10
  depth: number;
11
11
  type: 'avc1-data';
12
12
  };
13
+ export type Hvc1Data = {
14
+ pasp: Uint8Array;
15
+ hvccBox: Uint8Array;
16
+ width: number;
17
+ height: number;
18
+ horizontalResolution: number;
19
+ verticalResolution: number;
20
+ compressorName: string;
21
+ depth: number;
22
+ type: 'hvc1-data';
23
+ };
13
24
  export type Mp4aData = {
14
25
  type: 'mp4a-data';
15
26
  sampleRate: number;
@@ -2,22 +2,40 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createCodecSpecificData = void 0;
4
4
  const create_avcc_1 = require("../trak/mdia/minf/stbl/stsd/create-avcc");
5
+ const create_hvcc_1 = require("../trak/mdia/minf/stbl/stsd/create-hvcc");
5
6
  const create_pasp_1 = require("../trak/mdia/minf/stbl/stsd/create-pasp");
6
7
  const avc1_1 = require("./avc1");
8
+ const hvc1_1 = require("./hvc1");
7
9
  const mp4a_1 = require("./mp4a");
8
10
  const createCodecSpecificData = (track) => {
9
11
  if (track.type === 'video') {
10
- return (0, avc1_1.createAvc1Data)({
11
- avccBox: (0, create_avcc_1.createAvccBox)(track.codecPrivate),
12
- compressorName: 'WebCodecs',
13
- depth: 24,
14
- horizontalResolution: 72,
15
- verticalResolution: 72,
16
- height: track.height,
17
- width: track.width,
18
- pasp: (0, create_pasp_1.createPasp)(1, 1),
19
- type: 'avc1-data',
20
- });
12
+ if (track.codec === 'h264') {
13
+ return (0, avc1_1.createAvc1Data)({
14
+ avccBox: (0, create_avcc_1.createAvccBox)(track.codecPrivate),
15
+ compressorName: 'WebCodecs',
16
+ depth: 24,
17
+ horizontalResolution: 72,
18
+ verticalResolution: 72,
19
+ height: track.height,
20
+ width: track.width,
21
+ pasp: (0, create_pasp_1.createPasp)(1, 1),
22
+ type: 'avc1-data',
23
+ });
24
+ }
25
+ if (track.codec === 'h265') {
26
+ return (0, hvc1_1.createHvc1Data)({
27
+ hvccBox: (0, create_hvcc_1.createHvccBox)(track.codecPrivate),
28
+ compressorName: 'WebCodecs',
29
+ depth: 24,
30
+ horizontalResolution: 72,
31
+ verticalResolution: 72,
32
+ height: track.height,
33
+ width: track.width,
34
+ pasp: (0, create_pasp_1.createPasp)(1, 1),
35
+ type: 'hvc1-data',
36
+ });
37
+ }
38
+ throw new Error('Unsupported codec specific data ' + track.codec);
21
39
  }
22
40
  if (track.type === 'audio') {
23
41
  return (0, mp4a_1.createMp4a)({
@@ -0,0 +1,2 @@
1
+ import type { Hvc1Data } from './create-codec-specific-data';
2
+ export declare const createHvc1Data: ({ compressorName, depth, height, horizontalResolution, hvccBox, pasp, verticalResolution, width, }: Hvc1Data) => Uint8Array;
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createHvc1Data = void 0;
4
+ const matroska_utils_1 = require("../../matroska/matroska-utils");
5
+ const primitives_1 = require("../primitives");
6
+ const createHvc1Data = ({ compressorName, depth, height, horizontalResolution, hvccBox, pasp, verticalResolution, width, }) => {
7
+ return (0, primitives_1.addSize)((0, matroska_utils_1.combineUint8Arrays)([
8
+ // type
9
+ (0, primitives_1.stringsToUint8Array)('hvc1'),
10
+ // reserved
11
+ new Uint8Array([0, 0, 0, 0, 0, 0]),
12
+ // data_reference_index
13
+ new Uint8Array([0, 1]),
14
+ // version
15
+ new Uint8Array([0, 0]),
16
+ // revisionLevel
17
+ new Uint8Array([0, 0]),
18
+ // vendor
19
+ new Uint8Array([0, 0, 0, 0]),
20
+ // temporalQuality
21
+ new Uint8Array([0, 0, 0, 0]),
22
+ // spatialQuality
23
+ new Uint8Array([0, 0, 0, 0]),
24
+ // width
25
+ (0, primitives_1.numberTo16BitUIntOrInt)(width),
26
+ // height
27
+ (0, primitives_1.numberTo16BitUIntOrInt)(height),
28
+ // horizontalResolution
29
+ (0, primitives_1.setFixedPointSignedOrUnsigned1616Number)(horizontalResolution),
30
+ // verticalResolution
31
+ (0, primitives_1.setFixedPointSignedOrUnsigned1616Number)(verticalResolution),
32
+ // dataSize
33
+ new Uint8Array([0, 0, 0, 0]),
34
+ // frame count per sample
35
+ (0, primitives_1.numberTo16BitUIntOrInt)(1),
36
+ // compressor name
37
+ (0, primitives_1.stringToPascalString)(compressorName),
38
+ // depth
39
+ (0, primitives_1.numberTo16BitUIntOrInt)(depth),
40
+ // colorTableId
41
+ (0, primitives_1.numberTo16BitUIntOrInt)(-1),
42
+ // hvcc box
43
+ hvccBox,
44
+ // pasp
45
+ pasp,
46
+ ]));
47
+ };
48
+ exports.createHvc1Data = createHvc1Data;
@@ -13,7 +13,11 @@ const createIsoBaseMedia = async ({ writer, onBytesProgress, onMillisecondsProgr
13
13
  majorBrand: 'isom',
14
14
  minorBrand: 512,
15
15
  });
16
- const w = await writer.createContent({ filename, mimeType: 'video/mp4' });
16
+ const w = await writer.createContent({
17
+ filename,
18
+ mimeType: 'video/mp4',
19
+ logLevel,
20
+ });
17
21
  await w.write(header);
18
22
  let globalDurationInUnits = 0;
19
23
  const lowestTrackTimestamps = {};
@@ -135,8 +139,8 @@ const createIsoBaseMedia = async ({ writer, onBytesProgress, onMillisecondsProgr
135
139
  };
136
140
  const waitForFinishPromises = [];
137
141
  return {
138
- save: () => {
139
- return w.save();
142
+ getBlob: () => {
143
+ return w.getBlob();
140
144
  },
141
145
  remove: async () => {
142
146
  await w.remove();
@@ -177,7 +181,7 @@ const createIsoBaseMedia = async ({ writer, onBytesProgress, onMillisecondsProgr
177
181
  await updateMoov();
178
182
  await updateMdatSize();
179
183
  media_parser_1.MediaParserInternals.Log.verbose(logLevel, 'All write operations done. Waiting for finish...');
180
- await w.waitForFinish();
184
+ await w.finish();
181
185
  },
182
186
  };
183
187
  };
@@ -13,7 +13,9 @@ const create_stbl_1 = require("./trak/mdia/minf/create-stbl");
13
13
  const create_vmhd_1 = require("./trak/mdia/minf/create-vmhd");
14
14
  const create_hdlr_1 = require("./udta/meta/create-hdlr");
15
15
  const serializeTrack = ({ track, durationInUnits, samplePositions, timescale, }) => {
16
- if (track.codec !== 'h264' && track.codec !== 'aac') {
16
+ if (track.codec !== 'h264' &&
17
+ track.codec !== 'h265' &&
18
+ track.codec !== 'aac') {
17
19
  throw new Error('Currently only H.264 and AAC is supported');
18
20
  }
19
21
  return (0, create_trak_1.createTrak)({
@@ -0,0 +1 @@
1
+ export declare const createHvccBox: (privateData: Uint8Array | null) => Uint8Array;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createHvccBox = void 0;
4
+ const matroska_utils_1 = require("../../../../../../matroska/matroska-utils");
5
+ const primitives_1 = require("../../../../../primitives");
6
+ const createHvccBox = (privateData) => {
7
+ if (!privateData) {
8
+ throw new Error('privateData is required');
9
+ }
10
+ return (0, primitives_1.addSize)((0, matroska_utils_1.combineUint8Arrays)([
11
+ // type
12
+ (0, primitives_1.stringsToUint8Array)('hvcC'),
13
+ privateData,
14
+ ]));
15
+ };
16
+ exports.createHvccBox = createHvccBox;
@@ -1,6 +1,6 @@
1
+ import type { Writer } from '@remotion/media-parser';
1
2
  import { type AudioOrVideoSample } from '@remotion/media-parser';
2
3
  import type { LogLevel } from '../../log';
3
- import type { Writer } from '../../writers/writer';
4
4
  export declare const timestampToClusterTimestamp: (timestamp: number, timescale: number) => number;
5
5
  export declare const canFitInCluster: ({ clusterStartTimestamp, chunk, timescale, }: {
6
6
  clusterStartTimestamp: number;
@@ -16,7 +16,11 @@ const timescale = 1000000;
16
16
  const createMatroskaMedia = async ({ writer, onBytesProgress, onMillisecondsProgress, filename, logLevel, progressTracker, }) => {
17
17
  var _a, _b, _c, _d, _e, _f, _g;
18
18
  const header = (0, matroska_header_1.makeMatroskaHeader)();
19
- const w = await writer.createContent({ filename, mimeType: 'video/webm' });
19
+ const w = await writer.createContent({
20
+ filename,
21
+ mimeType: 'video/webm',
22
+ logLevel,
23
+ });
20
24
  await w.write(header.bytes);
21
25
  const matroskaInfo = (0, matroska_info_1.makeMatroskaInfo)({
22
26
  timescale,
@@ -149,8 +153,8 @@ const createMatroskaMedia = async ({ writer, onBytesProgress, onMillisecondsProg
149
153
  }
150
154
  });
151
155
  },
152
- save: () => {
153
- return w.save();
156
+ getBlob: async () => {
157
+ return w.getBlob();
154
158
  },
155
159
  remove: async () => {
156
160
  await w.remove();
@@ -177,12 +181,12 @@ const createMatroskaMedia = async ({ writer, onBytesProgress, onMillisecondsProg
177
181
  });
178
182
  await updateSeekWrite();
179
183
  await w.write((0, matroska_cues_1.createMatroskaCues)(cues).bytes);
180
- await w.waitForFinish();
181
184
  const segmentSize = w.getWrittenByteCount() -
182
185
  segmentOffset -
183
186
  (0, matroska_utils_1.matroskaToHex)(matroskaElements.Segment).byteLength -
184
187
  matroska_segment_1.MATROSKA_SEGMENT_MIN_VINT_WIDTH;
185
188
  await updateSegmentSize(segmentSize);
189
+ await w.finish();
186
190
  },
187
191
  };
188
192
  };
@@ -67,12 +67,18 @@ const makeAudioCodecId = (codecId) => {
67
67
  if (codecId === 'aac') {
68
68
  return 'A_AAC';
69
69
  }
70
+ if (codecId === 'ac3') {
71
+ return 'A_AC3';
72
+ }
70
73
  if (codecId === 'mp3') {
71
74
  return 'A_MPEG/L3';
72
75
  }
73
76
  if (codecId === 'vorbis') {
74
77
  return 'A_VORBIS';
75
78
  }
79
+ if (codecId === 'flac') {
80
+ return 'A_FLAC';
81
+ }
76
82
  if (codecId === 'pcm-u8') {
77
83
  return 'A_PCM/INT/LIT';
78
84
  }
@@ -1,10 +1,9 @@
1
- import type { AudioOrVideoSample } from '@remotion/media-parser';
1
+ import type { AudioOrVideoSample, WriterInterface } from '@remotion/media-parser';
2
2
  import type { LogLevel } from '../log';
3
- import type { WriterInterface } from '../writers/writer';
4
3
  import type { MakeTrackAudio, MakeTrackVideo } from './make-track-info';
5
4
  import type { ProgressTracker } from './progress-tracker';
6
5
  export type MediaFn = {
7
- save: () => Promise<Blob>;
6
+ getBlob: () => Promise<Blob>;
8
7
  remove: () => Promise<void>;
9
8
  addSample: (options: {
10
9
  chunk: AudioOrVideoSample;
@@ -16,7 +16,11 @@ const numberTo16BitLittleEndian = (num) => {
16
16
  const BIT_DEPTH = 16;
17
17
  const BYTES_PER_SAMPLE = BIT_DEPTH / 8;
18
18
  const createWav = async ({ filename, logLevel, onBytesProgress, onMillisecondsProgress, writer, progressTracker, }) => {
19
- const w = await writer.createContent({ filename, mimeType: 'audio/wav' });
19
+ const w = await writer.createContent({
20
+ filename,
21
+ mimeType: 'audio/wav',
22
+ logLevel,
23
+ });
20
24
  await w.write(new Uint8Array([0x52, 0x49, 0x46, 0x46])); // "RIFF"
21
25
  const sizePosition = w.getWrittenByteCount();
22
26
  await w.write(new Uint8Array([0x00, 0x00, 0x00, 0x00])); // Remaining size
@@ -64,8 +68,8 @@ const createWav = async ({ filename, logLevel, onBytesProgress, onMillisecondsPr
64
68
  };
65
69
  const waitForFinishPromises = [];
66
70
  return {
67
- save: () => {
68
- return w.save();
71
+ getBlob: () => {
72
+ return w.getBlob();
69
73
  },
70
74
  remove: () => {
71
75
  return w.remove();
@@ -89,7 +93,7 @@ const createWav = async ({ filename, logLevel, onBytesProgress, onMillisecondsPr
89
93
  await Promise.all(waitForFinishPromises.map((p) => p()));
90
94
  await operationProm.current;
91
95
  await updateSize();
92
- await w.waitForFinish();
96
+ await w.finish();
93
97
  },
94
98
  addTrack: async (track) => {
95
99
  if (track.type !== 'audio') {
@@ -1,21 +1,3 @@
1
- var __create = Object.create;
2
- var __getProtoOf = Object.getPrototypeOf;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __toESM = (mod, isNodeMode, target) => {
7
- target = mod != null ? __create(__getProtoOf(mod)) : {};
8
- const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
9
- for (let key of __getOwnPropNames(mod))
10
- if (!__hasOwnProp.call(to, key))
11
- __defProp(to, key, {
12
- get: () => mod[key],
13
- enumerable: true
14
- });
15
- return to;
16
- };
17
- var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
18
-
19
1
  // src/writers/buffer-implementation/writer.ts
20
2
  var createContent = ({ filename, mimeType }) => {
21
3
  const buf = new ArrayBuffer(0, {
@@ -42,10 +24,14 @@ var createContent = ({ filename, mimeType }) => {
42
24
  writPromise = writPromise.then(() => write(arr));
43
25
  return writPromise;
44
26
  },
45
- save: () => {
27
+ finish: async () => {
28
+ await writPromise;
46
29
  if (removed) {
47
30
  return Promise.reject(new Error("Already called .remove() on the result"));
48
31
  }
32
+ return Promise.resolve();
33
+ },
34
+ getBlob() {
49
35
  const arr = new Uint8Array(buf);
50
36
  return Promise.resolve(new File([arr.slice()], filename, { type: mimeType }));
51
37
  },
@@ -57,9 +43,6 @@ var createContent = ({ filename, mimeType }) => {
57
43
  updateDataAt: (position, newData) => {
58
44
  writPromise = writPromise.then(() => updateDataAt(position, newData));
59
45
  return writPromise;
60
- },
61
- waitForFinish: async () => {
62
- await writPromise;
63
46
  }
64
47
  };
65
48
  return Promise.resolve(writer);