@remotion/webcodecs 4.0.251 → 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.
- package/dist/auto-select-writer.d.ts +1 -1
- package/dist/can-copy-video-track.js +2 -1
- package/dist/choose-correct-hevc-profile.d.ts +5 -0
- package/dist/choose-correct-hevc-profile.js +42 -0
- package/dist/convert-media.d.ts +3 -4
- package/dist/convert-media.js +7 -5
- package/dist/create/iso-base-media/codec-specific/create-codec-specific-data.d.ts +11 -0
- package/dist/create/iso-base-media/codec-specific/create-codec-specific-data.js +29 -11
- package/dist/create/iso-base-media/codec-specific/hvc1.d.ts +2 -0
- package/dist/create/iso-base-media/codec-specific/hvc1.js +48 -0
- package/dist/create/iso-base-media/create-iso-base-media.js +8 -4
- package/dist/create/iso-base-media/serialize-track.js +3 -1
- package/dist/create/iso-base-media/trak/mdia/minf/stbl/stsd/create-hvcc.d.ts +1 -0
- package/dist/create/iso-base-media/trak/mdia/minf/stbl/stsd/create-hvcc.js +16 -0
- package/dist/create/matroska/cluster.d.ts +1 -1
- package/dist/create/matroska/create-matroska-media.js +8 -4
- package/dist/create/matroska/matroska-trackentry.js +3 -0
- package/dist/create/matroska/matroska-utils.d.ts +1 -1
- package/dist/create/media-fn.d.ts +2 -3
- package/dist/create/wav/create-wav.js +8 -4
- package/dist/esm/buffer.mjs +5 -22
- package/dist/esm/index.mjs +426 -62
- package/dist/esm/web-fs.mjs +4 -22
- package/dist/get-available-containers.d.ts +1 -2
- package/dist/get-available-containers.js +3 -3
- package/dist/get-available-video-codecs.d.ts +1 -2
- package/dist/get-available-video-codecs.js +3 -4
- package/dist/get-codec-string.d.ts +7 -0
- package/dist/get-codec-string.js +21 -0
- package/dist/hevc-levels.d.ts +13 -0
- package/dist/hevc-levels.js +233 -0
- package/dist/index.d.ts +0 -1
- package/dist/on-audio-track.js +1 -0
- package/dist/select-container-creator.d.ts +1 -1
- package/dist/test/remux-serverside.test.js +2 -2
- package/dist/video-encoder-config.js +4 -6
- package/dist/video-encoder.js +4 -0
- package/dist/writers/buffer-implementation/writer.d.ts +1 -1
- package/dist/writers/buffer-implementation/writer.js +5 -4
- package/dist/writers/buffer.d.ts +1 -1
- package/dist/writers/web-fs.d.ts +1 -1
- package/dist/writers/web-fs.js +4 -4
- package/package.json +5 -5
|
@@ -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>;
|
|
@@ -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,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;
|
package/dist/convert-media.d.ts
CHANGED
|
@@ -2,15 +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, ParseMediaFields, ParseMediaOptions, VideoTrack } from '@remotion/media-parser';
|
|
5
|
+
import type { AudioTrack, LogLevel, Options, ParseMediaFields, ParseMediaOptions, VideoTrack, WriterInterface } from '@remotion/media-parser';
|
|
6
6
|
import type { ParseMediaCallbacks } from '@remotion/media-parser';
|
|
7
7
|
import type { ConvertMediaAudioCodec } from './get-available-audio-codecs';
|
|
8
|
-
import type
|
|
9
|
-
import type
|
|
8
|
+
import { type ConvertMediaContainer } from './get-available-containers';
|
|
9
|
+
import { type ConvertMediaVideoCodec } from './get-available-video-codecs';
|
|
10
10
|
import { type ConvertMediaOnAudioTrackHandler } from './on-audio-track-handler';
|
|
11
11
|
import { type ConvertMediaOnVideoTrackHandler } from './on-video-track-handler';
|
|
12
12
|
import type { ResizeOperation } from './resizing/mode';
|
|
13
|
-
import type { WriterInterface } from './writers/writer';
|
|
14
13
|
export type ConvertMediaProgress = {
|
|
15
14
|
decodedVideoFrames: number;
|
|
16
15
|
decodedAudioFrames: number;
|
package/dist/convert-media.js
CHANGED
|
@@ -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
|
|
30
|
-
return Promise.reject(new TypeError(
|
|
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
|
|
33
|
-
return Promise.reject(new TypeError(
|
|
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.
|
|
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
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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,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({
|
|
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
|
-
|
|
139
|
-
return w.
|
|
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.
|
|
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' &&
|
|
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({
|
|
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
|
-
|
|
153
|
-
return w.
|
|
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
|
};
|
|
@@ -19,7 +19,7 @@ export type EbmlParsedOrUint8Array<T extends Ebml> = {
|
|
|
19
19
|
value: EbmlValueOrUint8Array<T>;
|
|
20
20
|
minVintWidth: number | null;
|
|
21
21
|
};
|
|
22
|
-
export declare const measureEBMLVarInt: (value: number) => 2 | 1 |
|
|
22
|
+
export declare const measureEBMLVarInt: (value: number) => 2 | 1 | 6 | 5 | 3 | 4;
|
|
23
23
|
export declare const getVariableInt: (value: number, minWidth: number | null) => Uint8Array;
|
|
24
24
|
export declare const makeMatroskaBytes: (fields: PossibleEbmlOrUint8Array) => BytesAndOffset;
|
|
25
25
|
export type PossibleEbmlOrUint8Array = Prettify<{
|
|
@@ -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
|
-
|
|
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({
|
|
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
|
-
|
|
68
|
-
return w.
|
|
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.
|
|
96
|
+
await w.finish();
|
|
93
97
|
},
|
|
94
98
|
addTrack: async (track) => {
|
|
95
99
|
if (track.type !== 'audio') {
|
package/dist/esm/buffer.mjs
CHANGED
|
@@ -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
|
-
|
|
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);
|