@remotion/media 4.0.398 → 4.0.399
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/esm/index.mjs +82 -72
- package/dist/video-extraction/extract-frame.js +40 -24
- package/package.json +4 -4
- package/dist/audio-for-rendering.d.ts +0 -3
- package/dist/audio-for-rendering.js +0 -94
- package/dist/audio.d.ts +0 -3
- package/dist/audio.js +0 -60
- package/dist/audiodata-to-array.d.ts +0 -0
- package/dist/audiodata-to-array.js +0 -1
- package/dist/convert-audiodata/data-types.d.ts +0 -1
- package/dist/convert-audiodata/data-types.js +0 -22
- package/dist/convert-audiodata/is-planar-format.d.ts +0 -1
- package/dist/convert-audiodata/is-planar-format.js +0 -3
- package/dist/convert-audiodata/log-audiodata.d.ts +0 -1
- package/dist/convert-audiodata/log-audiodata.js +0 -8
- package/dist/convert-audiodata/trim-audiodata.d.ts +0 -0
- package/dist/convert-audiodata/trim-audiodata.js +0 -1
- package/dist/deserialized-audiodata.d.ts +0 -15
- package/dist/deserialized-audiodata.js +0 -26
- package/dist/extract-audio.d.ts +0 -7
- package/dist/extract-audio.js +0 -98
- package/dist/extract-frame-via-broadcast-channel.d.ts +0 -15
- package/dist/extract-frame-via-broadcast-channel.js +0 -104
- package/dist/extract-frame.d.ts +0 -27
- package/dist/extract-frame.js +0 -21
- package/dist/extrct-audio.d.ts +0 -7
- package/dist/extrct-audio.js +0 -94
- package/dist/get-frames-since-keyframe.d.ts +0 -22
- package/dist/get-frames-since-keyframe.js +0 -41
- package/dist/keyframe-bank.d.ts +0 -25
- package/dist/keyframe-bank.js +0 -120
- package/dist/keyframe-manager.d.ts +0 -23
- package/dist/keyframe-manager.js +0 -170
- package/dist/log.d.ts +0 -10
- package/dist/log.js +0 -33
- package/dist/new-video-for-rendering.d.ts +0 -3
- package/dist/new-video-for-rendering.js +0 -108
- package/dist/new-video.d.ts +0 -3
- package/dist/new-video.js +0 -37
- package/dist/props.d.ts +0 -29
- package/dist/props.js +0 -1
- package/dist/remember-actual-matroska-timestamps.d.ts +0 -4
- package/dist/remember-actual-matroska-timestamps.js +0 -19
- package/dist/serialize-videoframe.d.ts +0 -0
- package/dist/serialize-videoframe.js +0 -1
- package/dist/video/media-player.d.ts +0 -62
- package/dist/video/media-player.js +0 -361
- package/dist/video/new-video-for-preview.d.ts +0 -10
- package/dist/video/new-video-for-preview.js +0 -108
- package/dist/video/timeout-utils.d.ts +0 -2
- package/dist/video/timeout-utils.js +0 -18
- package/dist/video-extraction/media-player.d.ts +0 -64
- package/dist/video-extraction/media-player.js +0 -501
- package/dist/video-extraction/new-video-for-preview.d.ts +0 -10
- package/dist/video-extraction/new-video-for-preview.js +0 -114
- package/dist/video-for-rendering.d.ts +0 -3
- package/dist/video-for-rendering.js +0 -108
- package/dist/video.d.ts +0 -3
- package/dist/video.js +0 -37
package/dist/esm/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/audio/audio.tsx
|
|
2
|
-
import { Internals as
|
|
2
|
+
import { Internals as Internals15, useRemotionEnvironment as useRemotionEnvironment2 } from "remotion";
|
|
3
3
|
|
|
4
4
|
// src/audio/audio-for-preview.tsx
|
|
5
5
|
import {
|
|
@@ -1873,7 +1873,7 @@ import { useContext as useContext3, useLayoutEffect as useLayoutEffect2, useMemo
|
|
|
1873
1873
|
import {
|
|
1874
1874
|
cancelRender as cancelRender2,
|
|
1875
1875
|
Html5Audio,
|
|
1876
|
-
Internals as
|
|
1876
|
+
Internals as Internals14,
|
|
1877
1877
|
random,
|
|
1878
1878
|
useCurrentFrame as useCurrentFrame3,
|
|
1879
1879
|
useDelayRender,
|
|
@@ -3169,6 +3169,7 @@ var extractAudio = (params) => {
|
|
|
3169
3169
|
};
|
|
3170
3170
|
|
|
3171
3171
|
// src/video-extraction/extract-frame.ts
|
|
3172
|
+
import { Internals as Internals13 } from "remotion";
|
|
3172
3173
|
var extractFrameInternal = async ({
|
|
3173
3174
|
src,
|
|
3174
3175
|
timeInSeconds: unloopedTimeInSeconds,
|
|
@@ -3181,12 +3182,16 @@ var extractFrameInternal = async ({
|
|
|
3181
3182
|
maxCacheSize
|
|
3182
3183
|
}) => {
|
|
3183
3184
|
const sink = await getSink(src, logLevel);
|
|
3184
|
-
const video = await
|
|
3185
|
+
const [video, mediaDurationInSecondsRaw] = await Promise.all([
|
|
3186
|
+
sink.getVideo(),
|
|
3187
|
+
loop ? sink.getDuration() : Promise.resolve(null)
|
|
3188
|
+
]);
|
|
3189
|
+
const mediaDurationInSeconds = loop ? mediaDurationInSecondsRaw : null;
|
|
3185
3190
|
if (video === "no-video-track") {
|
|
3186
3191
|
throw new Error(`No video track found for ${src}`);
|
|
3187
3192
|
}
|
|
3188
3193
|
if (video === "cannot-decode") {
|
|
3189
|
-
return { type: "cannot-decode", durationInSeconds:
|
|
3194
|
+
return { type: "cannot-decode", durationInSeconds: mediaDurationInSeconds };
|
|
3190
3195
|
}
|
|
3191
3196
|
if (video === "unknown-container-format") {
|
|
3192
3197
|
return { type: "unknown-container-format" };
|
|
@@ -3194,10 +3199,6 @@ var extractFrameInternal = async ({
|
|
|
3194
3199
|
if (video === "network-error") {
|
|
3195
3200
|
return { type: "network-error" };
|
|
3196
3201
|
}
|
|
3197
|
-
let mediaDurationInSeconds = null;
|
|
3198
|
-
if (loop) {
|
|
3199
|
-
mediaDurationInSeconds = await sink.getDuration();
|
|
3200
|
-
}
|
|
3201
3202
|
const timeInSeconds = getTimeInSeconds({
|
|
3202
3203
|
loop,
|
|
3203
3204
|
mediaDurationInSeconds,
|
|
@@ -3216,29 +3217,38 @@ var extractFrameInternal = async ({
|
|
|
3216
3217
|
durationInSeconds: await sink.getDuration()
|
|
3217
3218
|
};
|
|
3218
3219
|
}
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
|
|
3225
|
-
|
|
3226
|
-
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
|
|
3230
|
-
|
|
3231
|
-
|
|
3232
|
-
|
|
3233
|
-
|
|
3220
|
+
try {
|
|
3221
|
+
const keyframeBank = await keyframeManager.requestKeyframeBank({
|
|
3222
|
+
packetSink: video.packetSink,
|
|
3223
|
+
videoSampleSink: video.sampleSink,
|
|
3224
|
+
timestamp: timeInSeconds,
|
|
3225
|
+
src,
|
|
3226
|
+
logLevel,
|
|
3227
|
+
maxCacheSize
|
|
3228
|
+
});
|
|
3229
|
+
if (keyframeBank === "has-alpha") {
|
|
3230
|
+
return {
|
|
3231
|
+
type: "cannot-decode-alpha",
|
|
3232
|
+
durationInSeconds: await sink.getDuration()
|
|
3233
|
+
};
|
|
3234
|
+
}
|
|
3235
|
+
if (!keyframeBank) {
|
|
3236
|
+
return {
|
|
3237
|
+
type: "success",
|
|
3238
|
+
frame: null,
|
|
3239
|
+
durationInSeconds: await sink.getDuration()
|
|
3240
|
+
};
|
|
3241
|
+
}
|
|
3242
|
+
const frame = await keyframeBank.getFrameFromTimestamp(timeInSeconds);
|
|
3234
3243
|
return {
|
|
3235
3244
|
type: "success",
|
|
3236
|
-
frame
|
|
3245
|
+
frame,
|
|
3237
3246
|
durationInSeconds: await sink.getDuration()
|
|
3238
3247
|
};
|
|
3248
|
+
} catch (err) {
|
|
3249
|
+
Internals13.Log.info({ logLevel, tag: "@remotion/media" }, `Error decoding ${src} at time ${timeInSeconds}: ${err}`, err);
|
|
3250
|
+
return { type: "cannot-decode", durationInSeconds: mediaDurationInSeconds };
|
|
3239
3251
|
}
|
|
3240
|
-
const frame = await keyframeBank.getFrameFromTimestamp(timeInSeconds);
|
|
3241
|
-
return { type: "success", frame, durationInSeconds: await sink.getDuration() };
|
|
3242
3252
|
};
|
|
3243
3253
|
var queue2 = Promise.resolve(undefined);
|
|
3244
3254
|
var extractFrame = (params) => {
|
|
@@ -3654,10 +3664,10 @@ var AudioForRendering = ({
|
|
|
3654
3664
|
trimBefore
|
|
3655
3665
|
}) => {
|
|
3656
3666
|
const frame = useCurrentFrame3();
|
|
3657
|
-
const absoluteFrame =
|
|
3658
|
-
const videoConfig =
|
|
3659
|
-
const { registerRenderAsset, unregisterRenderAsset } = useContext3(
|
|
3660
|
-
const startsAt =
|
|
3667
|
+
const absoluteFrame = Internals14.useTimelinePosition();
|
|
3668
|
+
const videoConfig = Internals14.useUnsafeVideoConfig();
|
|
3669
|
+
const { registerRenderAsset, unregisterRenderAsset } = useContext3(Internals14.RenderAssetManager);
|
|
3670
|
+
const startsAt = Internals14.useMediaStartsAt();
|
|
3661
3671
|
const environment = useRemotionEnvironment();
|
|
3662
3672
|
if (!videoConfig) {
|
|
3663
3673
|
throw new Error("No video config found");
|
|
@@ -3668,7 +3678,7 @@ var AudioForRendering = ({
|
|
|
3668
3678
|
const { fps } = videoConfig;
|
|
3669
3679
|
const { delayRender, continueRender } = useDelayRender();
|
|
3670
3680
|
const [replaceWithHtml5Audio, setReplaceWithHtml5Audio] = useState3(false);
|
|
3671
|
-
const sequenceContext = useContext3(
|
|
3681
|
+
const sequenceContext = useContext3(Internals14.SequenceContext);
|
|
3672
3682
|
const id = useMemo3(() => `media-audio-${random(src)}-${sequenceContext?.cumulatedFrom}-${sequenceContext?.relativeFrom}-${sequenceContext?.durationInFrames}`, [
|
|
3673
3683
|
src,
|
|
3674
3684
|
sequenceContext?.cumulatedFrom,
|
|
@@ -3676,7 +3686,7 @@ var AudioForRendering = ({
|
|
|
3676
3686
|
sequenceContext?.durationInFrames
|
|
3677
3687
|
]);
|
|
3678
3688
|
const maxCacheSize = useMaxMediaCacheSize(logLevel ?? window.remotion_logLevel);
|
|
3679
|
-
const audioEnabled =
|
|
3689
|
+
const audioEnabled = Internals14.useAudioEnabled();
|
|
3680
3690
|
useLayoutEffect2(() => {
|
|
3681
3691
|
const timestamp = frame / fps;
|
|
3682
3692
|
const durationInSeconds = 1 / fps;
|
|
@@ -3723,7 +3733,7 @@ var AudioForRendering = ({
|
|
|
3723
3733
|
if (disallowFallbackToHtml5Audio) {
|
|
3724
3734
|
cancelRender2(new Error(`Unknown container format ${src}, and 'disallowFallbackToHtml5Audio' was set. Failing the render.`));
|
|
3725
3735
|
}
|
|
3726
|
-
|
|
3736
|
+
Internals14.Log.warn({
|
|
3727
3737
|
logLevel: logLevel ?? window.remotion_logLevel,
|
|
3728
3738
|
tag: "@remotion/media"
|
|
3729
3739
|
}, `Unknown container format for ${src} (Supported formats: https://www.remotion.dev/docs/mediabunny/formats), falling back to <Html5Audio>`);
|
|
@@ -3738,7 +3748,7 @@ var AudioForRendering = ({
|
|
|
3738
3748
|
if (disallowFallbackToHtml5Audio) {
|
|
3739
3749
|
cancelRender2(new Error(`Cannot decode ${src}, and 'disallowFallbackToHtml5Audio' was set. Failing the render.`));
|
|
3740
3750
|
}
|
|
3741
|
-
|
|
3751
|
+
Internals14.Log.warn({
|
|
3742
3752
|
logLevel: logLevel ?? window.remotion_logLevel,
|
|
3743
3753
|
tag: "@remotion/media"
|
|
3744
3754
|
}, `Cannot decode ${src}, falling back to <Html5Audio>`);
|
|
@@ -3756,7 +3766,7 @@ var AudioForRendering = ({
|
|
|
3756
3766
|
if (disallowFallbackToHtml5Audio) {
|
|
3757
3767
|
cancelRender2(new Error(`Cannot decode ${src}, and 'disallowFallbackToHtml5Audio' was set. Failing the render.`));
|
|
3758
3768
|
}
|
|
3759
|
-
|
|
3769
|
+
Internals14.Log.warn({
|
|
3760
3770
|
logLevel: logLevel ?? window.remotion_logLevel,
|
|
3761
3771
|
tag: "@remotion/media"
|
|
3762
3772
|
}, `Network error fetching ${src}, falling back to <Html5Audio>`);
|
|
@@ -3772,12 +3782,12 @@ var AudioForRendering = ({
|
|
|
3772
3782
|
frame,
|
|
3773
3783
|
startsAt
|
|
3774
3784
|
});
|
|
3775
|
-
const volume =
|
|
3785
|
+
const volume = Internals14.evaluateVolume({
|
|
3776
3786
|
volume: volumeProp,
|
|
3777
3787
|
frame: volumePropsFrame,
|
|
3778
3788
|
mediaVolume: 1
|
|
3779
3789
|
});
|
|
3780
|
-
|
|
3790
|
+
Internals14.warnAboutTooHighVolume(volume);
|
|
3781
3791
|
if (audio && volume > 0) {
|
|
3782
3792
|
applyVolume(audio.data, volume);
|
|
3783
3793
|
registerRenderAsset({
|
|
@@ -3852,7 +3862,7 @@ var AudioForRendering = ({
|
|
|
3852
3862
|
|
|
3853
3863
|
// src/audio/audio.tsx
|
|
3854
3864
|
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
3855
|
-
var { validateMediaProps } =
|
|
3865
|
+
var { validateMediaProps } = Internals15;
|
|
3856
3866
|
var Audio = (props) => {
|
|
3857
3867
|
const { name, stack, showInTimeline, ...otherProps } = props;
|
|
3858
3868
|
const environment = useRemotionEnvironment2();
|
|
@@ -3871,10 +3881,10 @@ var Audio = (props) => {
|
|
|
3871
3881
|
stack: stack ?? null
|
|
3872
3882
|
});
|
|
3873
3883
|
};
|
|
3874
|
-
|
|
3884
|
+
Internals15.addSequenceStackTraces(Audio);
|
|
3875
3885
|
|
|
3876
3886
|
// src/video/video.tsx
|
|
3877
|
-
import { Internals as
|
|
3887
|
+
import { Internals as Internals18, useRemotionEnvironment as useRemotionEnvironment4 } from "remotion";
|
|
3878
3888
|
|
|
3879
3889
|
// src/video/video-for-preview.tsx
|
|
3880
3890
|
import {
|
|
@@ -3887,7 +3897,7 @@ import {
|
|
|
3887
3897
|
} from "react";
|
|
3888
3898
|
import {
|
|
3889
3899
|
Html5Video,
|
|
3890
|
-
Internals as
|
|
3900
|
+
Internals as Internals16,
|
|
3891
3901
|
useBufferState as useBufferState2,
|
|
3892
3902
|
useCurrentFrame as useCurrentFrame4,
|
|
3893
3903
|
useVideoConfig as useVideoConfig3
|
|
@@ -3905,7 +3915,7 @@ var {
|
|
|
3905
3915
|
usePreload: usePreload2,
|
|
3906
3916
|
SequenceContext: SequenceContext2,
|
|
3907
3917
|
SequenceVisibilityToggleContext
|
|
3908
|
-
} =
|
|
3918
|
+
} = Internals16;
|
|
3909
3919
|
var VideoForPreviewAssertedShowing = ({
|
|
3910
3920
|
src: unpreloadedSrc,
|
|
3911
3921
|
style,
|
|
@@ -3939,7 +3949,7 @@ var VideoForPreviewAssertedShowing = ({
|
|
|
3939
3949
|
const [mediaPlayerReady, setMediaPlayerReady] = useState4(false);
|
|
3940
3950
|
const [shouldFallbackToNativeVideo, setShouldFallbackToNativeVideo] = useState4(false);
|
|
3941
3951
|
const [playing] = Timeline2.usePlayingState();
|
|
3942
|
-
const timelineContext = useContext4(
|
|
3952
|
+
const timelineContext = useContext4(Internals16.TimelineContext);
|
|
3943
3953
|
const globalPlaybackRate = timelineContext.playbackRate;
|
|
3944
3954
|
const sharedAudioContext = useContext4(SharedAudioContext2);
|
|
3945
3955
|
const buffer = useBufferState2();
|
|
@@ -3987,11 +3997,11 @@ var VideoForPreviewAssertedShowing = ({
|
|
|
3987
3997
|
const currentTimeRef = useRef2(currentTime);
|
|
3988
3998
|
currentTimeRef.current = currentTime;
|
|
3989
3999
|
const preloadedSrc = usePreload2(src);
|
|
3990
|
-
const buffering = useContext4(
|
|
4000
|
+
const buffering = useContext4(Internals16.BufferingContextReact);
|
|
3991
4001
|
if (!buffering) {
|
|
3992
4002
|
throw new Error("useMediaPlayback must be used inside a <BufferingContext>");
|
|
3993
4003
|
}
|
|
3994
|
-
const isPlayerBuffering =
|
|
4004
|
+
const isPlayerBuffering = Internals16.useIsPlayerBuffering(buffering);
|
|
3995
4005
|
const initialPlaying = useRef2(playing && !isPlayerBuffering);
|
|
3996
4006
|
const initialIsPremounting = useRef2(isPremounting);
|
|
3997
4007
|
const initialIsPostmounting = useRef2(isPostmounting);
|
|
@@ -4031,7 +4041,7 @@ var VideoForPreviewAssertedShowing = ({
|
|
|
4031
4041
|
if (disallowFallbackToOffthreadVideo) {
|
|
4032
4042
|
throw new Error(`Unknown container format ${preloadedSrc}, and 'disallowFallbackToOffthreadVideo' was set.`);
|
|
4033
4043
|
}
|
|
4034
|
-
|
|
4044
|
+
Internals16.Log.warn({ logLevel, tag: "@remotion/media" }, `Unknown container format for ${preloadedSrc} (Supported formats: https://www.remotion.dev/docs/mediabunny/formats), falling back to <OffthreadVideo>`);
|
|
4035
4045
|
setShouldFallbackToNativeVideo(true);
|
|
4036
4046
|
return;
|
|
4037
4047
|
}
|
|
@@ -4039,7 +4049,7 @@ var VideoForPreviewAssertedShowing = ({
|
|
|
4039
4049
|
if (disallowFallbackToOffthreadVideo) {
|
|
4040
4050
|
throw new Error(`Network error fetching ${preloadedSrc}, and 'disallowFallbackToOffthreadVideo' was set.`);
|
|
4041
4051
|
}
|
|
4042
|
-
|
|
4052
|
+
Internals16.Log.warn({ logLevel, tag: "@remotion/media" }, `Network error fetching ${preloadedSrc}, falling back to <OffthreadVideo>`);
|
|
4043
4053
|
setShouldFallbackToNativeVideo(true);
|
|
4044
4054
|
return;
|
|
4045
4055
|
}
|
|
@@ -4047,7 +4057,7 @@ var VideoForPreviewAssertedShowing = ({
|
|
|
4047
4057
|
if (disallowFallbackToOffthreadVideo) {
|
|
4048
4058
|
throw new Error(`Cannot decode ${preloadedSrc}, and 'disallowFallbackToOffthreadVideo' was set.`);
|
|
4049
4059
|
}
|
|
4050
|
-
|
|
4060
|
+
Internals16.Log.warn({ logLevel, tag: "@remotion/media" }, `Cannot decode ${preloadedSrc}, falling back to <OffthreadVideo>`);
|
|
4051
4061
|
setShouldFallbackToNativeVideo(true);
|
|
4052
4062
|
return;
|
|
4053
4063
|
}
|
|
@@ -4055,7 +4065,7 @@ var VideoForPreviewAssertedShowing = ({
|
|
|
4055
4065
|
if (disallowFallbackToOffthreadVideo) {
|
|
4056
4066
|
throw new Error(`No video or audio tracks found for ${preloadedSrc}, and 'disallowFallbackToOffthreadVideo' was set.`);
|
|
4057
4067
|
}
|
|
4058
|
-
|
|
4068
|
+
Internals16.Log.warn({ logLevel, tag: "@remotion/media" }, `No video or audio tracks found for ${preloadedSrc}, falling back to <OffthreadVideo>`);
|
|
4059
4069
|
setShouldFallbackToNativeVideo(true);
|
|
4060
4070
|
return;
|
|
4061
4071
|
}
|
|
@@ -4064,16 +4074,16 @@ var VideoForPreviewAssertedShowing = ({
|
|
|
4064
4074
|
setMediaDurationInSeconds(result.durationInSeconds);
|
|
4065
4075
|
}
|
|
4066
4076
|
}).catch((error) => {
|
|
4067
|
-
|
|
4077
|
+
Internals16.Log.error({ logLevel, tag: "@remotion/media" }, "[VideoForPreview] Failed to initialize MediaPlayer", error);
|
|
4068
4078
|
setShouldFallbackToNativeVideo(true);
|
|
4069
4079
|
});
|
|
4070
4080
|
} catch (error) {
|
|
4071
|
-
|
|
4081
|
+
Internals16.Log.error({ logLevel, tag: "@remotion/media" }, "[VideoForPreview] MediaPlayer initialization failed", error);
|
|
4072
4082
|
setShouldFallbackToNativeVideo(true);
|
|
4073
4083
|
}
|
|
4074
4084
|
return () => {
|
|
4075
4085
|
if (mediaPlayerRef.current) {
|
|
4076
|
-
|
|
4086
|
+
Internals16.Log.trace({ logLevel, tag: "@remotion/media" }, `[VideoForPreview] Disposing MediaPlayer`);
|
|
4077
4087
|
mediaPlayerRef.current.dispose();
|
|
4078
4088
|
mediaPlayerRef.current = null;
|
|
4079
4089
|
}
|
|
@@ -4092,7 +4102,7 @@ var VideoForPreviewAssertedShowing = ({
|
|
|
4092
4102
|
videoConfig.fps
|
|
4093
4103
|
]);
|
|
4094
4104
|
const classNameValue = useMemo4(() => {
|
|
4095
|
-
return [
|
|
4105
|
+
return [Internals16.OBJECTFIT_CONTAIN_CLASS_NAME, className].filter(Internals16.truthy).join(" ");
|
|
4096
4106
|
}, [className]);
|
|
4097
4107
|
useEffect3(() => {
|
|
4098
4108
|
const mediaPlayer = mediaPlayerRef.current;
|
|
@@ -4193,7 +4203,7 @@ var VideoForPreviewAssertedShowing = ({
|
|
|
4193
4203
|
if (!mediaPlayer || !mediaPlayerReady)
|
|
4194
4204
|
return;
|
|
4195
4205
|
mediaPlayer.seekTo(currentTime).catch(() => {});
|
|
4196
|
-
|
|
4206
|
+
Internals16.Log.trace({ logLevel, tag: "@remotion/media" }, `[VideoForPreview] Updating target time to ${currentTime.toFixed(3)}s`);
|
|
4197
4207
|
}, [currentTime, logLevel, mediaPlayerReady]);
|
|
4198
4208
|
const actualStyle = useMemo4(() => {
|
|
4199
4209
|
return {
|
|
@@ -4272,7 +4282,7 @@ import {
|
|
|
4272
4282
|
useState as useState5
|
|
4273
4283
|
} from "react";
|
|
4274
4284
|
import {
|
|
4275
|
-
Internals as
|
|
4285
|
+
Internals as Internals17,
|
|
4276
4286
|
Loop,
|
|
4277
4287
|
random as random2,
|
|
4278
4288
|
useCurrentFrame as useCurrentFrame5,
|
|
@@ -4308,11 +4318,11 @@ var VideoForRendering = ({
|
|
|
4308
4318
|
throw new TypeError("No `src` was passed to <Video>.");
|
|
4309
4319
|
}
|
|
4310
4320
|
const frame = useCurrentFrame5();
|
|
4311
|
-
const absoluteFrame =
|
|
4321
|
+
const absoluteFrame = Internals17.useTimelinePosition();
|
|
4312
4322
|
const { fps } = useVideoConfig4();
|
|
4313
|
-
const { registerRenderAsset, unregisterRenderAsset } = useContext5(
|
|
4314
|
-
const startsAt =
|
|
4315
|
-
const sequenceContext = useContext5(
|
|
4323
|
+
const { registerRenderAsset, unregisterRenderAsset } = useContext5(Internals17.RenderAssetManager);
|
|
4324
|
+
const startsAt = Internals17.useMediaStartsAt();
|
|
4325
|
+
const sequenceContext = useContext5(Internals17.SequenceContext);
|
|
4316
4326
|
const id = useMemo5(() => `media-video-${random2(src)}-${sequenceContext?.cumulatedFrom}-${sequenceContext?.relativeFrom}-${sequenceContext?.durationInFrames}`, [
|
|
4317
4327
|
src,
|
|
4318
4328
|
sequenceContext?.cumulatedFrom,
|
|
@@ -4323,8 +4333,8 @@ var VideoForRendering = ({
|
|
|
4323
4333
|
const { delayRender, continueRender, cancelRender: cancelRender3 } = useDelayRender2();
|
|
4324
4334
|
const canvasRef = useRef3(null);
|
|
4325
4335
|
const [replaceWithOffthreadVideo, setReplaceWithOffthreadVideo] = useState5(false);
|
|
4326
|
-
const audioEnabled =
|
|
4327
|
-
const videoEnabled =
|
|
4336
|
+
const audioEnabled = Internals17.useAudioEnabled();
|
|
4337
|
+
const videoEnabled = Internals17.useVideoEnabled();
|
|
4328
4338
|
const maxCacheSize = useMaxMediaCacheSize(logLevel);
|
|
4329
4339
|
const [error, setError] = useState5(null);
|
|
4330
4340
|
if (error) {
|
|
@@ -4380,7 +4390,7 @@ var VideoForRendering = ({
|
|
|
4380
4390
|
cancelRender3(new Error(`Unknown container format ${src}, and 'disallowFallbackToOffthreadVideo' was set. Failing the render.`));
|
|
4381
4391
|
}
|
|
4382
4392
|
if (window.remotion_isMainTab) {
|
|
4383
|
-
|
|
4393
|
+
Internals17.Log.info({ logLevel, tag: "@remotion/media" }, `Unknown container format for ${src} (Supported formats: https://www.remotion.dev/docs/mediabunny/formats), falling back to <OffthreadVideo>`);
|
|
4384
4394
|
}
|
|
4385
4395
|
setReplaceWithOffthreadVideo({ durationInSeconds: null });
|
|
4386
4396
|
return;
|
|
@@ -4394,7 +4404,7 @@ var VideoForRendering = ({
|
|
|
4394
4404
|
cancelRender3(new Error(`Cannot decode ${src}, and 'disallowFallbackToOffthreadVideo' was set. Failing the render.`));
|
|
4395
4405
|
}
|
|
4396
4406
|
if (window.remotion_isMainTab) {
|
|
4397
|
-
|
|
4407
|
+
Internals17.Log.warn({ logLevel, tag: "@remotion/media" }, `Cannot decode ${src}, falling back to <OffthreadVideo>`);
|
|
4398
4408
|
}
|
|
4399
4409
|
setReplaceWithOffthreadVideo({
|
|
4400
4410
|
durationInSeconds: result.durationInSeconds
|
|
@@ -4410,7 +4420,7 @@ var VideoForRendering = ({
|
|
|
4410
4420
|
cancelRender3(new Error(`Cannot decode alpha component for ${src}, and 'disallowFallbackToOffthreadVideo' was set. Failing the render.`));
|
|
4411
4421
|
}
|
|
4412
4422
|
if (window.remotion_isMainTab) {
|
|
4413
|
-
|
|
4423
|
+
Internals17.Log.info({ logLevel, tag: "@remotion/media" }, `Cannot decode alpha component for ${src}, falling back to <OffthreadVideo>`);
|
|
4414
4424
|
}
|
|
4415
4425
|
setReplaceWithOffthreadVideo({
|
|
4416
4426
|
durationInSeconds: result.durationInSeconds
|
|
@@ -4426,7 +4436,7 @@ var VideoForRendering = ({
|
|
|
4426
4436
|
cancelRender3(new Error(`Cannot decode ${src}, and 'disallowFallbackToOffthreadVideo' was set. Failing the render.`));
|
|
4427
4437
|
}
|
|
4428
4438
|
if (window.remotion_isMainTab) {
|
|
4429
|
-
|
|
4439
|
+
Internals17.Log.warn({ logLevel, tag: "@remotion/media" }, `Network error fetching ${src} (no CORS?), falling back to <OffthreadVideo>`);
|
|
4430
4440
|
}
|
|
4431
4441
|
setReplaceWithOffthreadVideo({ durationInSeconds: null });
|
|
4432
4442
|
return;
|
|
@@ -4464,12 +4474,12 @@ var VideoForRendering = ({
|
|
|
4464
4474
|
frame,
|
|
4465
4475
|
startsAt
|
|
4466
4476
|
});
|
|
4467
|
-
const volume =
|
|
4477
|
+
const volume = Internals17.evaluateVolume({
|
|
4468
4478
|
volume: volumeProp,
|
|
4469
4479
|
frame: volumePropsFrame,
|
|
4470
4480
|
mediaVolume: 1
|
|
4471
4481
|
});
|
|
4472
|
-
|
|
4482
|
+
Internals17.warnAboutTooHighVolume(volume);
|
|
4473
4483
|
if (audio && volume > 0) {
|
|
4474
4484
|
applyVolume(audio.data, volume);
|
|
4475
4485
|
registerRenderAsset({
|
|
@@ -4524,10 +4534,10 @@ var VideoForRendering = ({
|
|
|
4524
4534
|
headless
|
|
4525
4535
|
]);
|
|
4526
4536
|
const classNameValue = useMemo5(() => {
|
|
4527
|
-
return [
|
|
4537
|
+
return [Internals17.OBJECTFIT_CONTAIN_CLASS_NAME, className].filter(Internals17.truthy).join(" ");
|
|
4528
4538
|
}, [className]);
|
|
4529
4539
|
if (replaceWithOffthreadVideo) {
|
|
4530
|
-
const fallback = /* @__PURE__ */ jsx5(
|
|
4540
|
+
const fallback = /* @__PURE__ */ jsx5(Internals17.InnerOffthreadVideo, {
|
|
4531
4541
|
src,
|
|
4532
4542
|
playbackRate: playbackRate ?? 1,
|
|
4533
4543
|
muted: muted ?? false,
|
|
@@ -4569,7 +4579,7 @@ var VideoForRendering = ({
|
|
|
4569
4579
|
}
|
|
4570
4580
|
return /* @__PURE__ */ jsx5(Loop, {
|
|
4571
4581
|
layout: "none",
|
|
4572
|
-
durationInFrames:
|
|
4582
|
+
durationInFrames: Internals17.calculateMediaDuration({
|
|
4573
4583
|
trimAfter: trimAfterValue,
|
|
4574
4584
|
mediaDurationInFrames: replaceWithOffthreadVideo.durationInSeconds * fps,
|
|
4575
4585
|
playbackRate,
|
|
@@ -4592,7 +4602,7 @@ var VideoForRendering = ({
|
|
|
4592
4602
|
|
|
4593
4603
|
// src/video/video.tsx
|
|
4594
4604
|
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
4595
|
-
var { validateMediaTrimProps, resolveTrimProps, validateMediaProps: validateMediaProps2 } =
|
|
4605
|
+
var { validateMediaTrimProps, resolveTrimProps, validateMediaProps: validateMediaProps2 } = Internals18;
|
|
4596
4606
|
var InnerVideo = ({
|
|
4597
4607
|
src,
|
|
4598
4608
|
audioStreamIndex,
|
|
@@ -4734,7 +4744,7 @@ var Video = ({
|
|
|
4734
4744
|
headless: headless ?? false
|
|
4735
4745
|
});
|
|
4736
4746
|
};
|
|
4737
|
-
|
|
4747
|
+
Internals18.addSequenceStackTraces(Video);
|
|
4738
4748
|
// src/index.ts
|
|
4739
4749
|
var experimental_Audio = Audio;
|
|
4740
4750
|
var experimental_Video = Video;
|
|
@@ -1,14 +1,21 @@
|
|
|
1
|
+
import { Internals } from 'remotion';
|
|
1
2
|
import { keyframeManager } from '../caches';
|
|
2
3
|
import { getSink } from '../get-sink';
|
|
3
4
|
import { getTimeInSeconds } from '../get-time-in-seconds';
|
|
4
5
|
const extractFrameInternal = async ({ src, timeInSeconds: unloopedTimeInSeconds, logLevel, loop, trimAfter, trimBefore, playbackRate, fps, maxCacheSize, }) => {
|
|
5
6
|
const sink = await getSink(src, logLevel);
|
|
6
|
-
const video = await
|
|
7
|
+
const [video, mediaDurationInSecondsRaw] = await Promise.all([
|
|
8
|
+
sink.getVideo(),
|
|
9
|
+
loop ? sink.getDuration() : Promise.resolve(null),
|
|
10
|
+
]);
|
|
11
|
+
const mediaDurationInSeconds = loop
|
|
12
|
+
? mediaDurationInSecondsRaw
|
|
13
|
+
: null;
|
|
7
14
|
if (video === 'no-video-track') {
|
|
8
15
|
throw new Error(`No video track found for ${src}`);
|
|
9
16
|
}
|
|
10
17
|
if (video === 'cannot-decode') {
|
|
11
|
-
return { type: 'cannot-decode', durationInSeconds:
|
|
18
|
+
return { type: 'cannot-decode', durationInSeconds: mediaDurationInSeconds };
|
|
12
19
|
}
|
|
13
20
|
if (video === 'unknown-container-format') {
|
|
14
21
|
return { type: 'unknown-container-format' };
|
|
@@ -16,10 +23,6 @@ const extractFrameInternal = async ({ src, timeInSeconds: unloopedTimeInSeconds,
|
|
|
16
23
|
if (video === 'network-error') {
|
|
17
24
|
return { type: 'network-error' };
|
|
18
25
|
}
|
|
19
|
-
let mediaDurationInSeconds = null;
|
|
20
|
-
if (loop) {
|
|
21
|
-
mediaDurationInSeconds = await sink.getDuration();
|
|
22
|
-
}
|
|
23
26
|
const timeInSeconds = getTimeInSeconds({
|
|
24
27
|
loop,
|
|
25
28
|
mediaDurationInSeconds,
|
|
@@ -38,29 +41,42 @@ const extractFrameInternal = async ({ src, timeInSeconds: unloopedTimeInSeconds,
|
|
|
38
41
|
durationInSeconds: await sink.getDuration(),
|
|
39
42
|
};
|
|
40
43
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
44
|
+
// Must catch https://github.com/Vanilagy/mediabunny/issues/235
|
|
45
|
+
// https://discord.com/channels/@me/1127949286789881897/1455728482150518906
|
|
46
|
+
// Should be able to remove once upgraded to Chrome 145
|
|
47
|
+
try {
|
|
48
|
+
const keyframeBank = await keyframeManager.requestKeyframeBank({
|
|
49
|
+
packetSink: video.packetSink,
|
|
50
|
+
videoSampleSink: video.sampleSink,
|
|
51
|
+
timestamp: timeInSeconds,
|
|
52
|
+
src,
|
|
53
|
+
logLevel,
|
|
54
|
+
maxCacheSize,
|
|
55
|
+
});
|
|
56
|
+
if (keyframeBank === 'has-alpha') {
|
|
57
|
+
return {
|
|
58
|
+
type: 'cannot-decode-alpha',
|
|
59
|
+
durationInSeconds: await sink.getDuration(),
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
if (!keyframeBank) {
|
|
63
|
+
return {
|
|
64
|
+
type: 'success',
|
|
65
|
+
frame: null,
|
|
66
|
+
durationInSeconds: await sink.getDuration(),
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
const frame = await keyframeBank.getFrameFromTimestamp(timeInSeconds);
|
|
56
70
|
return {
|
|
57
71
|
type: 'success',
|
|
58
|
-
frame
|
|
72
|
+
frame,
|
|
59
73
|
durationInSeconds: await sink.getDuration(),
|
|
60
74
|
};
|
|
61
75
|
}
|
|
62
|
-
|
|
63
|
-
|
|
76
|
+
catch (err) {
|
|
77
|
+
Internals.Log.info({ logLevel, tag: '@remotion/media' }, `Error decoding ${src} at time ${timeInSeconds}: ${err}`, err);
|
|
78
|
+
return { type: 'cannot-decode', durationInSeconds: mediaDurationInSeconds };
|
|
79
|
+
}
|
|
64
80
|
};
|
|
65
81
|
let queue = Promise.resolve(undefined);
|
|
66
82
|
export const extractFrame = (params) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remotion/media",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.399",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"module": "dist/esm/index.mjs",
|
|
@@ -21,15 +21,15 @@
|
|
|
21
21
|
"make": "tsc -d && bun --env-file=../.env.bundle bundle.ts"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"mediabunny": "1.27.
|
|
25
|
-
"remotion": "4.0.
|
|
24
|
+
"mediabunny": "1.27.3",
|
|
25
|
+
"remotion": "4.0.399"
|
|
26
26
|
},
|
|
27
27
|
"peerDependencies": {
|
|
28
28
|
"react": ">=16.8.0",
|
|
29
29
|
"react-dom": ">=16.8.0"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
|
-
"@remotion/eslint-config-internal": "4.0.
|
|
32
|
+
"@remotion/eslint-config-internal": "4.0.399",
|
|
33
33
|
"@vitest/browser-webdriverio": "4.0.9",
|
|
34
34
|
"eslint": "9.19.0",
|
|
35
35
|
"react": "19.2.3",
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import { useContext, useLayoutEffect, useMemo, useState } from 'react';
|
|
2
|
-
import { cancelRender, Internals, useCurrentFrame, useDelayRender, useRemotionEnvironment, } from 'remotion';
|
|
3
|
-
import { extractFrameViaBroadcastChannel } from './extract-frame-via-broadcast-channel';
|
|
4
|
-
export const AudioForRendering = ({ volume: volumeProp, playbackRate, src, muted, loopVolumeCurveBehavior, delayRenderRetries, delayRenderTimeoutInMilliseconds, logLevel = window.remotion_logLevel, }) => {
|
|
5
|
-
const absoluteFrame = Internals.useTimelinePosition();
|
|
6
|
-
const videoConfig = Internals.useUnsafeVideoConfig();
|
|
7
|
-
const { registerRenderAsset, unregisterRenderAsset } = useContext(Internals.RenderAssetManager);
|
|
8
|
-
const frame = useCurrentFrame();
|
|
9
|
-
const volumePropsFrame = Internals.useFrameForVolumeProp(loopVolumeCurveBehavior ?? 'repeat');
|
|
10
|
-
const environment = useRemotionEnvironment();
|
|
11
|
-
const [id] = useState(() => `${Math.random()}`.replace('0.', ''));
|
|
12
|
-
if (!videoConfig) {
|
|
13
|
-
throw new Error('No video config found');
|
|
14
|
-
}
|
|
15
|
-
if (!src) {
|
|
16
|
-
throw new TypeError('No `src` was passed to <Video>.');
|
|
17
|
-
}
|
|
18
|
-
const volume = Internals.evaluateVolume({
|
|
19
|
-
volume: volumeProp,
|
|
20
|
-
frame: volumePropsFrame,
|
|
21
|
-
mediaVolume: 1,
|
|
22
|
-
});
|
|
23
|
-
Internals.warnAboutTooHighVolume(volume);
|
|
24
|
-
const shouldRenderAudio = useMemo(() => {
|
|
25
|
-
if (!window.remotion_audioEnabled) {
|
|
26
|
-
return false;
|
|
27
|
-
}
|
|
28
|
-
if (muted) {
|
|
29
|
-
return false;
|
|
30
|
-
}
|
|
31
|
-
if (volume <= 0) {
|
|
32
|
-
return false;
|
|
33
|
-
}
|
|
34
|
-
return true;
|
|
35
|
-
}, [muted, volume]);
|
|
36
|
-
const { fps } = videoConfig;
|
|
37
|
-
const { delayRender, continueRender } = useDelayRender();
|
|
38
|
-
useLayoutEffect(() => {
|
|
39
|
-
const actualFps = playbackRate ? fps / playbackRate : fps;
|
|
40
|
-
const timestamp = frame / actualFps;
|
|
41
|
-
const durationInSeconds = 1 / actualFps;
|
|
42
|
-
const newHandle = delayRender(`Extracting frame number ${frame}`, {
|
|
43
|
-
retries: delayRenderRetries ?? undefined,
|
|
44
|
-
timeoutInMilliseconds: delayRenderTimeoutInMilliseconds ?? undefined,
|
|
45
|
-
});
|
|
46
|
-
extractFrameViaBroadcastChannel({
|
|
47
|
-
src,
|
|
48
|
-
timeInSeconds: timestamp,
|
|
49
|
-
durationInSeconds,
|
|
50
|
-
logLevel: logLevel ?? 'info',
|
|
51
|
-
shouldRenderAudio,
|
|
52
|
-
isClientSideRendering: environment.isClientSideRendering,
|
|
53
|
-
})
|
|
54
|
-
.then(({ audio }) => {
|
|
55
|
-
if (audio) {
|
|
56
|
-
registerRenderAsset({
|
|
57
|
-
type: 'inline-audio',
|
|
58
|
-
id,
|
|
59
|
-
audio: Array.from(audio.data),
|
|
60
|
-
sampleRate: audio.sampleRate,
|
|
61
|
-
numberOfChannels: audio.numberOfChannels,
|
|
62
|
-
frame: absoluteFrame,
|
|
63
|
-
timestamp: audio.timestamp,
|
|
64
|
-
duration: (audio.numberOfFrames / audio.sampleRate) * 1000000,
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
continueRender(newHandle);
|
|
68
|
-
})
|
|
69
|
-
.catch((error) => {
|
|
70
|
-
cancelRender(error);
|
|
71
|
-
});
|
|
72
|
-
return () => {
|
|
73
|
-
continueRender(newHandle);
|
|
74
|
-
unregisterRenderAsset(id);
|
|
75
|
-
};
|
|
76
|
-
}, [
|
|
77
|
-
absoluteFrame,
|
|
78
|
-
continueRender,
|
|
79
|
-
delayRender,
|
|
80
|
-
delayRenderRetries,
|
|
81
|
-
delayRenderTimeoutInMilliseconds,
|
|
82
|
-
environment.isClientSideRendering,
|
|
83
|
-
fps,
|
|
84
|
-
frame,
|
|
85
|
-
id,
|
|
86
|
-
logLevel,
|
|
87
|
-
playbackRate,
|
|
88
|
-
registerRenderAsset,
|
|
89
|
-
shouldRenderAudio,
|
|
90
|
-
src,
|
|
91
|
-
unregisterRenderAsset,
|
|
92
|
-
]);
|
|
93
|
-
return null;
|
|
94
|
-
};
|
package/dist/audio.d.ts
DELETED