@remotion/webcodecs 4.0.249 → 4.0.251
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.js +5 -0
- package/dist/can-copy-audio-track.d.ts +2 -2
- package/dist/can-copy-video-track.d.ts +2 -2
- package/dist/can-reencode-video-track.d.ts +4 -1
- package/dist/can-reencode-video-track.js +11 -3
- package/dist/convert-media.d.ts +4 -2
- package/dist/create/matroska/matroska-trackentry.js +3 -0
- package/dist/create/matroska/matroska-utils.d.ts +1 -1
- package/dist/default-on-video-track-handler.js +2 -0
- package/dist/esm/index.mjs +29 -7
- package/dist/esm/node.mjs +71 -0
- package/dist/esm/web-fs.mjs +6 -3
- package/dist/on-audio-track-handler.d.ts +2 -2
- package/dist/on-video-track-handler.d.ts +2 -2
- package/dist/select-container-creator.d.ts +1 -1
- package/dist/test/create-matroska.test.js +13 -12
- package/dist/test/remux-serverside.test.d.ts +1 -0
- package/dist/test/remux-serverside.test.js +23 -0
- package/dist/test/stsd.test.js +4 -9
- package/dist/writers/node.d.ts +4 -0
- package/dist/writers/node.js +74 -0
- package/dist/writers/web-fs.js +6 -3
- package/package.json +14 -5
|
@@ -11,6 +11,11 @@ const autoSelectWriter = async (writer, logLevel) => {
|
|
|
11
11
|
return writer;
|
|
12
12
|
}
|
|
13
13
|
log_1.Log.verbose(logLevel, 'Determining best writer');
|
|
14
|
+
const hasNavigator = typeof navigator !== 'undefined';
|
|
15
|
+
if (!hasNavigator) {
|
|
16
|
+
log_1.Log.verbose(logLevel, 'No navigator API detected, using buffer writer');
|
|
17
|
+
return buffer_1.bufferWriter;
|
|
18
|
+
}
|
|
14
19
|
// Check if we're offline using the navigator API
|
|
15
20
|
const isOffline = !navigator.onLine;
|
|
16
21
|
if (isOffline) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { MediaParserAudioCodec,
|
|
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:
|
|
6
|
+
inputContainer: MediaParserContainer;
|
|
7
7
|
}) => boolean;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type {
|
|
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:
|
|
5
|
+
inputContainer: MediaParserContainer;
|
|
6
6
|
inputTrack: VideoTrack;
|
|
7
7
|
rotationToApply: number;
|
|
8
8
|
outputContainer: ConvertMediaContainer;
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type { VideoTrack } from '@remotion/media-parser';
|
|
2
2
|
import type { ConvertMediaVideoCodec } from './get-available-video-codecs';
|
|
3
|
-
|
|
3
|
+
import type { ResizeOperation } from './resizing/mode';
|
|
4
|
+
export declare const canReencodeVideoTrack: ({ videoCodec, track, resizeOperation, rotate, }: {
|
|
4
5
|
videoCodec: ConvertMediaVideoCodec;
|
|
5
6
|
track: VideoTrack;
|
|
7
|
+
resizeOperation: ResizeOperation | null;
|
|
8
|
+
rotate: number | null;
|
|
6
9
|
}) => Promise<boolean>;
|
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.canReencodeVideoTrack = void 0;
|
|
4
|
+
const rotation_1 = require("./rotation");
|
|
4
5
|
const video_decoder_config_1 = require("./video-decoder-config");
|
|
5
6
|
const video_encoder_config_1 = require("./video-encoder-config");
|
|
6
|
-
const canReencodeVideoTrack = async ({ videoCodec, track, }) => {
|
|
7
|
-
const
|
|
8
|
-
codec: videoCodec,
|
|
7
|
+
const canReencodeVideoTrack = async ({ videoCodec, track, resizeOperation, rotate, }) => {
|
|
8
|
+
const { height, width } = (0, rotation_1.calculateNewDimensionsFromRotateAndScale)({
|
|
9
9
|
height: track.displayAspectHeight,
|
|
10
|
+
resizeOperation,
|
|
11
|
+
rotation: rotate !== null && rotate !== void 0 ? rotate : 0,
|
|
12
|
+
videoCodec,
|
|
10
13
|
width: track.displayAspectWidth,
|
|
14
|
+
});
|
|
15
|
+
const videoEncoderConfig = await (0, video_encoder_config_1.getVideoEncoderConfig)({
|
|
16
|
+
codec: videoCodec,
|
|
17
|
+
height,
|
|
18
|
+
width,
|
|
11
19
|
fps: track.fps,
|
|
12
20
|
});
|
|
13
21
|
const videoDecoderConfig = await (0, video_decoder_config_1.getVideoDecoderConfigWithHardwareAcceleration)(track);
|
package/dist/convert-media.d.ts
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
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,
|
|
5
|
+
import type { AudioTrack, LogLevel, Options, ParseMediaFields, ParseMediaOptions, VideoTrack } from '@remotion/media-parser';
|
|
6
|
+
import type { ParseMediaCallbacks } from '@remotion/media-parser';
|
|
6
7
|
import type { ConvertMediaAudioCodec } from './get-available-audio-codecs';
|
|
7
8
|
import type { ConvertMediaContainer } from './get-available-containers';
|
|
8
9
|
import type { ConvertMediaVideoCodec } from './get-available-video-codecs';
|
|
@@ -52,4 +53,5 @@ export declare const convertMedia: <F extends Options<ParseMediaFields>>({ src,
|
|
|
52
53
|
rotate?: number;
|
|
53
54
|
resize?: ResizeOperation;
|
|
54
55
|
apiKey?: string | null;
|
|
55
|
-
|
|
56
|
+
fields?: F;
|
|
57
|
+
} & ParseMediaCallbacks) => Promise<ConvertMediaResult>;
|
|
@@ -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 | 4 | 3 | 5 | 6;
|
|
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<{
|
|
@@ -15,6 +15,8 @@ const defaultOnVideoTrackHandler = async ({ track, defaultVideoCodec, logLevel,
|
|
|
15
15
|
const canReencode = await (0, can_reencode_video_track_1.canReencodeVideoTrack)({
|
|
16
16
|
videoCodec: defaultVideoCodec,
|
|
17
17
|
track,
|
|
18
|
+
resizeOperation,
|
|
19
|
+
rotate,
|
|
18
20
|
});
|
|
19
21
|
if (canReencode) {
|
|
20
22
|
media_parser_1.MediaParserInternals.Log.verbose(logLevel, `Track ${track.trackId} (video): Cannot copy, but re-enconde, therefore re-encoding`);
|
package/dist/esm/index.mjs
CHANGED
|
@@ -97,9 +97,12 @@ var createContent = async ({ filename }) => {
|
|
|
97
97
|
const directoryHandle = await navigator.storage.getDirectory();
|
|
98
98
|
const actualFilename = `__remotion_mediaparser:${filename}`;
|
|
99
99
|
const remove = async () => {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
100
|
+
try {
|
|
101
|
+
await directoryHandle.removeEntry(actualFilename, {
|
|
102
|
+
recursive: true
|
|
103
|
+
});
|
|
104
|
+
} catch {
|
|
105
|
+
}
|
|
103
106
|
};
|
|
104
107
|
await remove();
|
|
105
108
|
const fileHandle = await directoryHandle.getFileHandle(actualFilename, {
|
|
@@ -1082,12 +1085,21 @@ var getVideoEncoderConfig = async ({
|
|
|
1082
1085
|
// src/can-reencode-video-track.ts
|
|
1083
1086
|
var canReencodeVideoTrack = async ({
|
|
1084
1087
|
videoCodec,
|
|
1085
|
-
track
|
|
1088
|
+
track,
|
|
1089
|
+
resizeOperation,
|
|
1090
|
+
rotate
|
|
1086
1091
|
}) => {
|
|
1092
|
+
const { height, width } = calculateNewDimensionsFromRotateAndScale({
|
|
1093
|
+
height: track.displayAspectHeight,
|
|
1094
|
+
resizeOperation,
|
|
1095
|
+
rotation: rotate ?? 0,
|
|
1096
|
+
videoCodec,
|
|
1097
|
+
width: track.displayAspectWidth
|
|
1098
|
+
});
|
|
1087
1099
|
const videoEncoderConfig = await getVideoEncoderConfig({
|
|
1088
1100
|
codec: videoCodec,
|
|
1089
|
-
height
|
|
1090
|
-
width
|
|
1101
|
+
height,
|
|
1102
|
+
width,
|
|
1091
1103
|
fps: track.fps
|
|
1092
1104
|
});
|
|
1093
1105
|
const videoDecoderConfig = await getVideoDecoderConfigWithHardwareAcceleration(track);
|
|
@@ -1103,6 +1115,11 @@ var autoSelectWriter = async (writer, logLevel) => {
|
|
|
1103
1115
|
return writer;
|
|
1104
1116
|
}
|
|
1105
1117
|
Log.verbose(logLevel, "Determining best writer");
|
|
1118
|
+
const hasNavigator = typeof navigator !== "undefined";
|
|
1119
|
+
if (!hasNavigator) {
|
|
1120
|
+
Log.verbose(logLevel, "No navigator API detected, using buffer writer");
|
|
1121
|
+
return bufferWriter;
|
|
1122
|
+
}
|
|
1106
1123
|
const isOffline = !navigator.onLine;
|
|
1107
1124
|
if (isOffline) {
|
|
1108
1125
|
Log.verbose(logLevel, "Offline mode detected, using buffer writer");
|
|
@@ -1474,7 +1491,9 @@ var defaultOnVideoTrackHandler = async ({
|
|
|
1474
1491
|
}
|
|
1475
1492
|
const canReencode = await canReencodeVideoTrack({
|
|
1476
1493
|
videoCodec: defaultVideoCodec,
|
|
1477
|
-
track
|
|
1494
|
+
track,
|
|
1495
|
+
resizeOperation,
|
|
1496
|
+
rotate
|
|
1478
1497
|
});
|
|
1479
1498
|
if (canReencode) {
|
|
1480
1499
|
MediaParserInternals4.Log.verbose(logLevel, `Track ${track.trackId} (video): Cannot copy, but re-enconde, therefore re-encoding`);
|
|
@@ -3730,6 +3749,9 @@ var makeAudioCodecId = (codecId) => {
|
|
|
3730
3749
|
if (codecId === "vorbis") {
|
|
3731
3750
|
return "A_VORBIS";
|
|
3732
3751
|
}
|
|
3752
|
+
if (codecId === "flac") {
|
|
3753
|
+
return "A_FLAC";
|
|
3754
|
+
}
|
|
3733
3755
|
if (codecId === "pcm-u8") {
|
|
3734
3756
|
return "A_PCM/INT/LIT";
|
|
3735
3757
|
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
// src/writers/node.ts
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
var createContent = (filename) => {
|
|
4
|
+
return async () => {
|
|
5
|
+
const writPromise = Promise.resolve();
|
|
6
|
+
const remove = async () => {
|
|
7
|
+
await fs.promises.unlink(filename).catch(() => {
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
await remove();
|
|
11
|
+
if (!fs.existsSync(filename)) {
|
|
12
|
+
fs.writeFileSync(filename, "");
|
|
13
|
+
}
|
|
14
|
+
const writeStream = fs.openSync(filename, "w");
|
|
15
|
+
let written = 0;
|
|
16
|
+
const write = async (data) => {
|
|
17
|
+
await new Promise((resolve, reject) => {
|
|
18
|
+
fs.write(writeStream, data, 0, data.length, undefined, (err) => {
|
|
19
|
+
if (err) {
|
|
20
|
+
reject(err);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
resolve();
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
written += data.byteLength;
|
|
27
|
+
};
|
|
28
|
+
const updateDataAt = (position, data) => {
|
|
29
|
+
return new Promise((resolve, reject) => {
|
|
30
|
+
fs.write(writeStream, data, 0, data.length, position, (err) => {
|
|
31
|
+
if (err) {
|
|
32
|
+
reject(err);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
resolve();
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
|
+
const writer = {
|
|
40
|
+
write: (arr) => {
|
|
41
|
+
writPromise.then(() => write(arr));
|
|
42
|
+
return writPromise;
|
|
43
|
+
},
|
|
44
|
+
updateDataAt: (position, data) => {
|
|
45
|
+
writPromise.then(() => updateDataAt(position, data));
|
|
46
|
+
return writPromise;
|
|
47
|
+
},
|
|
48
|
+
waitForFinish: async () => {
|
|
49
|
+
await writPromise;
|
|
50
|
+
},
|
|
51
|
+
getWrittenByteCount: () => written,
|
|
52
|
+
remove,
|
|
53
|
+
save: async () => {
|
|
54
|
+
try {
|
|
55
|
+
fs.closeSync(writeStream);
|
|
56
|
+
const file = await fs.promises.readFile(filename);
|
|
57
|
+
return new Blob([file]);
|
|
58
|
+
} catch (e) {
|
|
59
|
+
return Promise.reject(e);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
return writer;
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
var nodeWriter = (path) => {
|
|
67
|
+
return { createContent: createContent(path) };
|
|
68
|
+
};
|
|
69
|
+
export {
|
|
70
|
+
nodeWriter
|
|
71
|
+
};
|
package/dist/esm/web-fs.mjs
CHANGED
|
@@ -21,9 +21,12 @@ var createContent = async ({ filename }) => {
|
|
|
21
21
|
const directoryHandle = await navigator.storage.getDirectory();
|
|
22
22
|
const actualFilename = `__remotion_mediaparser:${filename}`;
|
|
23
23
|
const remove = async () => {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
try {
|
|
25
|
+
await directoryHandle.removeEntry(actualFilename, {
|
|
26
|
+
recursive: true
|
|
27
|
+
});
|
|
28
|
+
} catch {
|
|
29
|
+
}
|
|
27
30
|
};
|
|
28
31
|
await remove();
|
|
29
32
|
const fileHandle = await directoryHandle.getFileHandle(actualFilename, {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AudioTrack, LogLevel,
|
|
1
|
+
import type { AudioTrack, LogLevel, MediaParserContainer } from '@remotion/media-parser';
|
|
2
2
|
import type { ConvertMediaAudioCodec } from './get-available-audio-codecs';
|
|
3
3
|
import type { ConvertMediaContainer } from './get-available-containers';
|
|
4
4
|
export type AudioOperation = {
|
|
@@ -17,6 +17,6 @@ export type ConvertMediaOnAudioTrackHandler = (options: {
|
|
|
17
17
|
defaultAudioCodec: ConvertMediaAudioCodec | null;
|
|
18
18
|
logLevel: LogLevel;
|
|
19
19
|
outputContainer: ConvertMediaContainer;
|
|
20
|
-
inputContainer:
|
|
20
|
+
inputContainer: MediaParserContainer;
|
|
21
21
|
canCopyTrack: boolean;
|
|
22
22
|
}) => AudioOperation | Promise<AudioOperation>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { LogLevel,
|
|
1
|
+
import type { LogLevel, MediaParserContainer, VideoTrack } from '@remotion/media-parser';
|
|
2
2
|
import type { ConvertMediaContainer } from './get-available-containers';
|
|
3
3
|
import type { ConvertMediaVideoCodec } from './get-available-video-codecs';
|
|
4
4
|
import type { ResizeOperation } from './resizing/mode';
|
|
@@ -21,6 +21,6 @@ export type ConvertMediaOnVideoTrackHandler = (options: {
|
|
|
21
21
|
outputContainer: ConvertMediaContainer;
|
|
22
22
|
rotate: number;
|
|
23
23
|
resizeOperation: ResizeOperation | null;
|
|
24
|
-
inputContainer:
|
|
24
|
+
inputContainer: MediaParserContainer;
|
|
25
25
|
canCopyTrack: boolean;
|
|
26
26
|
}) => VideoOperation | Promise<VideoOperation>;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { ConvertMediaContainer } from './get-available-containers';
|
|
2
|
-
export declare const selectContainerCreator: (container: ConvertMediaContainer) => ({
|
|
2
|
+
export declare const selectContainerCreator: (container: ConvertMediaContainer) => ({ writer, onBytesProgress, onMillisecondsProgress, logLevel, filename, progressTracker, }: import("./create/media-fn").MediaFnGeneratorInput) => Promise<import("./create/media-fn").MediaFn>;
|
|
@@ -3,17 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const media_parser_1 = require("@remotion/media-parser");
|
|
4
4
|
const bun_test_1 = require("bun:test");
|
|
5
5
|
const matroska_utils_1 = require("../create/matroska/matroska-utils");
|
|
6
|
-
const state = media_parser_1.MediaParserInternals.makeParserState({
|
|
7
|
-
hasAudioTrackHandlers: false,
|
|
8
|
-
hasVideoTrackHandlers: false,
|
|
9
|
-
signal: undefined,
|
|
10
|
-
getIterator: () => null,
|
|
11
|
-
fields: {},
|
|
12
|
-
onAudioTrack: null,
|
|
13
|
-
onVideoTrack: null,
|
|
14
|
-
supportsContentRange: true,
|
|
15
|
-
contentLength: null,
|
|
16
|
-
});
|
|
17
6
|
(0, bun_test_1.test)('Should make Matroska header that is same as input', async () => {
|
|
18
7
|
const headerOutput = (0, matroska_utils_1.makeMatroskaBytes)({
|
|
19
8
|
type: 'Header',
|
|
@@ -57,7 +46,19 @@ const state = media_parser_1.MediaParserInternals.makeParserState({
|
|
|
57
46
|
],
|
|
58
47
|
});
|
|
59
48
|
const iterator = media_parser_1.MediaParserInternals.getArrayBufferIterator(headerOutput.bytes, headerOutput.bytes.length);
|
|
60
|
-
const
|
|
49
|
+
const state = media_parser_1.MediaParserInternals.makeParserState({
|
|
50
|
+
hasAudioTrackHandlers: false,
|
|
51
|
+
hasVideoTrackHandlers: false,
|
|
52
|
+
signal: undefined,
|
|
53
|
+
iterator,
|
|
54
|
+
fields: {},
|
|
55
|
+
onAudioTrack: null,
|
|
56
|
+
onVideoTrack: null,
|
|
57
|
+
supportsContentRange: true,
|
|
58
|
+
contentLength: null,
|
|
59
|
+
logLevel: 'info',
|
|
60
|
+
});
|
|
61
|
+
const parsed = await media_parser_1.MediaParserInternals.parseEbml(state);
|
|
61
62
|
(0, bun_test_1.expect)(parsed).toEqual({
|
|
62
63
|
type: 'Header',
|
|
63
64
|
minVintWidth: 1,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const example_videos_1 = require("@remotion/example-videos");
|
|
4
|
+
const node_1 = require("@remotion/media-parser/node");
|
|
5
|
+
const bun_test_1 = require("bun:test");
|
|
6
|
+
const node_fs_1 = require("node:fs");
|
|
7
|
+
const convert_media_1 = require("../convert-media");
|
|
8
|
+
const node_2 = require("../writers/node");
|
|
9
|
+
(0, bun_test_1.test)('should be able to remux server side', async () => {
|
|
10
|
+
// bun file descriptor problem
|
|
11
|
+
if (process.platform === 'win32') {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
const { save } = await (0, convert_media_1.convertMedia)({
|
|
15
|
+
src: example_videos_1.exampleVideos.bigBuckBunny,
|
|
16
|
+
reader: node_1.nodeReader,
|
|
17
|
+
container: 'mp4',
|
|
18
|
+
writer: (0, node_2.nodeWriter)('outputbun.mp4'),
|
|
19
|
+
});
|
|
20
|
+
const data = await save();
|
|
21
|
+
(0, bun_test_1.expect)(data.size).toBe(15306323);
|
|
22
|
+
(0, node_fs_1.unlinkSync)('outputbun.mp4');
|
|
23
|
+
});
|
package/dist/test/stsd.test.js
CHANGED
|
@@ -35,7 +35,6 @@ const bun_test_1 = require("bun:test");
|
|
|
35
35
|
const iterator = media_parser_1.MediaParserInternals.getArrayBufferIterator(buffer, null);
|
|
36
36
|
iterator.discard(8);
|
|
37
37
|
const parsed = await media_parser_1.MediaParserInternals.parseStsd({
|
|
38
|
-
iterator,
|
|
39
38
|
offset: 0,
|
|
40
39
|
size: 159,
|
|
41
40
|
state: media_parser_1.MediaParserInternals.makeParserState({
|
|
@@ -44,13 +43,12 @@ const bun_test_1 = require("bun:test");
|
|
|
44
43
|
hasAudioTrackHandlers: true,
|
|
45
44
|
hasVideoTrackHandlers: true,
|
|
46
45
|
signal: undefined,
|
|
47
|
-
|
|
46
|
+
iterator,
|
|
48
47
|
fields: {},
|
|
49
48
|
supportsContentRange: true,
|
|
50
49
|
contentLength: null,
|
|
50
|
+
logLevel: 'info',
|
|
51
51
|
}),
|
|
52
|
-
signal: null,
|
|
53
|
-
fields: {},
|
|
54
52
|
});
|
|
55
53
|
(0, bun_test_1.expect)(parsed).toEqual({
|
|
56
54
|
offset: 0,
|
|
@@ -203,23 +201,20 @@ const bun_test_1 = require("bun:test");
|
|
|
203
201
|
0, 0, 0, 16, 112, 97, 115, 112, 0, 0, 0, 1, 0, 0, 0, 1,
|
|
204
202
|
]);
|
|
205
203
|
const parsed = await media_parser_1.MediaParserInternals.processSample({
|
|
206
|
-
iterator: media_parser_1.MediaParserInternals.getArrayBufferIterator(buffer, null),
|
|
207
204
|
state: media_parser_1.MediaParserInternals.makeParserState({
|
|
208
205
|
onAudioTrack: null,
|
|
209
206
|
onVideoTrack: () => () => undefined,
|
|
210
207
|
hasAudioTrackHandlers: true,
|
|
211
208
|
hasVideoTrackHandlers: true,
|
|
212
209
|
signal: undefined,
|
|
213
|
-
|
|
210
|
+
iterator: media_parser_1.MediaParserInternals.getArrayBufferIterator(buffer, null),
|
|
214
211
|
fields: {
|
|
215
212
|
structure: true,
|
|
216
213
|
},
|
|
217
214
|
supportsContentRange: true,
|
|
218
215
|
contentLength: null,
|
|
216
|
+
logLevel: 'info',
|
|
219
217
|
}),
|
|
220
|
-
signal: null,
|
|
221
|
-
logLevel: 'info',
|
|
222
|
-
fields: {},
|
|
223
218
|
});
|
|
224
219
|
(0, bun_test_1.expect)(parsed.sample).toEqual({
|
|
225
220
|
size: 158,
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.nodeWriter = void 0;
|
|
7
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
|
+
const createContent = (filename) => {
|
|
9
|
+
return async () => {
|
|
10
|
+
const writPromise = Promise.resolve();
|
|
11
|
+
const remove = async () => {
|
|
12
|
+
await node_fs_1.default.promises.unlink(filename).catch(() => { });
|
|
13
|
+
};
|
|
14
|
+
await remove();
|
|
15
|
+
if (!node_fs_1.default.existsSync(filename)) {
|
|
16
|
+
node_fs_1.default.writeFileSync(filename, '');
|
|
17
|
+
}
|
|
18
|
+
const writeStream = node_fs_1.default.openSync(filename, 'w');
|
|
19
|
+
let written = 0;
|
|
20
|
+
const write = async (data) => {
|
|
21
|
+
await new Promise((resolve, reject) => {
|
|
22
|
+
node_fs_1.default.write(writeStream, data, 0, data.length, undefined, (err) => {
|
|
23
|
+
if (err) {
|
|
24
|
+
reject(err);
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
resolve();
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
written += data.byteLength;
|
|
31
|
+
};
|
|
32
|
+
const updateDataAt = (position, data) => {
|
|
33
|
+
return new Promise((resolve, reject) => {
|
|
34
|
+
node_fs_1.default.write(writeStream, data, 0, data.length, position, (err) => {
|
|
35
|
+
if (err) {
|
|
36
|
+
reject(err);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
resolve();
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
};
|
|
43
|
+
const writer = {
|
|
44
|
+
write: (arr) => {
|
|
45
|
+
writPromise.then(() => write(arr));
|
|
46
|
+
return writPromise;
|
|
47
|
+
},
|
|
48
|
+
updateDataAt: (position, data) => {
|
|
49
|
+
writPromise.then(() => updateDataAt(position, data));
|
|
50
|
+
return writPromise;
|
|
51
|
+
},
|
|
52
|
+
waitForFinish: async () => {
|
|
53
|
+
await writPromise;
|
|
54
|
+
},
|
|
55
|
+
getWrittenByteCount: () => written,
|
|
56
|
+
remove,
|
|
57
|
+
save: async () => {
|
|
58
|
+
try {
|
|
59
|
+
node_fs_1.default.closeSync(writeStream);
|
|
60
|
+
const file = await node_fs_1.default.promises.readFile(filename);
|
|
61
|
+
return new Blob([file]);
|
|
62
|
+
}
|
|
63
|
+
catch (e) {
|
|
64
|
+
return Promise.reject(e);
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
return writer;
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
const nodeWriter = (path) => {
|
|
72
|
+
return { createContent: createContent(path) };
|
|
73
|
+
};
|
|
74
|
+
exports.nodeWriter = nodeWriter;
|
package/dist/writers/web-fs.js
CHANGED
|
@@ -5,9 +5,12 @@ const createContent = async ({ filename }) => {
|
|
|
5
5
|
const directoryHandle = await navigator.storage.getDirectory();
|
|
6
6
|
const actualFilename = `__remotion_mediaparser:${filename}`;
|
|
7
7
|
const remove = async () => {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
try {
|
|
9
|
+
await directoryHandle.removeEntry(actualFilename, {
|
|
10
|
+
recursive: true,
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
catch (_a) { }
|
|
11
14
|
};
|
|
12
15
|
await remove();
|
|
13
16
|
const fileHandle = await directoryHandle.getFileHandle(actualFilename, {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remotion/webcodecs",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.251",
|
|
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.
|
|
21
|
-
"@remotion/licensing": "4.0.
|
|
20
|
+
"@remotion/media-parser": "4.0.251",
|
|
21
|
+
"@remotion/licensing": "4.0.251"
|
|
22
22
|
},
|
|
23
23
|
"peerDependencies": {},
|
|
24
24
|
"devDependencies": {
|
|
25
25
|
"@types/dom-webcodecs": "0.1.11",
|
|
26
26
|
"eslint": "9.14.0",
|
|
27
|
-
"@remotion/
|
|
28
|
-
"@remotion/
|
|
27
|
+
"@remotion/example-videos": "4.0.251",
|
|
28
|
+
"@remotion/eslint-config-internal": "4.0.251"
|
|
29
29
|
},
|
|
30
30
|
"keywords": [],
|
|
31
31
|
"publishConfig": {
|
|
@@ -50,6 +50,12 @@
|
|
|
50
50
|
"module": "./dist/esm/buffer.mjs",
|
|
51
51
|
"import": "./dist/esm/buffer.mjs"
|
|
52
52
|
},
|
|
53
|
+
"./node": {
|
|
54
|
+
"types": "./dist/writers/node.d.ts",
|
|
55
|
+
"require": "./dist/writers/node.js",
|
|
56
|
+
"module": "./dist/esm/node.mjs",
|
|
57
|
+
"import": "./dist/esm/node.mjs"
|
|
58
|
+
},
|
|
53
59
|
"./package.json": "./package.json"
|
|
54
60
|
},
|
|
55
61
|
"typesVersions": {
|
|
@@ -57,6 +63,9 @@
|
|
|
57
63
|
"web-fs": [
|
|
58
64
|
"dist/writers/web-fs.d.ts"
|
|
59
65
|
],
|
|
66
|
+
"node": [
|
|
67
|
+
"dist/writers/node.d.ts"
|
|
68
|
+
],
|
|
60
69
|
"buffer": [
|
|
61
70
|
"dist/writers/buffer.d.ts"
|
|
62
71
|
]
|