@remotion/media 4.0.490 → 4.0.492
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 +148 -39
- package/dist/media-player.d.ts +2 -0
- package/dist/prores-error.d.ts +4 -0
- package/dist/video/get-video-sequence-duration.d.ts +7 -0
- package/dist/video-extraction/add-broadcast-channel-listener.d.ts +4 -0
- package/dist/video-extraction/extract-frame-via-broadcast-channel.d.ts +3 -0
- package/dist/video-extraction/extract-frame.d.ts +3 -0
- package/dist/video-extraction/get-frames-since-keyframe.d.ts +1 -1
- package/package.json +4 -4
package/dist/esm/index.mjs
CHANGED
|
@@ -1122,6 +1122,7 @@ var makeStableFramePool = () => {
|
|
|
1122
1122
|
if (!context) {
|
|
1123
1123
|
throw new Error("Could not create canvas context");
|
|
1124
1124
|
}
|
|
1125
|
+
context.clearRect(0, 0, stableCanvas.width, stableCanvas.height);
|
|
1125
1126
|
context.drawImage(canvas, 0, 0);
|
|
1126
1127
|
let released = false;
|
|
1127
1128
|
const stableFrame = {
|
|
@@ -1815,6 +1816,9 @@ class MediaPlayer {
|
|
|
1815
1816
|
}
|
|
1816
1817
|
const canDecode = await videoTrack.canDecode();
|
|
1817
1818
|
if (!canDecode) {
|
|
1819
|
+
if (videoTrack.codec === "prores") {
|
|
1820
|
+
return { type: "cannot-decode-prores" };
|
|
1821
|
+
}
|
|
1818
1822
|
return { type: "cannot-decode" };
|
|
1819
1823
|
}
|
|
1820
1824
|
if (this.isDisposalError()) {
|
|
@@ -2533,6 +2537,9 @@ var AudioForPreviewAssertedShowing = ({
|
|
|
2533
2537
|
handleError(new Error(`No video or audio tracks found for ${preloadedSrc}.`), `No video or audio tracks found for ${preloadedSrc}, falling back to <Html5Audio>`);
|
|
2534
2538
|
return;
|
|
2535
2539
|
}
|
|
2540
|
+
if (result.type === "cannot-decode-prores") {
|
|
2541
|
+
throw new Error(`Encountered ProRes media for ${preloadedSrc}. But this should never happen, since you used the <Audio> tag. Please report this as a bug.`);
|
|
2542
|
+
}
|
|
2536
2543
|
if (result.type === "success") {
|
|
2537
2544
|
setMediaPlayerReady(true);
|
|
2538
2545
|
setMediaDurationInSeconds(result.durationInSeconds);
|
|
@@ -3916,6 +3923,9 @@ var getSinks = async (src, logLevel, credentials, requestInit) => {
|
|
|
3916
3923
|
}
|
|
3917
3924
|
const canDecode = await videoTrack.canDecode();
|
|
3918
3925
|
if (!canDecode) {
|
|
3926
|
+
if (videoTrack.codec === "prores") {
|
|
3927
|
+
return "cannot-decode-prores";
|
|
3928
|
+
}
|
|
3919
3929
|
return "cannot-decode";
|
|
3920
3930
|
}
|
|
3921
3931
|
const sampleSink = new VideoSampleSink(videoTrack);
|
|
@@ -4174,6 +4184,12 @@ var extractFrameInternal = async ({
|
|
|
4174
4184
|
if (video === "cannot-decode") {
|
|
4175
4185
|
return { type: "cannot-decode", durationInSeconds: mediaDurationInSeconds };
|
|
4176
4186
|
}
|
|
4187
|
+
if (video === "cannot-decode-prores") {
|
|
4188
|
+
return {
|
|
4189
|
+
type: "cannot-decode-prores",
|
|
4190
|
+
durationInSeconds: mediaDurationInSeconds
|
|
4191
|
+
};
|
|
4192
|
+
}
|
|
4177
4193
|
if (video === "unknown-container-format") {
|
|
4178
4194
|
return { type: "unknown-container-format" };
|
|
4179
4195
|
}
|
|
@@ -4329,6 +4345,12 @@ var extractFrameAndAudio = async ({
|
|
|
4329
4345
|
durationInSeconds: video.durationInSeconds
|
|
4330
4346
|
};
|
|
4331
4347
|
}
|
|
4348
|
+
if (video?.type === "cannot-decode-prores") {
|
|
4349
|
+
return {
|
|
4350
|
+
type: "cannot-decode-prores",
|
|
4351
|
+
durationInSeconds: video.durationInSeconds
|
|
4352
|
+
};
|
|
4353
|
+
}
|
|
4332
4354
|
if (video?.type === "unknown-container-format") {
|
|
4333
4355
|
return { type: "unknown-container-format" };
|
|
4334
4356
|
}
|
|
@@ -4416,6 +4438,15 @@ var addBroadcastChannelListener = () => {
|
|
|
4416
4438
|
window.remotion_broadcastChannel.postMessage(cannotDecodeResponse);
|
|
4417
4439
|
return;
|
|
4418
4440
|
}
|
|
4441
|
+
if (result.type === "cannot-decode-prores") {
|
|
4442
|
+
const cannotDecodeProresResponse = {
|
|
4443
|
+
type: "response-cannot-decode-prores",
|
|
4444
|
+
id: data.id,
|
|
4445
|
+
durationInSeconds: result.durationInSeconds
|
|
4446
|
+
};
|
|
4447
|
+
window.remotion_broadcastChannel.postMessage(cannotDecodeProresResponse);
|
|
4448
|
+
return;
|
|
4449
|
+
}
|
|
4419
4450
|
if (result.type === "cannot-decode-alpha") {
|
|
4420
4451
|
const cannotDecodeAlphaResponse = {
|
|
4421
4452
|
type: "response-cannot-decode-alpha",
|
|
@@ -4562,6 +4593,14 @@ var extractFrameViaBroadcastChannel = async ({
|
|
|
4562
4593
|
window.remotion_broadcastChannel.removeEventListener("message", onMessage);
|
|
4563
4594
|
return;
|
|
4564
4595
|
}
|
|
4596
|
+
if (data.type === "response-cannot-decode-prores") {
|
|
4597
|
+
resolve({
|
|
4598
|
+
type: "cannot-decode-prores",
|
|
4599
|
+
durationInSeconds: data.durationInSeconds
|
|
4600
|
+
});
|
|
4601
|
+
window.remotion_broadcastChannel.removeEventListener("message", onMessage);
|
|
4602
|
+
return;
|
|
4603
|
+
}
|
|
4565
4604
|
if (data.type === "response-network-error") {
|
|
4566
4605
|
resolve({ type: "network-error" });
|
|
4567
4606
|
window.remotion_broadcastChannel.removeEventListener("message", onMessage);
|
|
@@ -4735,6 +4774,9 @@ var AudioForRendering = ({
|
|
|
4735
4774
|
if (result.type === "cannot-decode-alpha") {
|
|
4736
4775
|
throw new Error(`Cannot decode alpha component for ${src}, and 'disallowFallbackToHtml5Audio' was set. But this should never happen, since you used the <Audio> tag. Please report this as a bug.`);
|
|
4737
4776
|
}
|
|
4777
|
+
if (result.type === "cannot-decode-prores") {
|
|
4778
|
+
throw new Error(`Encountered ProRes media for ${src}. But this should never happen, since you used the <Audio> tag. Please report this as a bug.`);
|
|
4779
|
+
}
|
|
4738
4780
|
if (result.type === "network-error") {
|
|
4739
4781
|
handleError(new Error(`Network error fetching ${src}.`), new Error(`Cannot render audio "${src}": Network error while fetching the audio (possibly CORS).`), `Network error fetching ${src}, falling back to <Html5Audio>`);
|
|
4740
4782
|
return;
|
|
@@ -4834,6 +4876,12 @@ var AudioForRendering = ({
|
|
|
4834
4876
|
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
4835
4877
|
var { validateMediaProps } = Internals17;
|
|
4836
4878
|
var audioSchema = {
|
|
4879
|
+
src: {
|
|
4880
|
+
type: "asset",
|
|
4881
|
+
default: undefined,
|
|
4882
|
+
description: "Source",
|
|
4883
|
+
keyframable: false
|
|
4884
|
+
},
|
|
4837
4885
|
...Internals17.baseSchema,
|
|
4838
4886
|
volume: {
|
|
4839
4887
|
type: "number",
|
|
@@ -4948,13 +4996,34 @@ var Audio = Interactive.withSchema({
|
|
|
4948
4996
|
// src/video/video.tsx
|
|
4949
4997
|
import React6, { useMemo as useMemo6, useState as useState6 } from "react";
|
|
4950
4998
|
import {
|
|
4951
|
-
Internals as
|
|
4999
|
+
Internals as Internals22,
|
|
4952
5000
|
Interactive as Interactive2,
|
|
4953
5001
|
Sequence as Sequence2,
|
|
4954
5002
|
useRemotionEnvironment as useRemotionEnvironment4,
|
|
4955
5003
|
useVideoConfig as useVideoConfig5
|
|
4956
5004
|
} from "remotion";
|
|
4957
5005
|
|
|
5006
|
+
// src/video/get-video-sequence-duration.ts
|
|
5007
|
+
import { Internals as Internals18 } from "remotion";
|
|
5008
|
+
var getVideoSequenceDuration = ({
|
|
5009
|
+
durationInFrames,
|
|
5010
|
+
loop,
|
|
5011
|
+
playbackRate,
|
|
5012
|
+
trimAfter,
|
|
5013
|
+
trimBefore
|
|
5014
|
+
}) => {
|
|
5015
|
+
if (loop || trimAfter === undefined) {
|
|
5016
|
+
return durationInFrames;
|
|
5017
|
+
}
|
|
5018
|
+
const trimmedDuration = Internals18.calculateMediaDuration({
|
|
5019
|
+
trimAfter,
|
|
5020
|
+
trimBefore,
|
|
5021
|
+
playbackRate,
|
|
5022
|
+
mediaDurationInFrames: Infinity
|
|
5023
|
+
});
|
|
5024
|
+
return Math.min(durationInFrames ?? Infinity, trimmedDuration);
|
|
5025
|
+
};
|
|
5026
|
+
|
|
4958
5027
|
// src/video/video-for-preview.tsx
|
|
4959
5028
|
import {
|
|
4960
5029
|
useCallback,
|
|
@@ -4967,12 +5036,25 @@ import {
|
|
|
4967
5036
|
} from "react";
|
|
4968
5037
|
import {
|
|
4969
5038
|
Html5Video,
|
|
4970
|
-
Internals as
|
|
5039
|
+
Internals as Internals20,
|
|
4971
5040
|
useBufferState as useBufferState2,
|
|
4972
5041
|
useCurrentFrame as useCurrentFrame3,
|
|
4973
5042
|
useVideoConfig as useVideoConfig3
|
|
4974
5043
|
} from "remotion";
|
|
4975
5044
|
|
|
5045
|
+
// src/prores-error.ts
|
|
5046
|
+
var PRORES_DOCS_URL = "https://www.remotion.dev/docs/videos/prores";
|
|
5047
|
+
var proresDecoderNotEnabledMessage = (src) => {
|
|
5048
|
+
return `Cannot decode "${src}": it is encoded with Apple ProRes, which WebCodecs does not support natively. ` + `ProRes decoding is not enabled by default. Register the ProRes decoder by calling ` + `registerProresDecoder() from "@mediabunny/prores" in your entry point, before registerRoot(). ` + `See ${PRORES_DOCS_URL}. ` + `(This is required to decode a ProRes source for both preview and rendering — it is unrelated to exporting a video as ProRes.)`;
|
|
5049
|
+
};
|
|
5050
|
+
|
|
5051
|
+
class ProResDecoderNotEnabledError extends Error {
|
|
5052
|
+
constructor(src) {
|
|
5053
|
+
super(proresDecoderNotEnabledMessage(src));
|
|
5054
|
+
this.name = "ProResDecoderNotEnabledError";
|
|
5055
|
+
}
|
|
5056
|
+
}
|
|
5057
|
+
|
|
4976
5058
|
// src/video/video-frame-cache.ts
|
|
4977
5059
|
var cache = new Map;
|
|
4978
5060
|
var cacheVideoFrame = (src, sourceCanvas) => {
|
|
@@ -4997,7 +5079,7 @@ var getCachedVideoFrame = (src) => {
|
|
|
4997
5079
|
};
|
|
4998
5080
|
|
|
4999
5081
|
// src/video/warn-object-fit-css.ts
|
|
5000
|
-
import { Internals as
|
|
5082
|
+
import { Internals as Internals19 } from "remotion";
|
|
5001
5083
|
var OBJECT_FIT_CLASS_PATTERN = /\bobject-(contain|cover|fill|none|scale-down)\b/;
|
|
5002
5084
|
var warnedStyle = false;
|
|
5003
5085
|
var warnedClassName = false;
|
|
@@ -5008,11 +5090,11 @@ var warnAboutObjectFitInStyleOrClassName = ({
|
|
|
5008
5090
|
}) => {
|
|
5009
5091
|
if (!warnedStyle && style?.objectFit) {
|
|
5010
5092
|
warnedStyle = true;
|
|
5011
|
-
|
|
5093
|
+
Internals19.Log.warn({ logLevel, tag: "@remotion/media" }, "Use the `objectFit` prop instead of the `style` prop.");
|
|
5012
5094
|
}
|
|
5013
5095
|
if (!warnedClassName && className && OBJECT_FIT_CLASS_PATTERN.test(className)) {
|
|
5014
5096
|
warnedClassName = true;
|
|
5015
|
-
|
|
5097
|
+
Internals19.Log.warn({ logLevel, tag: "@remotion/media" }, "Use the `objectFit` prop instead of `object-*` CSS class names.");
|
|
5016
5098
|
}
|
|
5017
5099
|
};
|
|
5018
5100
|
|
|
@@ -5030,7 +5112,7 @@ var {
|
|
|
5030
5112
|
usePreload: usePreload2,
|
|
5031
5113
|
SequenceContext: SequenceContext2,
|
|
5032
5114
|
useEffectChainState
|
|
5033
|
-
} =
|
|
5115
|
+
} = Internals20;
|
|
5034
5116
|
var VideoForPreviewAssertedShowing = ({
|
|
5035
5117
|
src: unpreloadedSrc,
|
|
5036
5118
|
style,
|
|
@@ -5073,7 +5155,7 @@ var VideoForPreviewAssertedShowing = ({
|
|
|
5073
5155
|
const [mediaPlayerReady, setMediaPlayerReady] = useState4(false);
|
|
5074
5156
|
const [shouldFallbackToNativeVideo, setShouldFallbackToNativeVideo] = useState4(false);
|
|
5075
5157
|
const [playing] = Timeline2.usePlayingState();
|
|
5076
|
-
const { playbackRate: globalPlaybackRate } =
|
|
5158
|
+
const { playbackRate: globalPlaybackRate } = Internals20.usePlaybackRate();
|
|
5077
5159
|
const sharedAudioContext = useContext4(SharedAudioContext2);
|
|
5078
5160
|
const buffer = useBufferState2();
|
|
5079
5161
|
const canvasRefCallback = useCallback((canvas) => {
|
|
@@ -5110,12 +5192,12 @@ var VideoForPreviewAssertedShowing = ({
|
|
|
5110
5192
|
const currentTimeRef = useRef2(currentTime);
|
|
5111
5193
|
currentTimeRef.current = currentTime;
|
|
5112
5194
|
const preloadedSrc = usePreload2(src);
|
|
5113
|
-
const buffering = useContext4(
|
|
5195
|
+
const buffering = useContext4(Internals20.BufferingContextReact);
|
|
5114
5196
|
if (!buffering) {
|
|
5115
5197
|
throw new Error("useMediaPlayback must be used inside a <BufferingContext>");
|
|
5116
5198
|
}
|
|
5117
5199
|
const effectiveMuted = muted || playerMuted || userPreferredVolume <= 0;
|
|
5118
|
-
const isPlayerBuffering =
|
|
5200
|
+
const isPlayerBuffering = Internals20.useIsPlayerBuffering(buffering);
|
|
5119
5201
|
const initialPlaying = useRef2(playing && !isPlayerBuffering);
|
|
5120
5202
|
const initialIsPremounting = useRef2(isPremounting);
|
|
5121
5203
|
const initialIsPostmounting = useRef2(isPostmounting);
|
|
@@ -5213,7 +5295,7 @@ var VideoForPreviewAssertedShowing = ({
|
|
|
5213
5295
|
if (action === "fail") {
|
|
5214
5296
|
throw errorToUse;
|
|
5215
5297
|
}
|
|
5216
|
-
|
|
5298
|
+
Internals20.Log.warn({ logLevel, tag: "@remotion/media" }, fallbackMessage);
|
|
5217
5299
|
setShouldFallbackToNativeVideo(true);
|
|
5218
5300
|
};
|
|
5219
5301
|
if (result.type === "unknown-container-format") {
|
|
@@ -5228,6 +5310,9 @@ var VideoForPreviewAssertedShowing = ({
|
|
|
5228
5310
|
handleError(new Error(`Cannot decode ${preloadedSrc}.`), `Cannot decode ${preloadedSrc}, falling back to <OffthreadVideo>`);
|
|
5229
5311
|
return;
|
|
5230
5312
|
}
|
|
5313
|
+
if (result.type === "cannot-decode-prores") {
|
|
5314
|
+
throw new ProResDecoderNotEnabledError(preloadedSrc);
|
|
5315
|
+
}
|
|
5231
5316
|
if (result.type === "no-tracks") {
|
|
5232
5317
|
handleError(new Error(`No video or audio tracks found for ${preloadedSrc}.`), `No video or audio tracks found for ${preloadedSrc}, falling back to <OffthreadVideo>`);
|
|
5233
5318
|
return;
|
|
@@ -5238,6 +5323,10 @@ var VideoForPreviewAssertedShowing = ({
|
|
|
5238
5323
|
hasDrawnRealFrameRef.current = true;
|
|
5239
5324
|
}
|
|
5240
5325
|
}).catch((error) => {
|
|
5326
|
+
if (error instanceof ProResDecoderNotEnabledError) {
|
|
5327
|
+
onErrorRef.current?.(error);
|
|
5328
|
+
throw error;
|
|
5329
|
+
}
|
|
5241
5330
|
const [action, errorToUse] = callOnErrorAndResolve({
|
|
5242
5331
|
onError: onErrorRef.current,
|
|
5243
5332
|
error,
|
|
@@ -5248,7 +5337,7 @@ var VideoForPreviewAssertedShowing = ({
|
|
|
5248
5337
|
if (action === "fail") {
|
|
5249
5338
|
throw errorToUse;
|
|
5250
5339
|
}
|
|
5251
|
-
|
|
5340
|
+
Internals20.Log.error({ logLevel, tag: "@remotion/media" }, "[VideoForPreview] Failed to initialize MediaPlayer", errorToUse);
|
|
5252
5341
|
setShouldFallbackToNativeVideo(true);
|
|
5253
5342
|
});
|
|
5254
5343
|
} catch (error) {
|
|
@@ -5262,12 +5351,12 @@ var VideoForPreviewAssertedShowing = ({
|
|
|
5262
5351
|
if (action === "fail") {
|
|
5263
5352
|
throw errorToUse;
|
|
5264
5353
|
}
|
|
5265
|
-
|
|
5354
|
+
Internals20.Log.error({ logLevel, tag: "@remotion/media" }, "[VideoForPreview] MediaPlayer initialization failed", errorToUse);
|
|
5266
5355
|
setShouldFallbackToNativeVideo(true);
|
|
5267
5356
|
}
|
|
5268
5357
|
return () => {
|
|
5269
5358
|
if (mediaPlayerRef.current) {
|
|
5270
|
-
|
|
5359
|
+
Internals20.Log.trace({ logLevel, tag: "@remotion/media" }, `[VideoForPreview] Disposing MediaPlayer`);
|
|
5271
5360
|
mediaPlayerRef.current.dispose();
|
|
5272
5361
|
mediaPlayerRef.current = null;
|
|
5273
5362
|
}
|
|
@@ -5291,7 +5380,7 @@ var VideoForPreviewAssertedShowing = ({
|
|
|
5291
5380
|
]);
|
|
5292
5381
|
warnAboutObjectFitInStyleOrClassName({ style, className, logLevel });
|
|
5293
5382
|
const classNameValue = useMemo4(() => {
|
|
5294
|
-
return [
|
|
5383
|
+
return [Internals20.OBJECTFIT_CONTAIN_CLASS_NAME, className].filter(Internals20.truthy).join(" ");
|
|
5295
5384
|
}, [className]);
|
|
5296
5385
|
useCommonEffects({
|
|
5297
5386
|
mediaPlayerRef,
|
|
@@ -5415,7 +5504,7 @@ import {
|
|
|
5415
5504
|
useState as useState5
|
|
5416
5505
|
} from "react";
|
|
5417
5506
|
import {
|
|
5418
|
-
Internals as
|
|
5507
|
+
Internals as Internals21,
|
|
5419
5508
|
Loop,
|
|
5420
5509
|
random as random2,
|
|
5421
5510
|
useCurrentFrame as useCurrentFrame4,
|
|
@@ -5456,11 +5545,11 @@ var VideoForRendering = ({
|
|
|
5456
5545
|
throw new TypeError("No `src` was passed to <Video>.");
|
|
5457
5546
|
}
|
|
5458
5547
|
const frame = useCurrentFrame4();
|
|
5459
|
-
const absoluteFrame =
|
|
5548
|
+
const absoluteFrame = Internals21.useTimelinePosition();
|
|
5460
5549
|
const { fps } = useVideoConfig4();
|
|
5461
|
-
const { registerRenderAsset, unregisterRenderAsset } = useContext5(
|
|
5462
|
-
const startsAt =
|
|
5463
|
-
const sequenceContext = useContext5(
|
|
5550
|
+
const { registerRenderAsset, unregisterRenderAsset } = useContext5(Internals21.RenderAssetManager);
|
|
5551
|
+
const startsAt = Internals21.useMediaStartsAt();
|
|
5552
|
+
const sequenceContext = useContext5(Internals21.SequenceContext);
|
|
5464
5553
|
const id = useMemo5(() => `media-video-${random2(src)}-${sequenceContext?.cumulatedFrom}-${sequenceContext?.relativeFrom}-${sequenceContext?.durationInFrames}`, [
|
|
5465
5554
|
src,
|
|
5466
5555
|
sequenceContext?.cumulatedFrom,
|
|
@@ -5472,10 +5561,10 @@ var VideoForRendering = ({
|
|
|
5472
5561
|
const canvasRef = useRef3(null);
|
|
5473
5562
|
const [replaceWithOffthreadVideo, setReplaceWithOffthreadVideo] = useState5(false);
|
|
5474
5563
|
const [initialRequestInit] = useState5(requestInit);
|
|
5475
|
-
const audioEnabled =
|
|
5476
|
-
const videoEnabled =
|
|
5564
|
+
const audioEnabled = Internals21.useAudioEnabled();
|
|
5565
|
+
const videoEnabled = Internals21.useVideoEnabled();
|
|
5477
5566
|
const maxCacheSize = useMaxMediaCacheSize(logLevel);
|
|
5478
|
-
const effectChainState =
|
|
5567
|
+
const effectChainState = Internals21.useEffectChainState();
|
|
5479
5568
|
const [error, setError] = useState5(null);
|
|
5480
5569
|
if (error) {
|
|
5481
5570
|
throw error;
|
|
@@ -5540,7 +5629,7 @@ var VideoForRendering = ({
|
|
|
5540
5629
|
return;
|
|
5541
5630
|
}
|
|
5542
5631
|
if (window.remotion_isMainTab) {
|
|
5543
|
-
|
|
5632
|
+
Internals21.Log.warn({ logLevel, tag: "@remotion/media" }, fallbackMessage);
|
|
5544
5633
|
}
|
|
5545
5634
|
setReplaceWithOffthreadVideo({
|
|
5546
5635
|
durationInSeconds: mediaDurationInSeconds
|
|
@@ -5554,6 +5643,12 @@ var VideoForRendering = ({
|
|
|
5554
5643
|
handleError(new Error(`Cannot decode ${src}.`), new Error(`Cannot render video "${src}": The video could not be decoded by the browser.`), `Cannot decode ${src}, falling back to <OffthreadVideo>`, result.durationInSeconds);
|
|
5555
5644
|
return;
|
|
5556
5645
|
}
|
|
5646
|
+
if (result.type === "cannot-decode-prores") {
|
|
5647
|
+
const proresError = new ProResDecoderNotEnabledError(src);
|
|
5648
|
+
onError?.(proresError);
|
|
5649
|
+
cancelRender3(proresError);
|
|
5650
|
+
return;
|
|
5651
|
+
}
|
|
5557
5652
|
if (result.type === "cannot-decode-alpha") {
|
|
5558
5653
|
handleError(new Error(`Cannot decode alpha component for ${src}.`), new Error(`Cannot render video "${src}": The alpha channel could not be decoded by the browser.`), `Cannot decode alpha component for ${src}, falling back to <OffthreadVideo>`, result.durationInSeconds);
|
|
5559
5654
|
return;
|
|
@@ -5578,7 +5673,7 @@ var VideoForRendering = ({
|
|
|
5578
5673
|
context.canvas.style.aspectRatio = `${context.canvas.width} / ${context.canvas.height}`;
|
|
5579
5674
|
context.drawImage(imageBitmap, 0, 0);
|
|
5580
5675
|
if (effects.length > 0) {
|
|
5581
|
-
const completed = await
|
|
5676
|
+
const completed = await Internals21.runEffectChain({
|
|
5582
5677
|
state: effectChainState.get(imageBitmap.width, imageBitmap.height),
|
|
5583
5678
|
source: context.canvas,
|
|
5584
5679
|
effects,
|
|
@@ -5609,12 +5704,12 @@ var VideoForRendering = ({
|
|
|
5609
5704
|
frame,
|
|
5610
5705
|
startsAt
|
|
5611
5706
|
});
|
|
5612
|
-
const volume =
|
|
5707
|
+
const volume = Internals21.evaluateVolume({
|
|
5613
5708
|
volume: volumeProp,
|
|
5614
5709
|
frame: volumePropsFrame,
|
|
5615
5710
|
mediaVolume: 1
|
|
5616
5711
|
});
|
|
5617
|
-
|
|
5712
|
+
Internals21.warnAboutTooHighVolume(volume);
|
|
5618
5713
|
if (audio && volume > 0) {
|
|
5619
5714
|
applyVolume(audio.data, volume);
|
|
5620
5715
|
registerRenderAsset({
|
|
@@ -5675,7 +5770,7 @@ var VideoForRendering = ({
|
|
|
5675
5770
|
]);
|
|
5676
5771
|
warnAboutObjectFitInStyleOrClassName({ style, className, logLevel });
|
|
5677
5772
|
const classNameValue = useMemo5(() => {
|
|
5678
|
-
return [
|
|
5773
|
+
return [Internals21.OBJECTFIT_CONTAIN_CLASS_NAME, className].filter(Internals21.truthy).join(" ");
|
|
5679
5774
|
}, [className]);
|
|
5680
5775
|
const styleWithObjectFit = useMemo5(() => {
|
|
5681
5776
|
return {
|
|
@@ -5684,7 +5779,7 @@ var VideoForRendering = ({
|
|
|
5684
5779
|
};
|
|
5685
5780
|
}, [objectFitProp, style]);
|
|
5686
5781
|
if (replaceWithOffthreadVideo) {
|
|
5687
|
-
const fallback = /* @__PURE__ */ jsx5(
|
|
5782
|
+
const fallback = /* @__PURE__ */ jsx5(Internals21.InnerOffthreadVideo, {
|
|
5688
5783
|
...props,
|
|
5689
5784
|
src,
|
|
5690
5785
|
playbackRate: playbackRate ?? 1,
|
|
@@ -5726,7 +5821,7 @@ var VideoForRendering = ({
|
|
|
5726
5821
|
}
|
|
5727
5822
|
return /* @__PURE__ */ jsx5(Loop, {
|
|
5728
5823
|
layout: "none",
|
|
5729
|
-
durationInFrames:
|
|
5824
|
+
durationInFrames: Internals21.calculateMediaDuration({
|
|
5730
5825
|
trimAfter: trimAfterValue,
|
|
5731
5826
|
mediaDurationInFrames: replaceWithOffthreadVideo.durationInSeconds * fps,
|
|
5732
5827
|
playbackRate,
|
|
@@ -5750,9 +5845,15 @@ var VideoForRendering = ({
|
|
|
5750
5845
|
|
|
5751
5846
|
// src/video/video.tsx
|
|
5752
5847
|
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
5753
|
-
var { validateMediaTrimProps, resolveTrimProps, validateMediaProps: validateMediaProps2 } =
|
|
5848
|
+
var { validateMediaTrimProps, resolveTrimProps, validateMediaProps: validateMediaProps2 } = Internals22;
|
|
5754
5849
|
var videoSchema = {
|
|
5755
|
-
|
|
5850
|
+
src: {
|
|
5851
|
+
type: "asset",
|
|
5852
|
+
default: undefined,
|
|
5853
|
+
description: "Source",
|
|
5854
|
+
keyframable: false
|
|
5855
|
+
},
|
|
5856
|
+
...Internals22.baseSchema,
|
|
5756
5857
|
volume: {
|
|
5757
5858
|
type: "number",
|
|
5758
5859
|
min: 0,
|
|
@@ -5771,8 +5872,9 @@ var videoSchema = {
|
|
|
5771
5872
|
hiddenFromList: false,
|
|
5772
5873
|
keyframable: false
|
|
5773
5874
|
},
|
|
5875
|
+
muted: { type: "boolean", default: false, description: "Muted" },
|
|
5774
5876
|
loop: { type: "boolean", default: false, description: "Loop" },
|
|
5775
|
-
...
|
|
5877
|
+
...Internals22.transformSchema
|
|
5776
5878
|
};
|
|
5777
5879
|
var InnerVideo = ({
|
|
5778
5880
|
src,
|
|
@@ -5924,12 +6026,19 @@ var VideoInner = ({
|
|
|
5924
6026
|
hidden,
|
|
5925
6027
|
...props
|
|
5926
6028
|
}) => {
|
|
5927
|
-
const fallbackLogLevel =
|
|
5928
|
-
const [mediaVolume] =
|
|
5929
|
-
const mediaStartsAt =
|
|
6029
|
+
const fallbackLogLevel = Internals22.useLogLevel();
|
|
6030
|
+
const [mediaVolume] = Internals22.useMediaVolumeState();
|
|
6031
|
+
const mediaStartsAt = Internals22.useMediaStartsAt();
|
|
5930
6032
|
const videoConfig = useVideoConfig5();
|
|
5931
6033
|
const sequenceDurationInFrames = Math.min(durationInFrames ?? Infinity, Math.max(0, videoConfig.durationInFrames - (from ?? 0)));
|
|
5932
|
-
const
|
|
6034
|
+
const videoSequenceDuration = getVideoSequenceDuration({
|
|
6035
|
+
durationInFrames,
|
|
6036
|
+
loop: loop ?? false,
|
|
6037
|
+
playbackRate: playbackRate ?? 1,
|
|
6038
|
+
trimAfter,
|
|
6039
|
+
trimBefore
|
|
6040
|
+
});
|
|
6041
|
+
const basicInfo = Internals22.useBasicMediaInTimeline({
|
|
5933
6042
|
src,
|
|
5934
6043
|
volume,
|
|
5935
6044
|
playbackRate: playbackRate ?? 1,
|
|
@@ -5964,11 +6073,11 @@ var VideoInner = ({
|
|
|
5964
6073
|
type: "video",
|
|
5965
6074
|
data: basicInfo
|
|
5966
6075
|
}), [basicInfo]);
|
|
5967
|
-
const memoizedEffects =
|
|
6076
|
+
const memoizedEffects = Internals22.useMemoizedEffects({
|
|
5968
6077
|
effects: effects ?? [],
|
|
5969
6078
|
overrideId: controls?.overrideId ?? null
|
|
5970
6079
|
});
|
|
5971
|
-
const memoizedEffectDefinitions =
|
|
6080
|
+
const memoizedEffectDefinitions = Internals22.useMemoizedEffectDefinitions(effects ?? []);
|
|
5972
6081
|
const refForOutline = React6.useRef(null);
|
|
5973
6082
|
if (sequenceDurationInFrames === 0) {
|
|
5974
6083
|
return null;
|
|
@@ -5976,7 +6085,7 @@ var VideoInner = ({
|
|
|
5976
6085
|
return /* @__PURE__ */ jsx6(Sequence2, {
|
|
5977
6086
|
layout: "none",
|
|
5978
6087
|
from: from ?? 0,
|
|
5979
|
-
durationInFrames:
|
|
6088
|
+
durationInFrames: videoSequenceDuration,
|
|
5980
6089
|
freeze,
|
|
5981
6090
|
_remotionInternalStack: stack,
|
|
5982
6091
|
_remotionInternalIsMedia: isMedia,
|
package/dist/media-player.d.ts
CHANGED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const getVideoSequenceDuration: ({ durationInFrames, loop, playbackRate, trimAfter, trimBefore, }: {
|
|
2
|
+
readonly durationInFrames: number | undefined;
|
|
3
|
+
readonly loop: boolean;
|
|
4
|
+
readonly playbackRate: number;
|
|
5
|
+
readonly trimAfter: number | undefined;
|
|
6
|
+
readonly trimBefore: number | undefined;
|
|
7
|
+
}) => number | undefined;
|
|
@@ -15,6 +15,10 @@ export type MessageFromMainTab = {
|
|
|
15
15
|
type: 'response-cannot-decode';
|
|
16
16
|
id: string;
|
|
17
17
|
durationInSeconds: number | null;
|
|
18
|
+
} | {
|
|
19
|
+
type: 'response-cannot-decode-prores';
|
|
20
|
+
id: string;
|
|
21
|
+
durationInSeconds: number | null;
|
|
18
22
|
} | {
|
|
19
23
|
type: 'response-cannot-decode-alpha';
|
|
20
24
|
id: string;
|
|
@@ -8,6 +8,9 @@ export type ExtractFrameViaBroadcastChannelResult = {
|
|
|
8
8
|
} | {
|
|
9
9
|
type: 'cannot-decode';
|
|
10
10
|
durationInSeconds: number | null;
|
|
11
|
+
} | {
|
|
12
|
+
type: 'cannot-decode-prores';
|
|
13
|
+
durationInSeconds: number | null;
|
|
11
14
|
} | {
|
|
12
15
|
type: 'cannot-decode-alpha';
|
|
13
16
|
durationInSeconds: number | null;
|
|
@@ -7,7 +7,7 @@ type AudioSinks = {
|
|
|
7
7
|
sampleSink: AudioSampleSink;
|
|
8
8
|
};
|
|
9
9
|
export type AudioSinkResult = AudioSinks | 'no-audio-track' | 'cannot-decode-audio' | 'unknown-container-format' | 'network-error';
|
|
10
|
-
export type VideoSinkResult = VideoSinks | 'no-video-track' | 'cannot-decode' | 'cannot-decode-alpha' | 'unknown-container-format' | 'network-error';
|
|
10
|
+
export type VideoSinkResult = VideoSinks | 'no-video-track' | 'cannot-decode' | 'cannot-decode-prores' | 'cannot-decode-alpha' | 'unknown-container-format' | 'network-error';
|
|
11
11
|
export declare const getSinks: (src: string, logLevel: "error" | "info" | "trace" | "verbose" | "warn", credentials: RequestCredentials | undefined, requestInit?: MediaRequestInit | undefined) => Promise<{
|
|
12
12
|
getVideo: () => Promise<VideoSinkResult>;
|
|
13
13
|
getAudio: (index: number | null) => Promise<AudioSinkResult>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remotion/media",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.492",
|
|
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.50.8",
|
|
26
|
-
"remotion": "4.0.
|
|
26
|
+
"remotion": "4.0.492",
|
|
27
27
|
"zod": "4.3.6"
|
|
28
28
|
},
|
|
29
29
|
"peerDependencies": {
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
"react-dom": ">=16.8.0"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"@remotion/eslint-config-internal": "4.0.
|
|
35
|
-
"@remotion/player": "4.0.
|
|
34
|
+
"@remotion/eslint-config-internal": "4.0.492",
|
|
35
|
+
"@remotion/player": "4.0.492",
|
|
36
36
|
"@vitest/browser-webdriverio": "4.0.9",
|
|
37
37
|
"eslint": "9.19.0",
|
|
38
38
|
"react": "19.2.3",
|