@remotion/webcodecs 4.0.232 → 4.0.234
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/README.md +2 -2
- package/dist/audio-decoder-config.d.ts +2 -1
- package/dist/audio-decoder-config.js +44 -3
- package/dist/audio-decoder.d.ts +6 -3
- package/dist/audio-decoder.js +20 -4
- package/dist/audio-encoder.d.ts +3 -2
- package/dist/audio-encoder.js +11 -3
- package/dist/browser-quirks.d.ts +1 -0
- package/dist/browser-quirks.js +5 -1
- package/dist/can-copy-video-track.d.ts +3 -1
- package/dist/can-copy-video-track.js +6 -1
- package/dist/can-reencode-audio-track.d.ts +3 -2
- package/dist/can-reencode-audio-track.js +2 -2
- package/dist/convert-media.d.ts +2 -1
- package/dist/convert-media.js +7 -3
- package/dist/convert-to-correct-videoframe.js +4 -0
- package/dist/default-on-video-track-handler.js +8 -2
- package/dist/esm/index.mjs +352 -137
- package/dist/get-wave-audio-decoder.d.ts +2 -0
- package/dist/get-wave-audio-decoder.js +29 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +6 -1
- package/dist/io-manager/event-emitter.d.ts +4 -0
- package/dist/io-manager/event-emitter.js +1 -0
- package/dist/io-manager/io-synchronizer.d.ts +8 -2
- package/dist/io-manager/io-synchronizer.js +31 -20
- package/dist/io-manager/make-timeout-promise.d.ts +4 -0
- package/dist/io-manager/make-timeout-promise.js +18 -0
- package/dist/on-audio-track.d.ts +3 -2
- package/dist/on-audio-track.js +6 -3
- package/dist/on-frame.d.ts +2 -1
- package/dist/on-frame.js +25 -14
- package/dist/on-video-track-handler.d.ts +2 -0
- package/dist/on-video-track.d.ts +4 -2
- package/dist/on-video-track.js +21 -5
- package/dist/rotate-video-frame.d.ts +5 -0
- package/dist/rotate-video-frame.js +48 -0
- package/dist/rotate-video.d.ts +4 -0
- package/dist/rotate-video.js +43 -0
- package/dist/rotation.d.ts +8 -0
- package/dist/rotation.js +10 -0
- package/dist/select-container-creator.d.ts +1 -1
- package/dist/test/avi-to-mp4.test.js +15 -0
- package/dist/video-decoder.d.ts +3 -2
- package/dist/video-decoder.js +11 -3
- package/dist/video-encoder.d.ts +3 -2
- package/dist/video-encoder.js +7 -2
- package/package.json +5 -3
package/dist/esm/index.mjs
CHANGED
|
@@ -1,3 +1,59 @@
|
|
|
1
|
+
// src/rotation.ts
|
|
2
|
+
var calculateNewDimensionsFromDimensions = ({
|
|
3
|
+
width,
|
|
4
|
+
height,
|
|
5
|
+
rotation
|
|
6
|
+
}) => {
|
|
7
|
+
const switchDimensions = rotation % 90 === 0 && rotation % 180 !== 0;
|
|
8
|
+
const newHeight = switchDimensions ? width : height;
|
|
9
|
+
const newWidth = switchDimensions ? height : width;
|
|
10
|
+
return { height: newHeight, width: newWidth };
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
// src/rotate-video-frame.ts
|
|
14
|
+
var normalizeVideoRotation = (rotation) => {
|
|
15
|
+
return (rotation % 360 + 360) % 360;
|
|
16
|
+
};
|
|
17
|
+
var rotateVideoFrame = ({
|
|
18
|
+
frame,
|
|
19
|
+
rotation
|
|
20
|
+
}) => {
|
|
21
|
+
const normalized = (rotation % 360 + 360) % 360;
|
|
22
|
+
if (normalized % 360 === 0) {
|
|
23
|
+
return frame;
|
|
24
|
+
}
|
|
25
|
+
if (normalized % 90 !== 0) {
|
|
26
|
+
throw new Error("Only 90 degree rotations are supported");
|
|
27
|
+
}
|
|
28
|
+
const { height, width } = calculateNewDimensionsFromDimensions({
|
|
29
|
+
height: frame.displayHeight,
|
|
30
|
+
width: frame.displayWidth,
|
|
31
|
+
rotation
|
|
32
|
+
});
|
|
33
|
+
const canvas = new OffscreenCanvas(width, height);
|
|
34
|
+
const ctx = canvas.getContext("2d");
|
|
35
|
+
if (!ctx) {
|
|
36
|
+
throw new Error("Could not get 2d context");
|
|
37
|
+
}
|
|
38
|
+
canvas.width = width;
|
|
39
|
+
canvas.height = height;
|
|
40
|
+
if (normalized === 90) {
|
|
41
|
+
ctx.translate(width, 0);
|
|
42
|
+
} else if (normalized === 180) {
|
|
43
|
+
ctx.translate(width, height);
|
|
44
|
+
} else if (normalized === 270) {
|
|
45
|
+
ctx.translate(0, height);
|
|
46
|
+
}
|
|
47
|
+
ctx.rotate(normalized * (Math.PI / 180));
|
|
48
|
+
ctx.drawImage(frame, 0, 0);
|
|
49
|
+
return new VideoFrame(canvas, {
|
|
50
|
+
displayHeight: height,
|
|
51
|
+
displayWidth: width,
|
|
52
|
+
duration: frame.duration ?? undefined,
|
|
53
|
+
timestamp: frame.timestamp
|
|
54
|
+
});
|
|
55
|
+
};
|
|
56
|
+
|
|
1
57
|
// src/set-remotion-imported.ts
|
|
2
58
|
import { VERSION } from "@remotion/media-parser";
|
|
3
59
|
var setRemotionImported = () => {
|
|
@@ -13,58 +69,65 @@ var setRemotionImported = () => {
|
|
|
13
69
|
}
|
|
14
70
|
};
|
|
15
71
|
|
|
16
|
-
// src/
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
const { promise: returnPromise, resolve: resolveReturn } = withResolvers();
|
|
72
|
+
// src/get-wave-audio-decoder.ts
|
|
73
|
+
var getWaveAudioDecoder = ({
|
|
74
|
+
onFrame,
|
|
75
|
+
track
|
|
76
|
+
}) => {
|
|
77
|
+
let queue = Promise.resolve();
|
|
78
|
+
const processSample = async (audioSample) => {
|
|
79
|
+
await onFrame(new AudioData({
|
|
80
|
+
data: audioSample.data,
|
|
81
|
+
format: "s16",
|
|
82
|
+
numberOfChannels: track.numberOfChannels,
|
|
83
|
+
numberOfFrames: audioSample.data.byteLength / 2,
|
|
84
|
+
sampleRate: track.sampleRate,
|
|
85
|
+
timestamp: audioSample.timestamp
|
|
86
|
+
}));
|
|
87
|
+
};
|
|
33
88
|
return {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
return promise;
|
|
89
|
+
close() {
|
|
90
|
+
return Promise.resolve();
|
|
37
91
|
},
|
|
38
|
-
|
|
39
|
-
|
|
92
|
+
processSample(audioSample) {
|
|
93
|
+
queue = queue.then(() => processSample(audioSample));
|
|
94
|
+
return queue;
|
|
40
95
|
},
|
|
41
|
-
resolve
|
|
96
|
+
flush: () => Promise.resolve(),
|
|
97
|
+
waitForFinish: () => Promise.resolve()
|
|
42
98
|
};
|
|
43
99
|
};
|
|
44
100
|
|
|
45
|
-
// src/io-manager/
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
101
|
+
// src/io-manager/io-synchronizer.ts
|
|
102
|
+
import { MediaParserInternals as MediaParserInternals3 } from "@remotion/media-parser";
|
|
103
|
+
|
|
104
|
+
// src/log.ts
|
|
105
|
+
import { MediaParserInternals } from "@remotion/media-parser";
|
|
106
|
+
var { Log } = MediaParserInternals;
|
|
107
|
+
|
|
108
|
+
// src/io-manager/make-timeout-promise.ts
|
|
109
|
+
import { MediaParserInternals as MediaParserInternals2 } from "@remotion/media-parser";
|
|
110
|
+
var makeTimeoutPromise = (label, ms) => {
|
|
111
|
+
const { promise, reject, resolve } = MediaParserInternals2.withResolvers();
|
|
112
|
+
const timeout = setTimeout(() => {
|
|
113
|
+
reject(new Error(`${label} (timed out after ${ms}ms)`));
|
|
114
|
+
}, ms);
|
|
115
|
+
return {
|
|
116
|
+
timeoutPromise: promise,
|
|
117
|
+
clear: () => {
|
|
118
|
+
clearTimeout(timeout);
|
|
119
|
+
resolve();
|
|
120
|
+
}
|
|
51
121
|
};
|
|
52
|
-
|
|
53
|
-
this.listeners[name].push(callback);
|
|
54
|
-
}
|
|
55
|
-
removeEventListener(name, callback) {
|
|
56
|
-
this.listeners[name] = this.listeners[name].filter((l) => l !== callback);
|
|
57
|
-
}
|
|
58
|
-
dispatchEvent(dispatchName, context) {
|
|
59
|
-
this.listeners[dispatchName].forEach((callback) => {
|
|
60
|
-
callback({ detail: context });
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
}
|
|
122
|
+
};
|
|
64
123
|
|
|
65
124
|
// src/io-manager/io-synchronizer.ts
|
|
66
|
-
var makeIoSynchronizer = (
|
|
67
|
-
|
|
125
|
+
var makeIoSynchronizer = ({
|
|
126
|
+
logLevel,
|
|
127
|
+
label,
|
|
128
|
+
progress
|
|
129
|
+
}) => {
|
|
130
|
+
const eventEmitter = new MediaParserInternals3.IoEventEmitter;
|
|
68
131
|
let lastInput = 0;
|
|
69
132
|
let lastInputKeyframe = 0;
|
|
70
133
|
let lastOutput = 0;
|
|
@@ -108,7 +171,7 @@ var makeIoSynchronizer = (logLevel, label) => {
|
|
|
108
171
|
printState("Got output");
|
|
109
172
|
};
|
|
110
173
|
const waitForOutput = () => {
|
|
111
|
-
const { promise, resolve } = withResolvers();
|
|
174
|
+
const { promise, resolve } = MediaParserInternals3.withResolvers();
|
|
112
175
|
const on = () => {
|
|
113
176
|
eventEmitter.removeEventListener("output", on);
|
|
114
177
|
resolve();
|
|
@@ -117,7 +180,7 @@ var makeIoSynchronizer = (logLevel, label) => {
|
|
|
117
180
|
return promise;
|
|
118
181
|
};
|
|
119
182
|
const waitForProcessed = () => {
|
|
120
|
-
const { promise, resolve } = withResolvers();
|
|
183
|
+
const { promise, resolve } = MediaParserInternals3.withResolvers();
|
|
121
184
|
const on = () => {
|
|
122
185
|
eventEmitter.removeEventListener("processed", on);
|
|
123
186
|
resolve();
|
|
@@ -127,23 +190,33 @@ var makeIoSynchronizer = (logLevel, label) => {
|
|
|
127
190
|
};
|
|
128
191
|
const waitFor = async ({
|
|
129
192
|
_unprocessed,
|
|
130
|
-
unemitted
|
|
193
|
+
unemitted,
|
|
194
|
+
minimumProgress
|
|
131
195
|
}) => {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
196
|
+
const { timeoutPromise, clear } = makeTimeoutPromise(`Waited too long for ${label}`, 1e4);
|
|
197
|
+
await Promise.race([
|
|
198
|
+
timeoutPromise,
|
|
199
|
+
Promise.all([
|
|
200
|
+
(async () => {
|
|
201
|
+
while (getUnemittedItems() > unemitted) {
|
|
202
|
+
await waitForOutput();
|
|
203
|
+
}
|
|
204
|
+
})(),
|
|
205
|
+
(async () => {
|
|
206
|
+
while (getUnprocessed() > _unprocessed) {
|
|
207
|
+
await waitForProcessed();
|
|
208
|
+
}
|
|
209
|
+
})(),
|
|
210
|
+
minimumProgress === null ? Promise.resolve() : (async () => {
|
|
211
|
+
while (progress.getSmallestProgress() < minimumProgress) {
|
|
212
|
+
await progress.waitForProgress();
|
|
213
|
+
}
|
|
214
|
+
})()
|
|
215
|
+
])
|
|
216
|
+
]).finally(() => clear());
|
|
144
217
|
};
|
|
145
218
|
const waitForFinish = async () => {
|
|
146
|
-
await waitFor({ _unprocessed: 0, unemitted: 0 });
|
|
219
|
+
await waitFor({ _unprocessed: 0, unemitted: 0, minimumProgress: null });
|
|
147
220
|
};
|
|
148
221
|
const onProcessed = () => {
|
|
149
222
|
eventEmitter.dispatchEvent("processed", {});
|
|
@@ -165,12 +238,21 @@ var createAudioDecoder = ({
|
|
|
165
238
|
onError,
|
|
166
239
|
signal,
|
|
167
240
|
config,
|
|
168
|
-
logLevel
|
|
241
|
+
logLevel,
|
|
242
|
+
track,
|
|
243
|
+
progressTracker
|
|
169
244
|
}) => {
|
|
170
245
|
if (signal.aborted) {
|
|
171
246
|
throw new Error("Not creating audio decoder, already aborted");
|
|
172
247
|
}
|
|
173
|
-
|
|
248
|
+
if (config.codec === "pcm-s16") {
|
|
249
|
+
return getWaveAudioDecoder({ onFrame, track });
|
|
250
|
+
}
|
|
251
|
+
const ioSynchronizer = makeIoSynchronizer({
|
|
252
|
+
logLevel,
|
|
253
|
+
label: "Audio decoder",
|
|
254
|
+
progress: progressTracker
|
|
255
|
+
});
|
|
174
256
|
let outputQueue = Promise.resolve();
|
|
175
257
|
const audioDecoder = new AudioDecoder({
|
|
176
258
|
output(inputFrame) {
|
|
@@ -213,7 +295,11 @@ var createAudioDecoder = ({
|
|
|
213
295
|
if (audioDecoder.state === "closed") {
|
|
214
296
|
return;
|
|
215
297
|
}
|
|
216
|
-
await ioSynchronizer.waitFor({
|
|
298
|
+
await ioSynchronizer.waitFor({
|
|
299
|
+
unemitted: 20,
|
|
300
|
+
_unprocessed: 20,
|
|
301
|
+
minimumProgress: audioSample.timestamp - 1e7
|
|
302
|
+
});
|
|
217
303
|
const chunk = new EncodedAudioChunk(audioSample);
|
|
218
304
|
audioDecoder.decode(chunk);
|
|
219
305
|
ioSynchronizer.inputItem(chunk.timestamp, audioSample.type === "key");
|
|
@@ -228,7 +314,10 @@ var createAudioDecoder = ({
|
|
|
228
314
|
return queue;
|
|
229
315
|
},
|
|
230
316
|
waitForFinish: async () => {
|
|
231
|
-
|
|
317
|
+
try {
|
|
318
|
+
await audioDecoder.flush();
|
|
319
|
+
} catch {
|
|
320
|
+
}
|
|
232
321
|
await queue;
|
|
233
322
|
await ioSynchronizer.waitForFinish();
|
|
234
323
|
await outputQueue;
|
|
@@ -274,7 +363,8 @@ var createAudioEncoder = ({
|
|
|
274
363
|
signal,
|
|
275
364
|
config: audioEncoderConfig,
|
|
276
365
|
logLevel,
|
|
277
|
-
onNewAudioSampleRate
|
|
366
|
+
onNewAudioSampleRate,
|
|
367
|
+
progressTracker
|
|
278
368
|
}) => {
|
|
279
369
|
if (signal.aborted) {
|
|
280
370
|
throw new Error("Not creating audio encoder, already aborted");
|
|
@@ -282,7 +372,11 @@ var createAudioEncoder = ({
|
|
|
282
372
|
if (codec === "wav") {
|
|
283
373
|
return getWaveAudioEncoder({ onChunk, signal });
|
|
284
374
|
}
|
|
285
|
-
const ioSynchronizer = makeIoSynchronizer(
|
|
375
|
+
const ioSynchronizer = makeIoSynchronizer({
|
|
376
|
+
logLevel,
|
|
377
|
+
label: "Audio encoder",
|
|
378
|
+
progress: progressTracker
|
|
379
|
+
});
|
|
286
380
|
let prom = Promise.resolve();
|
|
287
381
|
const encoder = new AudioEncoder({
|
|
288
382
|
output: (chunk) => {
|
|
@@ -322,7 +416,11 @@ var createAudioEncoder = ({
|
|
|
322
416
|
if (encoder.state === "closed") {
|
|
323
417
|
return;
|
|
324
418
|
}
|
|
325
|
-
await ioSynchronizer.waitFor({
|
|
419
|
+
await ioSynchronizer.waitFor({
|
|
420
|
+
unemitted: 20,
|
|
421
|
+
_unprocessed: 20,
|
|
422
|
+
minimumProgress: audioData.timestamp - 1e7
|
|
423
|
+
});
|
|
326
424
|
if (encoder.state === "closed") {
|
|
327
425
|
return;
|
|
328
426
|
}
|
|
@@ -376,8 +474,13 @@ var canCopyAudioTrack = ({
|
|
|
376
474
|
// src/can-copy-video-track.ts
|
|
377
475
|
var canCopyVideoTrack = ({
|
|
378
476
|
inputCodec,
|
|
379
|
-
container
|
|
477
|
+
container,
|
|
478
|
+
inputRotation,
|
|
479
|
+
rotationToApply
|
|
380
480
|
}) => {
|
|
481
|
+
if (normalizeVideoRotation(inputRotation) !== normalizeVideoRotation(rotationToApply)) {
|
|
482
|
+
return false;
|
|
483
|
+
}
|
|
381
484
|
if (container === "webm") {
|
|
382
485
|
return inputCodec === "vp8" || inputCodec === "vp9";
|
|
383
486
|
}
|
|
@@ -389,16 +492,68 @@ var canCopyVideoTrack = ({
|
|
|
389
492
|
}
|
|
390
493
|
throw new Error(`Unhandled codec: ${container}`);
|
|
391
494
|
};
|
|
495
|
+
// src/browser-quirks.ts
|
|
496
|
+
var isFirefox = () => {
|
|
497
|
+
return navigator.userAgent.toLowerCase().indexOf("firefox") > -1;
|
|
498
|
+
};
|
|
499
|
+
var isSafari = () => {
|
|
500
|
+
return /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
|
|
501
|
+
};
|
|
502
|
+
var isChrome = () => {
|
|
503
|
+
return navigator.userAgent.toLowerCase().indexOf("chrome") > -1;
|
|
504
|
+
};
|
|
505
|
+
|
|
392
506
|
// src/audio-decoder-config.ts
|
|
393
|
-
var
|
|
507
|
+
var overrideBrowserQuirks = ({
|
|
508
|
+
config,
|
|
509
|
+
logLevel
|
|
510
|
+
}) => {
|
|
511
|
+
const bytes = config.description;
|
|
512
|
+
if (!bytes) {
|
|
513
|
+
return config;
|
|
514
|
+
}
|
|
515
|
+
if (bytes[0] === 18 && bytes[1] === 8) {
|
|
516
|
+
if (isFirefox()) {
|
|
517
|
+
return {
|
|
518
|
+
...config,
|
|
519
|
+
codec: "mp4a.40.2",
|
|
520
|
+
description: bytes
|
|
521
|
+
};
|
|
522
|
+
}
|
|
523
|
+
if (!isChrome()) {
|
|
524
|
+
return config;
|
|
525
|
+
}
|
|
526
|
+
Log.warn(logLevel, "Chrome has a bug and might not be able to decode this audio. It will be fixed, see: https://issues.chromium.org/issues/360083330");
|
|
527
|
+
return {
|
|
528
|
+
...config,
|
|
529
|
+
description: new Uint8Array([18, 16])
|
|
530
|
+
};
|
|
531
|
+
}
|
|
532
|
+
if (bytes.byteLength === 2 && bytes[0] === 17 && bytes[1] === 136) {
|
|
533
|
+
Log.warn(logLevel, "Chrome has a bug and might not be able to decode this audio. It will be fixed, see: https://issues.chromium.org/issues/360083330");
|
|
534
|
+
return {
|
|
535
|
+
...config,
|
|
536
|
+
description: new Uint8Array([18, 144])
|
|
537
|
+
};
|
|
538
|
+
}
|
|
539
|
+
return config;
|
|
540
|
+
};
|
|
541
|
+
var getAudioDecoderConfig = async (config, logLevel) => {
|
|
542
|
+
if (config.codec === "pcm-s16") {
|
|
543
|
+
return config;
|
|
544
|
+
}
|
|
394
545
|
if (typeof AudioDecoder === "undefined") {
|
|
395
546
|
return null;
|
|
396
547
|
}
|
|
397
548
|
if (typeof EncodedAudioChunk === "undefined") {
|
|
398
549
|
return null;
|
|
399
550
|
}
|
|
400
|
-
|
|
401
|
-
|
|
551
|
+
const realConfig = overrideBrowserQuirks({
|
|
552
|
+
config,
|
|
553
|
+
logLevel
|
|
554
|
+
});
|
|
555
|
+
if ((await AudioDecoder.isConfigSupported(realConfig)).supported) {
|
|
556
|
+
return realConfig;
|
|
402
557
|
}
|
|
403
558
|
return null;
|
|
404
559
|
};
|
|
@@ -437,9 +592,10 @@ var getAudioEncoderConfig = async (config) => {
|
|
|
437
592
|
var canReencodeAudioTrack = async ({
|
|
438
593
|
track,
|
|
439
594
|
audioCodec,
|
|
440
|
-
bitrate
|
|
595
|
+
bitrate,
|
|
596
|
+
logLevel = "info"
|
|
441
597
|
}) => {
|
|
442
|
-
const audioDecoderConfig = await getAudioDecoderConfig(track);
|
|
598
|
+
const audioDecoderConfig = await getAudioDecoderConfig(track, logLevel);
|
|
443
599
|
if (audioCodec === "wav" && audioDecoderConfig) {
|
|
444
600
|
return true;
|
|
445
601
|
}
|
|
@@ -473,14 +629,6 @@ var getVideoDecoderConfigWithHardwareAcceleration = async (config) => {
|
|
|
473
629
|
return null;
|
|
474
630
|
};
|
|
475
631
|
|
|
476
|
-
// src/browser-quirks.ts
|
|
477
|
-
var isFirefox = () => {
|
|
478
|
-
return navigator.userAgent.toLowerCase().indexOf("firefox") > -1;
|
|
479
|
-
};
|
|
480
|
-
var isSafari = () => {
|
|
481
|
-
return /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
|
|
482
|
-
};
|
|
483
|
-
|
|
484
632
|
// src/choose-correct-avc1-profile.ts
|
|
485
633
|
var chooseCorrectAvc1Profile = ({
|
|
486
634
|
width,
|
|
@@ -564,7 +712,10 @@ var canReencodeVideoTrack = async ({
|
|
|
564
712
|
return Boolean(videoDecoderConfig && videoEncoderConfig);
|
|
565
713
|
};
|
|
566
714
|
// src/convert-media.ts
|
|
567
|
-
import {
|
|
715
|
+
import {
|
|
716
|
+
MediaParserInternals as MediaParserInternals7,
|
|
717
|
+
parseMedia
|
|
718
|
+
} from "@remotion/media-parser";
|
|
568
719
|
|
|
569
720
|
// src/auto-select-writer.ts
|
|
570
721
|
import { bufferWriter } from "@remotion/media-parser/buffer";
|
|
@@ -621,7 +772,7 @@ var convertEncodedChunk = (chunk, trackId) => {
|
|
|
621
772
|
};
|
|
622
773
|
|
|
623
774
|
// src/default-on-audio-track-handler.ts
|
|
624
|
-
import { MediaParserInternals as
|
|
775
|
+
import { MediaParserInternals as MediaParserInternals4 } from "@remotion/media-parser";
|
|
625
776
|
|
|
626
777
|
// src/get-default-audio-codec.ts
|
|
627
778
|
var getDefaultAudioCodec = ({
|
|
@@ -653,7 +804,7 @@ var defaultOnAudioTrackHandler = async ({
|
|
|
653
804
|
container
|
|
654
805
|
});
|
|
655
806
|
if (canCopy) {
|
|
656
|
-
|
|
807
|
+
MediaParserInternals4.Log.verbose(logLevel, `Track ${track.trackId} (audio): Can copy track, therefore copying`);
|
|
657
808
|
return Promise.resolve({ type: "copy" });
|
|
658
809
|
}
|
|
659
810
|
const audioCodec = defaultAudioCodec ?? getDefaultAudioCodec({ container });
|
|
@@ -663,14 +814,14 @@ var defaultOnAudioTrackHandler = async ({
|
|
|
663
814
|
bitrate
|
|
664
815
|
});
|
|
665
816
|
if (canReencode) {
|
|
666
|
-
|
|
817
|
+
MediaParserInternals4.Log.verbose(logLevel, `Track ${track.trackId} (audio): Cannot copy, but re-encode, therefore re-encoding`);
|
|
667
818
|
return Promise.resolve({
|
|
668
819
|
type: "reencode",
|
|
669
820
|
bitrate,
|
|
670
821
|
audioCodec
|
|
671
822
|
});
|
|
672
823
|
}
|
|
673
|
-
|
|
824
|
+
MediaParserInternals4.Log.verbose(logLevel, `Track ${track.trackId} (audio): Can neither re-encode nor copy, failing render`);
|
|
674
825
|
return Promise.resolve({ type: "fail" });
|
|
675
826
|
};
|
|
676
827
|
|
|
@@ -683,7 +834,8 @@ var makeAudioTrackHandler = ({
|
|
|
683
834
|
onMediaStateUpdate,
|
|
684
835
|
onAudioTrack,
|
|
685
836
|
logLevel,
|
|
686
|
-
container
|
|
837
|
+
container,
|
|
838
|
+
progressTracker
|
|
687
839
|
}) => async (track) => {
|
|
688
840
|
const audioOperation = await (onAudioTrack ?? defaultOnAudioTrackHandler)({
|
|
689
841
|
defaultAudioCodec: audioCodec,
|
|
@@ -734,7 +886,7 @@ var makeAudioTrackHandler = ({
|
|
|
734
886
|
numberOfChannels: track.numberOfChannels,
|
|
735
887
|
sampleRate: track.sampleRate,
|
|
736
888
|
description: track.description
|
|
737
|
-
});
|
|
889
|
+
}, logLevel);
|
|
738
890
|
if (!audioEncoderConfig) {
|
|
739
891
|
abortConversion(new error_cause_default(`Could not configure audio encoder of track ${track.trackId}`));
|
|
740
892
|
return null;
|
|
@@ -779,7 +931,8 @@ var makeAudioTrackHandler = ({
|
|
|
779
931
|
codec: audioOperation.audioCodec,
|
|
780
932
|
signal: controller.signal,
|
|
781
933
|
config: audioEncoderConfig,
|
|
782
|
-
logLevel
|
|
934
|
+
logLevel,
|
|
935
|
+
progressTracker
|
|
783
936
|
});
|
|
784
937
|
const audioDecoder = createAudioDecoder({
|
|
785
938
|
onFrame: async (frame) => {
|
|
@@ -793,13 +946,15 @@ var makeAudioTrackHandler = ({
|
|
|
793
946
|
frame.close();
|
|
794
947
|
},
|
|
795
948
|
onError(error) {
|
|
796
|
-
abortConversion(new error_cause_default(`Audio decoder of track ${track.trackId} failed (see .cause of this error)`, {
|
|
949
|
+
abortConversion(new error_cause_default(`Audio decoder of track ${track.trackId} failed. Config: ${JSON.stringify(audioDecoderConfig)} (see .cause of this error)`, {
|
|
797
950
|
cause: error
|
|
798
951
|
}));
|
|
799
952
|
},
|
|
800
953
|
signal: controller.signal,
|
|
801
954
|
config: audioDecoderConfig,
|
|
802
|
-
logLevel
|
|
955
|
+
logLevel,
|
|
956
|
+
track,
|
|
957
|
+
progressTracker
|
|
803
958
|
});
|
|
804
959
|
state.addWaitForFinishPromise(async () => {
|
|
805
960
|
await audioDecoder.waitForFinish();
|
|
@@ -818,7 +973,7 @@ var arrayBufferToUint8Array = (buffer) => {
|
|
|
818
973
|
};
|
|
819
974
|
|
|
820
975
|
// src/default-on-video-track-handler.ts
|
|
821
|
-
import { MediaParserInternals as
|
|
976
|
+
import { MediaParserInternals as MediaParserInternals5 } from "@remotion/media-parser";
|
|
822
977
|
|
|
823
978
|
// src/get-default-video-codec.ts
|
|
824
979
|
var getDefaultVideoCodec = ({
|
|
@@ -841,19 +996,22 @@ var defaultOnVideoTrackHandler = async ({
|
|
|
841
996
|
track,
|
|
842
997
|
defaultVideoCodec,
|
|
843
998
|
logLevel,
|
|
844
|
-
container
|
|
999
|
+
container,
|
|
1000
|
+
rotate
|
|
845
1001
|
}) => {
|
|
846
1002
|
const canCopy = canCopyVideoTrack({
|
|
847
1003
|
inputCodec: track.codecWithoutConfig,
|
|
848
|
-
container
|
|
1004
|
+
container,
|
|
1005
|
+
inputRotation: track.rotation,
|
|
1006
|
+
rotationToApply: rotate
|
|
849
1007
|
});
|
|
850
1008
|
if (canCopy) {
|
|
851
|
-
|
|
1009
|
+
MediaParserInternals5.Log.verbose(logLevel, `Track ${track.trackId} (video): Can copy, therefore copying`);
|
|
852
1010
|
return Promise.resolve({ type: "copy" });
|
|
853
1011
|
}
|
|
854
1012
|
const videoCodec = defaultVideoCodec ?? getDefaultVideoCodec({ container });
|
|
855
1013
|
if (videoCodec === null) {
|
|
856
|
-
|
|
1014
|
+
MediaParserInternals5.Log.verbose(logLevel, `Track ${track.trackId} (video): No default video codec, therefore dropping`);
|
|
857
1015
|
return Promise.resolve({ type: "drop" });
|
|
858
1016
|
}
|
|
859
1017
|
const canReencode = await canReencodeVideoTrack({
|
|
@@ -861,10 +1019,14 @@ var defaultOnVideoTrackHandler = async ({
|
|
|
861
1019
|
track
|
|
862
1020
|
});
|
|
863
1021
|
if (canReencode) {
|
|
864
|
-
|
|
865
|
-
return Promise.resolve({
|
|
1022
|
+
MediaParserInternals5.Log.verbose(logLevel, `Track ${track.trackId} (video): Cannot copy, but re-enconde, therefore re-encoding`);
|
|
1023
|
+
return Promise.resolve({
|
|
1024
|
+
type: "reencode",
|
|
1025
|
+
videoCodec,
|
|
1026
|
+
rotation: rotate - track.rotation
|
|
1027
|
+
});
|
|
866
1028
|
}
|
|
867
|
-
|
|
1029
|
+
MediaParserInternals5.Log.verbose(logLevel, `Track ${track.trackId} (video): Can neither copy nor re-encode, therefore failing`);
|
|
868
1030
|
return Promise.resolve({ type: "fail" });
|
|
869
1031
|
};
|
|
870
1032
|
|
|
@@ -876,6 +1038,9 @@ var needsToCorrectVideoFrame = ({
|
|
|
876
1038
|
if (videoFrame.format === null) {
|
|
877
1039
|
return true;
|
|
878
1040
|
}
|
|
1041
|
+
if (videoFrame.format === "I420P10") {
|
|
1042
|
+
return true;
|
|
1043
|
+
}
|
|
879
1044
|
return isFirefox() && videoFrame.format === "BGRX" && outputCodec === "h264";
|
|
880
1045
|
};
|
|
881
1046
|
var convertToCorrectVideoFrame = ({
|
|
@@ -903,35 +1068,43 @@ var convertToCorrectVideoFrame = ({
|
|
|
903
1068
|
|
|
904
1069
|
// src/on-frame.ts
|
|
905
1070
|
var onFrame = async ({
|
|
906
|
-
frame,
|
|
1071
|
+
frame: unrotatedFrame,
|
|
907
1072
|
onVideoFrame,
|
|
908
1073
|
videoEncoder,
|
|
909
1074
|
track,
|
|
910
|
-
outputCodec
|
|
1075
|
+
outputCodec,
|
|
1076
|
+
rotation
|
|
911
1077
|
}) => {
|
|
912
|
-
const
|
|
913
|
-
|
|
914
|
-
|
|
1078
|
+
const rotated = rotateVideoFrame({
|
|
1079
|
+
rotation,
|
|
1080
|
+
frame: unrotatedFrame
|
|
1081
|
+
});
|
|
1082
|
+
if (unrotatedFrame !== rotated) {
|
|
1083
|
+
unrotatedFrame.close();
|
|
1084
|
+
}
|
|
1085
|
+
const userProcessedFrame = onVideoFrame ? await onVideoFrame({ frame: rotated, track }) : rotated;
|
|
1086
|
+
if (userProcessedFrame.displayWidth !== rotated.displayWidth) {
|
|
1087
|
+
throw new Error(`Returned VideoFrame of track ${track.trackId} has different displayWidth (${userProcessedFrame.displayWidth}) than the input frame (${userProcessedFrame.displayHeight})`);
|
|
915
1088
|
}
|
|
916
|
-
if (
|
|
917
|
-
throw new Error(`Returned VideoFrame of track ${track.trackId} has different displayHeight (${
|
|
1089
|
+
if (userProcessedFrame.displayHeight !== rotated.displayHeight) {
|
|
1090
|
+
throw new Error(`Returned VideoFrame of track ${track.trackId} has different displayHeight (${userProcessedFrame.displayHeight}) than the input frame (${userProcessedFrame.displayHeight})`);
|
|
918
1091
|
}
|
|
919
|
-
if (
|
|
920
|
-
throw new Error(`Returned VideoFrame of track ${track.trackId} has different timestamp (${
|
|
1092
|
+
if (userProcessedFrame.timestamp !== rotated.timestamp) {
|
|
1093
|
+
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`);
|
|
921
1094
|
}
|
|
922
|
-
if (
|
|
923
|
-
throw new Error(`Returned VideoFrame of track ${track.trackId} has different duration (${
|
|
1095
|
+
if ((userProcessedFrame.duration ?? 0) !== (rotated.duration ?? 0)) {
|
|
1096
|
+
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`);
|
|
924
1097
|
}
|
|
925
1098
|
const fixedFrame = convertToCorrectVideoFrame({
|
|
926
|
-
videoFrame:
|
|
1099
|
+
videoFrame: userProcessedFrame,
|
|
927
1100
|
outputCodec
|
|
928
1101
|
});
|
|
929
1102
|
await videoEncoder.encodeFrame(fixedFrame, fixedFrame.timestamp);
|
|
930
1103
|
fixedFrame.close();
|
|
931
|
-
if (
|
|
932
|
-
|
|
1104
|
+
if (rotated !== userProcessedFrame) {
|
|
1105
|
+
rotated.close();
|
|
933
1106
|
}
|
|
934
|
-
if (fixedFrame !==
|
|
1107
|
+
if (fixedFrame !== userProcessedFrame) {
|
|
935
1108
|
fixedFrame.close();
|
|
936
1109
|
}
|
|
937
1110
|
};
|
|
@@ -942,9 +1115,14 @@ var createVideoDecoder = ({
|
|
|
942
1115
|
onError,
|
|
943
1116
|
signal,
|
|
944
1117
|
config,
|
|
945
|
-
logLevel
|
|
1118
|
+
logLevel,
|
|
1119
|
+
progress
|
|
946
1120
|
}) => {
|
|
947
|
-
const ioSynchronizer = makeIoSynchronizer(
|
|
1121
|
+
const ioSynchronizer = makeIoSynchronizer({
|
|
1122
|
+
logLevel,
|
|
1123
|
+
label: "Video decoder",
|
|
1124
|
+
progress
|
|
1125
|
+
});
|
|
948
1126
|
let outputQueue = Promise.resolve();
|
|
949
1127
|
const videoDecoder = new VideoDecoder({
|
|
950
1128
|
output(inputFrame) {
|
|
@@ -990,7 +1168,11 @@ var createVideoDecoder = ({
|
|
|
990
1168
|
if (videoDecoder.state === "closed") {
|
|
991
1169
|
return;
|
|
992
1170
|
}
|
|
993
|
-
await ioSynchronizer.waitFor({
|
|
1171
|
+
await ioSynchronizer.waitFor({
|
|
1172
|
+
unemitted: 20,
|
|
1173
|
+
_unprocessed: 2,
|
|
1174
|
+
minimumProgress: sample.timestamp - 5000000
|
|
1175
|
+
});
|
|
994
1176
|
if (sample.type === "key") {
|
|
995
1177
|
await videoDecoder.flush();
|
|
996
1178
|
}
|
|
@@ -1027,12 +1209,17 @@ var createVideoEncoder = ({
|
|
|
1027
1209
|
signal,
|
|
1028
1210
|
config,
|
|
1029
1211
|
logLevel,
|
|
1030
|
-
outputCodec
|
|
1212
|
+
outputCodec,
|
|
1213
|
+
progress
|
|
1031
1214
|
}) => {
|
|
1032
1215
|
if (signal.aborted) {
|
|
1033
1216
|
throw new Error("Not creating video encoder, already aborted");
|
|
1034
1217
|
}
|
|
1035
|
-
const ioSynchronizer = makeIoSynchronizer(
|
|
1218
|
+
const ioSynchronizer = makeIoSynchronizer({
|
|
1219
|
+
logLevel,
|
|
1220
|
+
label: "Video encoder",
|
|
1221
|
+
progress
|
|
1222
|
+
});
|
|
1036
1223
|
let outputQueue = Promise.resolve();
|
|
1037
1224
|
const encoder = new VideoEncoder({
|
|
1038
1225
|
error(error) {
|
|
@@ -1074,7 +1261,8 @@ var createVideoEncoder = ({
|
|
|
1074
1261
|
}
|
|
1075
1262
|
await ioSynchronizer.waitFor({
|
|
1076
1263
|
unemitted: 10,
|
|
1077
|
-
_unprocessed: 10
|
|
1264
|
+
_unprocessed: 10,
|
|
1265
|
+
minimumProgress: frame.timestamp - 5000000
|
|
1078
1266
|
});
|
|
1079
1267
|
if (encoder.state === "closed") {
|
|
1080
1268
|
return;
|
|
@@ -1114,7 +1302,9 @@ var makeVideoTrackHandler = ({
|
|
|
1114
1302
|
defaultVideoCodec,
|
|
1115
1303
|
onVideoTrack,
|
|
1116
1304
|
logLevel,
|
|
1117
|
-
container
|
|
1305
|
+
container,
|
|
1306
|
+
rotate,
|
|
1307
|
+
progress
|
|
1118
1308
|
}) => async (track) => {
|
|
1119
1309
|
if (controller.signal.aborted) {
|
|
1120
1310
|
throw new error_cause_default("Aborted");
|
|
@@ -1123,7 +1313,8 @@ var makeVideoTrackHandler = ({
|
|
|
1123
1313
|
track,
|
|
1124
1314
|
defaultVideoCodec,
|
|
1125
1315
|
logLevel,
|
|
1126
|
-
container
|
|
1316
|
+
container,
|
|
1317
|
+
rotate
|
|
1127
1318
|
});
|
|
1128
1319
|
if (videoOperation.type === "drop") {
|
|
1129
1320
|
return null;
|
|
@@ -1158,10 +1349,20 @@ var makeVideoTrackHandler = ({
|
|
|
1158
1349
|
});
|
|
1159
1350
|
};
|
|
1160
1351
|
}
|
|
1352
|
+
if (videoOperation.type !== "reencode") {
|
|
1353
|
+
throw new error_cause_default(`Video track with ID ${track.trackId} could not be resolved with a valid operation. Received ${JSON.stringify(videoOperation)}, but must be either "copy", "reencode", "drop" or "fail"`);
|
|
1354
|
+
}
|
|
1355
|
+
const rotation = (videoOperation.rotate ?? rotate) - track.rotation;
|
|
1356
|
+
console.log(rotate);
|
|
1357
|
+
const { height: newHeight, width: newWidth } = calculateNewDimensionsFromDimensions({
|
|
1358
|
+
width: track.codedWidth,
|
|
1359
|
+
height: track.codedHeight,
|
|
1360
|
+
rotation
|
|
1361
|
+
});
|
|
1161
1362
|
const videoEncoderConfig = await getVideoEncoderConfig({
|
|
1162
1363
|
codec: videoOperation.videoCodec,
|
|
1163
|
-
height:
|
|
1164
|
-
width:
|
|
1364
|
+
height: newHeight,
|
|
1365
|
+
width: newWidth,
|
|
1165
1366
|
fps: track.fps
|
|
1166
1367
|
});
|
|
1167
1368
|
const videoDecoderConfig = await getVideoDecoderConfigWithHardwareAcceleration(track);
|
|
@@ -1176,8 +1377,8 @@ var makeVideoTrackHandler = ({
|
|
|
1176
1377
|
const { trackNumber } = await state.addTrack({
|
|
1177
1378
|
type: "video",
|
|
1178
1379
|
color: track.color,
|
|
1179
|
-
width:
|
|
1180
|
-
height:
|
|
1380
|
+
width: newWidth,
|
|
1381
|
+
height: newHeight,
|
|
1181
1382
|
codec: videoOperation.videoCodec,
|
|
1182
1383
|
codecPrivate: null,
|
|
1183
1384
|
timescale: track.timescale
|
|
@@ -1207,7 +1408,8 @@ var makeVideoTrackHandler = ({
|
|
|
1207
1408
|
signal: controller.signal,
|
|
1208
1409
|
config: videoEncoderConfig,
|
|
1209
1410
|
logLevel,
|
|
1210
|
-
outputCodec: videoOperation.videoCodec
|
|
1411
|
+
outputCodec: videoOperation.videoCodec,
|
|
1412
|
+
progress
|
|
1211
1413
|
});
|
|
1212
1414
|
const videoDecoder = createVideoDecoder({
|
|
1213
1415
|
config: videoDecoderConfig,
|
|
@@ -1217,7 +1419,8 @@ var makeVideoTrackHandler = ({
|
|
|
1217
1419
|
track,
|
|
1218
1420
|
videoEncoder,
|
|
1219
1421
|
onVideoFrame,
|
|
1220
|
-
outputCodec: videoOperation.videoCodec
|
|
1422
|
+
outputCodec: videoOperation.videoCodec,
|
|
1423
|
+
rotation
|
|
1221
1424
|
});
|
|
1222
1425
|
},
|
|
1223
1426
|
onError: (err) => {
|
|
@@ -1226,7 +1429,8 @@ var makeVideoTrackHandler = ({
|
|
|
1226
1429
|
}));
|
|
1227
1430
|
},
|
|
1228
1431
|
signal: controller.signal,
|
|
1229
|
-
logLevel
|
|
1432
|
+
logLevel,
|
|
1433
|
+
progress
|
|
1230
1434
|
});
|
|
1231
1435
|
state.addWaitForFinishPromise(async () => {
|
|
1232
1436
|
Log.verbose(logLevel, "Waiting for video decoder to finish");
|
|
@@ -1243,16 +1447,16 @@ var makeVideoTrackHandler = ({
|
|
|
1243
1447
|
};
|
|
1244
1448
|
|
|
1245
1449
|
// src/select-container-creator.ts
|
|
1246
|
-
import { MediaParserInternals as
|
|
1450
|
+
import { MediaParserInternals as MediaParserInternals6 } from "@remotion/media-parser";
|
|
1247
1451
|
var selectContainerCreator = (container) => {
|
|
1248
1452
|
if (container === "mp4") {
|
|
1249
|
-
return
|
|
1453
|
+
return MediaParserInternals6.createIsoBaseMedia;
|
|
1250
1454
|
}
|
|
1251
1455
|
if (container === "wav") {
|
|
1252
|
-
return
|
|
1456
|
+
return MediaParserInternals6.createWav;
|
|
1253
1457
|
}
|
|
1254
1458
|
if (container === "webm") {
|
|
1255
|
-
return
|
|
1459
|
+
return MediaParserInternals6.createMatroskaMedia;
|
|
1256
1460
|
}
|
|
1257
1461
|
throw new Error(`Unsupported container: ${container}`);
|
|
1258
1462
|
};
|
|
@@ -1325,6 +1529,7 @@ var convertMedia = async function({
|
|
|
1325
1529
|
logLevel = "info",
|
|
1326
1530
|
writer,
|
|
1327
1531
|
progressIntervalInMs,
|
|
1532
|
+
rotate,
|
|
1328
1533
|
...more
|
|
1329
1534
|
}) {
|
|
1330
1535
|
if (userPassedAbortSignal?.aborted) {
|
|
@@ -1336,7 +1541,7 @@ var convertMedia = async function({
|
|
|
1336
1541
|
if (videoCodec && videoCodec !== "vp8" && videoCodec !== "vp9") {
|
|
1337
1542
|
return Promise.reject(new TypeError('Only `videoCodec: "vp8"` and `videoCodec: "vp9"` are supported currently'));
|
|
1338
1543
|
}
|
|
1339
|
-
const { resolve, reject, getPromiseToImmediatelyReturn } = withResolversAndWaitForReturn();
|
|
1544
|
+
const { resolve, reject, getPromiseToImmediatelyReturn } = MediaParserInternals7.withResolversAndWaitForReturn();
|
|
1340
1545
|
const controller = new AbortController;
|
|
1341
1546
|
const abortConversion = (errCause) => {
|
|
1342
1547
|
reject(errCause);
|
|
@@ -1354,6 +1559,7 @@ var convertMedia = async function({
|
|
|
1354
1559
|
everyMilliseconds: progressIntervalInMs ?? 100,
|
|
1355
1560
|
signal: controller.signal
|
|
1356
1561
|
});
|
|
1562
|
+
const progressTracker = MediaParserInternals7.makeProgressTracker();
|
|
1357
1563
|
const state = await creator({
|
|
1358
1564
|
filename: generateOutputFilename(src, container),
|
|
1359
1565
|
writer: await autoSelectWriter(writer, logLevel),
|
|
@@ -1380,7 +1586,8 @@ var convertMedia = async function({
|
|
|
1380
1586
|
return prevState;
|
|
1381
1587
|
});
|
|
1382
1588
|
},
|
|
1383
|
-
logLevel
|
|
1589
|
+
logLevel,
|
|
1590
|
+
progressTracker
|
|
1384
1591
|
});
|
|
1385
1592
|
const onVideoTrack = makeVideoTrackHandler({
|
|
1386
1593
|
state,
|
|
@@ -1391,7 +1598,9 @@ var convertMedia = async function({
|
|
|
1391
1598
|
defaultVideoCodec: videoCodec ?? null,
|
|
1392
1599
|
onVideoTrack: userVideoResolver ?? null,
|
|
1393
1600
|
logLevel,
|
|
1394
|
-
container
|
|
1601
|
+
container,
|
|
1602
|
+
rotate: rotate ?? 0,
|
|
1603
|
+
progress: progressTracker
|
|
1395
1604
|
});
|
|
1396
1605
|
const onAudioTrack = makeAudioTrackHandler({
|
|
1397
1606
|
abortConversion,
|
|
@@ -1401,7 +1610,8 @@ var convertMedia = async function({
|
|
|
1401
1610
|
state,
|
|
1402
1611
|
onAudioTrack: userAudioResolver ?? null,
|
|
1403
1612
|
logLevel,
|
|
1404
|
-
container
|
|
1613
|
+
container,
|
|
1614
|
+
progressTracker
|
|
1405
1615
|
});
|
|
1406
1616
|
parseMedia({
|
|
1407
1617
|
logLevel,
|
|
@@ -1488,6 +1698,10 @@ var getAvailableVideoCodecs = ({
|
|
|
1488
1698
|
throw new Error(`Unsupported container: ${container}`);
|
|
1489
1699
|
};
|
|
1490
1700
|
// src/index.ts
|
|
1701
|
+
var WebCodecsInternals = {
|
|
1702
|
+
rotateVideoFrame,
|
|
1703
|
+
normalizeVideoRotation
|
|
1704
|
+
};
|
|
1491
1705
|
setRemotionImported();
|
|
1492
1706
|
export {
|
|
1493
1707
|
getDefaultVideoCodec,
|
|
@@ -1505,5 +1719,6 @@ export {
|
|
|
1505
1719
|
canReencodeVideoTrack,
|
|
1506
1720
|
canReencodeAudioTrack,
|
|
1507
1721
|
canCopyVideoTrack,
|
|
1508
|
-
canCopyAudioTrack
|
|
1722
|
+
canCopyAudioTrack,
|
|
1723
|
+
WebCodecsInternals
|
|
1509
1724
|
};
|