@remotion/media 4.0.446 → 4.0.448
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/audio-decode-scheduler.d.ts +14 -0
- package/dist/convert-audiodata/resample-audiodata.d.ts +1 -1
- package/dist/esm/index.mjs +92 -16
- package/dist/index.d.ts +2 -0
- package/dist/video/props.d.ts +1 -0
- package/dist/video/video-for-preview.d.ts +1 -0
- package/dist/video/video-frame-cache.d.ts +2 -0
- package/dist/video/video.d.ts +1 -0
- package/package.json +3 -3
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare class AudioDecodeScheduler {
|
|
2
|
+
private activeTurns;
|
|
3
|
+
private nextId;
|
|
4
|
+
private queue;
|
|
5
|
+
private pendingBatch;
|
|
6
|
+
private batchTimer;
|
|
7
|
+
requestTurn(priority: number): Promise<number>;
|
|
8
|
+
releaseTurn(id: number): void;
|
|
9
|
+
private processBatch;
|
|
10
|
+
private grant;
|
|
11
|
+
private getMinActivePriority;
|
|
12
|
+
private grantEligibleWaiters;
|
|
13
|
+
}
|
|
14
|
+
export declare const getAudioDecodeScheduler: (audioContext: AudioContext) => AudioDecodeScheduler;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export declare const TARGET_NUMBER_OF_CHANNELS = 2;
|
|
2
|
-
export declare const
|
|
2
|
+
export declare const getTargetSampleRate: () => number;
|
|
3
3
|
export declare const resampleAudioData: ({ srcNumberOfChannels, sourceChannels, destination, targetFrames, chunkSize, }: {
|
|
4
4
|
srcNumberOfChannels: number;
|
|
5
5
|
sourceChannels: Int16Array<ArrayBufferLike>;
|
package/dist/esm/index.mjs
CHANGED
|
@@ -381,7 +381,7 @@ var isAlreadyQueued = (time, queuedPeriod) => {
|
|
|
381
381
|
|
|
382
382
|
// src/make-iterator-with-priming.ts
|
|
383
383
|
var AUDIO_PRIMING_SECONDS = 0.5;
|
|
384
|
-
var PREDECODE_AHEAD_SECONDS =
|
|
384
|
+
var PREDECODE_AHEAD_SECONDS = 2;
|
|
385
385
|
function makePredecodingIterator(inner) {
|
|
386
386
|
const buffer = [];
|
|
387
387
|
let consumerEndTime = 0;
|
|
@@ -564,7 +564,7 @@ var makePrewarmedAudioIteratorCache = (audioSink) => {
|
|
|
564
564
|
};
|
|
565
565
|
|
|
566
566
|
// src/audio-iterator-manager.ts
|
|
567
|
-
var MAX_BUFFER_AHEAD_SECONDS =
|
|
567
|
+
var MAX_BUFFER_AHEAD_SECONDS = 2;
|
|
568
568
|
var audioIteratorManager = ({
|
|
569
569
|
audioTrack,
|
|
570
570
|
delayPlaybackHandleIfNotPremounting,
|
|
@@ -1093,8 +1093,10 @@ var videoIteratorManager = ({
|
|
|
1093
1093
|
let framesRendered = 0;
|
|
1094
1094
|
let currentDelayHandle = null;
|
|
1095
1095
|
if (canvas) {
|
|
1096
|
-
canvas.width
|
|
1097
|
-
|
|
1096
|
+
if (canvas.width !== videoTrack.displayWidth || canvas.height !== videoTrack.displayHeight) {
|
|
1097
|
+
canvas.width = videoTrack.displayWidth;
|
|
1098
|
+
canvas.height = videoTrack.displayHeight;
|
|
1099
|
+
}
|
|
1098
1100
|
}
|
|
1099
1101
|
const canvasSink = new CanvasSink(videoTrack, {
|
|
1100
1102
|
poolSize: 2,
|
|
@@ -3259,7 +3261,12 @@ var applyVolume = (array, volume) => {
|
|
|
3259
3261
|
|
|
3260
3262
|
// src/convert-audiodata/resample-audiodata.ts
|
|
3261
3263
|
var TARGET_NUMBER_OF_CHANNELS = 2;
|
|
3262
|
-
var
|
|
3264
|
+
var getTargetSampleRate = () => {
|
|
3265
|
+
if (typeof window !== "undefined" && window.remotion_sampleRate) {
|
|
3266
|
+
return window.remotion_sampleRate;
|
|
3267
|
+
}
|
|
3268
|
+
return 48000;
|
|
3269
|
+
};
|
|
3263
3270
|
var fixFloatingPoint = (value) => {
|
|
3264
3271
|
if (value % 1 < 0.0000001) {
|
|
3265
3272
|
return Math.floor(value);
|
|
@@ -3392,7 +3399,7 @@ var convertAudioData = ({
|
|
|
3392
3399
|
sampleRate: currentSampleRate,
|
|
3393
3400
|
numberOfFrames
|
|
3394
3401
|
} = audioData;
|
|
3395
|
-
const ratio = currentSampleRate /
|
|
3402
|
+
const ratio = currentSampleRate / getTargetSampleRate();
|
|
3396
3403
|
const frameOffset = Math.floor(fixFloatingPoint2(trimStartInSeconds * audioData.sampleRate));
|
|
3397
3404
|
const unroundedFrameCount = numberOfFrames - trimEndInSeconds * audioData.sampleRate - frameOffset;
|
|
3398
3405
|
const frameCount = isLast ? ceilButNotIfFloatingPointIssue(unroundedFrameCount) : Math.round(unroundedFrameCount);
|
|
@@ -3439,7 +3446,7 @@ var convertAudioData = ({
|
|
|
3439
3446
|
data: srcChannels,
|
|
3440
3447
|
numberOfFrames: newNumberOfFrames,
|
|
3441
3448
|
timestamp: audioDataTimestamp * 1e6 + fixFloatingPoint2(timestampOffsetMicroseconds),
|
|
3442
|
-
durationInMicroSeconds: fixFloatingPoint2(newNumberOfFrames /
|
|
3449
|
+
durationInMicroSeconds: fixFloatingPoint2(newNumberOfFrames / getTargetSampleRate() * 1e6)
|
|
3443
3450
|
};
|
|
3444
3451
|
}
|
|
3445
3452
|
resampleAudioData({
|
|
@@ -3453,7 +3460,7 @@ var convertAudioData = ({
|
|
|
3453
3460
|
data,
|
|
3454
3461
|
numberOfFrames: newNumberOfFrames,
|
|
3455
3462
|
timestamp: audioDataTimestamp * 1e6 + fixFloatingPoint2(timestampOffsetMicroseconds),
|
|
3456
|
-
durationInMicroSeconds: fixFloatingPoint2(newNumberOfFrames /
|
|
3463
|
+
durationInMicroSeconds: fixFloatingPoint2(newNumberOfFrames / getTargetSampleRate() * 1e6)
|
|
3457
3464
|
};
|
|
3458
3465
|
return newAudioData;
|
|
3459
3466
|
};
|
|
@@ -3725,12 +3732,12 @@ var extractAudioInternal = async ({
|
|
|
3725
3732
|
if (isFirstSample) {
|
|
3726
3733
|
trimStartInSeconds = fixFloatingPoint2(timeInSeconds - sample.timestamp);
|
|
3727
3734
|
if (trimStartInSeconds < 0) {
|
|
3728
|
-
const silenceFrames = Math.ceil(fixFloatingPoint2(-trimStartInSeconds *
|
|
3735
|
+
const silenceFrames = Math.ceil(fixFloatingPoint2(-trimStartInSeconds * getTargetSampleRate()));
|
|
3729
3736
|
leadingSilence = {
|
|
3730
3737
|
data: new Int16Array(silenceFrames * TARGET_NUMBER_OF_CHANNELS),
|
|
3731
3738
|
numberOfFrames: silenceFrames,
|
|
3732
3739
|
timestamp: timeInSeconds * 1e6,
|
|
3733
|
-
durationInMicroSeconds: silenceFrames /
|
|
3740
|
+
durationInMicroSeconds: silenceFrames / getTargetSampleRate() * 1e6
|
|
3734
3741
|
};
|
|
3735
3742
|
trimStartInSeconds = 0;
|
|
3736
3743
|
}
|
|
@@ -4381,7 +4388,7 @@ var AudioForRendering = ({
|
|
|
4381
4388
|
audio: environment.isClientSideRendering ? audio.data : Array.from(audio.data),
|
|
4382
4389
|
frame: absoluteFrame,
|
|
4383
4390
|
timestamp: audio.timestamp,
|
|
4384
|
-
duration: audio.numberOfFrames /
|
|
4391
|
+
duration: audio.numberOfFrames / getTargetSampleRate() * 1e6,
|
|
4385
4392
|
toneFrequency: toneFrequency ?? 1
|
|
4386
4393
|
});
|
|
4387
4394
|
}
|
|
@@ -4521,6 +4528,29 @@ import {
|
|
|
4521
4528
|
useVideoConfig as useVideoConfig3
|
|
4522
4529
|
} from "remotion";
|
|
4523
4530
|
|
|
4531
|
+
// src/video/video-frame-cache.ts
|
|
4532
|
+
var cache = new Map;
|
|
4533
|
+
var cacheVideoFrame = (src, sourceCanvas) => {
|
|
4534
|
+
const { width, height } = sourceCanvas;
|
|
4535
|
+
if (width === 0 || height === 0) {
|
|
4536
|
+
return;
|
|
4537
|
+
}
|
|
4538
|
+
let cached = cache.get(src);
|
|
4539
|
+
if (!cached || cached.width !== width || cached.height !== height) {
|
|
4540
|
+
cached = new OffscreenCanvas(width, height);
|
|
4541
|
+
cache.set(src, cached);
|
|
4542
|
+
}
|
|
4543
|
+
const ctx = cached.getContext("2d");
|
|
4544
|
+
if (!ctx) {
|
|
4545
|
+
return;
|
|
4546
|
+
}
|
|
4547
|
+
ctx.clearRect(0, 0, width, height);
|
|
4548
|
+
ctx.drawImage(sourceCanvas, 0, 0);
|
|
4549
|
+
};
|
|
4550
|
+
var getCachedVideoFrame = (src) => {
|
|
4551
|
+
return cache.get(src) ?? null;
|
|
4552
|
+
};
|
|
4553
|
+
|
|
4524
4554
|
// src/video/warn-object-fit-css.ts
|
|
4525
4555
|
import { Internals as Internals20 } from "remotion";
|
|
4526
4556
|
var OBJECT_FIT_CLASS_PATTERN = /\bobject-(contain|cover|fill|none|scale-down)\b/;
|
|
@@ -4581,7 +4611,8 @@ var VideoForPreviewAssertedShowing = ({
|
|
|
4581
4611
|
onError,
|
|
4582
4612
|
credentials,
|
|
4583
4613
|
controls,
|
|
4584
|
-
objectFit: objectFitProp
|
|
4614
|
+
objectFit: objectFitProp,
|
|
4615
|
+
_experimentalInitiallyDrawCachedFrame
|
|
4585
4616
|
}) => {
|
|
4586
4617
|
const src = usePreload2(unpreloadedSrc);
|
|
4587
4618
|
const canvasRef = useRef2(null);
|
|
@@ -4658,6 +4689,44 @@ var VideoForPreviewAssertedShowing = ({
|
|
|
4658
4689
|
const initialMuted = useRef2(effectiveMuted);
|
|
4659
4690
|
const initialDurationInFrames = useRef2(videoConfig.durationInFrames);
|
|
4660
4691
|
const initialSequenceOffset = useRef2(sequenceOffset);
|
|
4692
|
+
const hasDrawnRealFrameRef = useRef2(false);
|
|
4693
|
+
const isPremountingRef = useRef2(isPremounting);
|
|
4694
|
+
isPremountingRef.current = isPremounting;
|
|
4695
|
+
useLayoutEffect3(() => {
|
|
4696
|
+
if (!_experimentalInitiallyDrawCachedFrame) {
|
|
4697
|
+
return;
|
|
4698
|
+
}
|
|
4699
|
+
const canvas = canvasRef.current;
|
|
4700
|
+
if (!canvas) {
|
|
4701
|
+
return;
|
|
4702
|
+
}
|
|
4703
|
+
const cached = getCachedVideoFrame(src);
|
|
4704
|
+
if (!cached) {
|
|
4705
|
+
return;
|
|
4706
|
+
}
|
|
4707
|
+
canvas.width = cached.width;
|
|
4708
|
+
canvas.height = cached.height;
|
|
4709
|
+
const ctx = canvas.getContext("2d", {
|
|
4710
|
+
alpha: true,
|
|
4711
|
+
desynchronized: true
|
|
4712
|
+
});
|
|
4713
|
+
if (!ctx) {
|
|
4714
|
+
return;
|
|
4715
|
+
}
|
|
4716
|
+
ctx.drawImage(cached, 0, 0);
|
|
4717
|
+
}, [_experimentalInitiallyDrawCachedFrame, src]);
|
|
4718
|
+
useLayoutEffect3(() => {
|
|
4719
|
+
if (!_experimentalInitiallyDrawCachedFrame) {
|
|
4720
|
+
return;
|
|
4721
|
+
}
|
|
4722
|
+
const canvas = canvasRef.current;
|
|
4723
|
+
return () => {
|
|
4724
|
+
if (!canvas || !hasDrawnRealFrameRef.current || isPremountingRef.current) {
|
|
4725
|
+
return;
|
|
4726
|
+
}
|
|
4727
|
+
cacheVideoFrame(src, canvas);
|
|
4728
|
+
};
|
|
4729
|
+
}, [_experimentalInitiallyDrawCachedFrame, src]);
|
|
4661
4730
|
useEffect3(() => {
|
|
4662
4731
|
if (!sharedAudioContext)
|
|
4663
4732
|
return;
|
|
@@ -4726,6 +4795,7 @@ var VideoForPreviewAssertedShowing = ({
|
|
|
4726
4795
|
if (result.type === "success") {
|
|
4727
4796
|
setMediaPlayerReady(true);
|
|
4728
4797
|
setMediaDurationInSeconds(result.durationInSeconds);
|
|
4798
|
+
hasDrawnRealFrameRef.current = true;
|
|
4729
4799
|
}
|
|
4730
4800
|
}).catch((error) => {
|
|
4731
4801
|
const [action, errorToUse] = callOnErrorAndResolve({
|
|
@@ -4763,6 +4833,7 @@ var VideoForPreviewAssertedShowing = ({
|
|
|
4763
4833
|
}
|
|
4764
4834
|
setMediaPlayerReady(false);
|
|
4765
4835
|
setShouldFallbackToNativeVideo(false);
|
|
4836
|
+
hasDrawnRealFrameRef.current = false;
|
|
4766
4837
|
};
|
|
4767
4838
|
}, [
|
|
4768
4839
|
audioStreamIndex,
|
|
@@ -5087,7 +5158,7 @@ var VideoForRendering = ({
|
|
|
5087
5158
|
audio: environment.isClientSideRendering ? audio.data : Array.from(audio.data),
|
|
5088
5159
|
frame: absoluteFrame,
|
|
5089
5160
|
timestamp: audio.timestamp,
|
|
5090
|
-
duration: audio.numberOfFrames /
|
|
5161
|
+
duration: audio.numberOfFrames / getTargetSampleRate() * 1e6,
|
|
5091
5162
|
toneFrequency
|
|
5092
5163
|
});
|
|
5093
5164
|
}
|
|
@@ -5283,7 +5354,8 @@ var InnerVideo = ({
|
|
|
5283
5354
|
onError,
|
|
5284
5355
|
credentials,
|
|
5285
5356
|
controls,
|
|
5286
|
-
objectFit
|
|
5357
|
+
objectFit,
|
|
5358
|
+
_experimentalInitiallyDrawCachedFrame
|
|
5287
5359
|
}) => {
|
|
5288
5360
|
const environment = useRemotionEnvironment4();
|
|
5289
5361
|
if (typeof src !== "string") {
|
|
@@ -5355,7 +5427,8 @@ var InnerVideo = ({
|
|
|
5355
5427
|
onError,
|
|
5356
5428
|
credentials,
|
|
5357
5429
|
controls,
|
|
5358
|
-
objectFit
|
|
5430
|
+
objectFit,
|
|
5431
|
+
_experimentalInitiallyDrawCachedFrame
|
|
5359
5432
|
});
|
|
5360
5433
|
};
|
|
5361
5434
|
var VideoInner = ({
|
|
@@ -5387,6 +5460,7 @@ var VideoInner = ({
|
|
|
5387
5460
|
credentials,
|
|
5388
5461
|
controls,
|
|
5389
5462
|
objectFit,
|
|
5463
|
+
_experimentalInitiallyDrawCachedFrame,
|
|
5390
5464
|
from,
|
|
5391
5465
|
durationInFrames
|
|
5392
5466
|
}) => {
|
|
@@ -5424,7 +5498,8 @@ var VideoInner = ({
|
|
|
5424
5498
|
onError,
|
|
5425
5499
|
credentials,
|
|
5426
5500
|
controls,
|
|
5427
|
-
objectFit: objectFit ?? "contain"
|
|
5501
|
+
objectFit: objectFit ?? "contain",
|
|
5502
|
+
_experimentalInitiallyDrawCachedFrame: _experimentalInitiallyDrawCachedFrame ?? false
|
|
5428
5503
|
})
|
|
5429
5504
|
});
|
|
5430
5505
|
};
|
|
@@ -5435,6 +5510,7 @@ Internals23.addSequenceStackTraces(Video);
|
|
|
5435
5510
|
var experimental_Audio = Audio;
|
|
5436
5511
|
var experimental_Video = Video;
|
|
5437
5512
|
export {
|
|
5513
|
+
getTargetSampleRate,
|
|
5438
5514
|
experimental_Video,
|
|
5439
5515
|
experimental_Audio,
|
|
5440
5516
|
Video,
|
package/dist/index.d.ts
CHANGED
|
@@ -39,6 +39,7 @@ export declare const experimental_Video: import("react").ComponentType<{
|
|
|
39
39
|
onError: import("./on-error").MediaOnError | undefined;
|
|
40
40
|
credentials: RequestCredentials | undefined;
|
|
41
41
|
objectFit: import(".").VideoObjectFit;
|
|
42
|
+
_experimentalInitiallyDrawCachedFrame: boolean;
|
|
42
43
|
}> & {
|
|
43
44
|
from?: number | undefined;
|
|
44
45
|
durationInFrames?: number | undefined;
|
|
@@ -47,4 +48,5 @@ export { AudioForPreview } from './audio/audio-for-preview';
|
|
|
47
48
|
export { AudioProps, FallbackHtml5AudioProps } from './audio/props';
|
|
48
49
|
export { MediaErrorAction } from './on-error';
|
|
49
50
|
export { FallbackOffthreadVideoProps, VideoObjectFit, VideoProps, } from './video/props';
|
|
51
|
+
export { getTargetSampleRate } from './convert-audiodata/resample-audiodata';
|
|
50
52
|
export { Audio, Video };
|
package/dist/video/props.d.ts
CHANGED
|
@@ -51,6 +51,7 @@ type OptionalVideoProps = {
|
|
|
51
51
|
onError: MediaOnError | undefined;
|
|
52
52
|
credentials: RequestCredentials | undefined;
|
|
53
53
|
objectFit: VideoObjectFit;
|
|
54
|
+
_experimentalInitiallyDrawCachedFrame: boolean;
|
|
54
55
|
};
|
|
55
56
|
export type InnerVideoProps = MandatoryVideoProps & OuterVideoProps & OptionalVideoProps;
|
|
56
57
|
export type VideoProps = MandatoryVideoProps & Partial<OuterVideoProps> & Partial<OptionalVideoProps> & {
|
|
@@ -27,6 +27,7 @@ type VideoForPreviewProps = {
|
|
|
27
27
|
readonly onError: MediaOnError | undefined;
|
|
28
28
|
readonly credentials: RequestCredentials | undefined;
|
|
29
29
|
readonly objectFit: VideoObjectFit;
|
|
30
|
+
readonly _experimentalInitiallyDrawCachedFrame: boolean;
|
|
30
31
|
};
|
|
31
32
|
export declare const VideoForPreview: React.FC<VideoForPreviewProps & {
|
|
32
33
|
readonly controls: SequenceControls | undefined;
|
package/dist/video/video.d.ts
CHANGED
|
@@ -31,6 +31,7 @@ export declare const Video: React.ComponentType<{
|
|
|
31
31
|
onError: import("../on-error").MediaOnError | undefined;
|
|
32
32
|
credentials: RequestCredentials | undefined;
|
|
33
33
|
objectFit: import("./props").VideoObjectFit;
|
|
34
|
+
_experimentalInitiallyDrawCachedFrame: boolean;
|
|
34
35
|
}> & {
|
|
35
36
|
from?: number | undefined;
|
|
36
37
|
durationInFrames?: number | undefined;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remotion/media",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.448",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"module": "dist/esm/index.mjs",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"mediabunny": "1.39.2",
|
|
26
|
-
"remotion": "4.0.
|
|
26
|
+
"remotion": "4.0.448",
|
|
27
27
|
"zod": "4.3.6"
|
|
28
28
|
},
|
|
29
29
|
"peerDependencies": {
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"react-dom": ">=16.8.0"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"@remotion/eslint-config-internal": "4.0.
|
|
34
|
+
"@remotion/eslint-config-internal": "4.0.448",
|
|
35
35
|
"@vitest/browser-webdriverio": "4.0.9",
|
|
36
36
|
"eslint": "9.19.0",
|
|
37
37
|
"react": "19.2.3",
|