@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.
Files changed (59) hide show
  1. package/dist/esm/index.mjs +82 -72
  2. package/dist/video-extraction/extract-frame.js +40 -24
  3. package/package.json +4 -4
  4. package/dist/audio-for-rendering.d.ts +0 -3
  5. package/dist/audio-for-rendering.js +0 -94
  6. package/dist/audio.d.ts +0 -3
  7. package/dist/audio.js +0 -60
  8. package/dist/audiodata-to-array.d.ts +0 -0
  9. package/dist/audiodata-to-array.js +0 -1
  10. package/dist/convert-audiodata/data-types.d.ts +0 -1
  11. package/dist/convert-audiodata/data-types.js +0 -22
  12. package/dist/convert-audiodata/is-planar-format.d.ts +0 -1
  13. package/dist/convert-audiodata/is-planar-format.js +0 -3
  14. package/dist/convert-audiodata/log-audiodata.d.ts +0 -1
  15. package/dist/convert-audiodata/log-audiodata.js +0 -8
  16. package/dist/convert-audiodata/trim-audiodata.d.ts +0 -0
  17. package/dist/convert-audiodata/trim-audiodata.js +0 -1
  18. package/dist/deserialized-audiodata.d.ts +0 -15
  19. package/dist/deserialized-audiodata.js +0 -26
  20. package/dist/extract-audio.d.ts +0 -7
  21. package/dist/extract-audio.js +0 -98
  22. package/dist/extract-frame-via-broadcast-channel.d.ts +0 -15
  23. package/dist/extract-frame-via-broadcast-channel.js +0 -104
  24. package/dist/extract-frame.d.ts +0 -27
  25. package/dist/extract-frame.js +0 -21
  26. package/dist/extrct-audio.d.ts +0 -7
  27. package/dist/extrct-audio.js +0 -94
  28. package/dist/get-frames-since-keyframe.d.ts +0 -22
  29. package/dist/get-frames-since-keyframe.js +0 -41
  30. package/dist/keyframe-bank.d.ts +0 -25
  31. package/dist/keyframe-bank.js +0 -120
  32. package/dist/keyframe-manager.d.ts +0 -23
  33. package/dist/keyframe-manager.js +0 -170
  34. package/dist/log.d.ts +0 -10
  35. package/dist/log.js +0 -33
  36. package/dist/new-video-for-rendering.d.ts +0 -3
  37. package/dist/new-video-for-rendering.js +0 -108
  38. package/dist/new-video.d.ts +0 -3
  39. package/dist/new-video.js +0 -37
  40. package/dist/props.d.ts +0 -29
  41. package/dist/props.js +0 -1
  42. package/dist/remember-actual-matroska-timestamps.d.ts +0 -4
  43. package/dist/remember-actual-matroska-timestamps.js +0 -19
  44. package/dist/serialize-videoframe.d.ts +0 -0
  45. package/dist/serialize-videoframe.js +0 -1
  46. package/dist/video/media-player.d.ts +0 -62
  47. package/dist/video/media-player.js +0 -361
  48. package/dist/video/new-video-for-preview.d.ts +0 -10
  49. package/dist/video/new-video-for-preview.js +0 -108
  50. package/dist/video/timeout-utils.d.ts +0 -2
  51. package/dist/video/timeout-utils.js +0 -18
  52. package/dist/video-extraction/media-player.d.ts +0 -64
  53. package/dist/video-extraction/media-player.js +0 -501
  54. package/dist/video-extraction/new-video-for-preview.d.ts +0 -10
  55. package/dist/video-extraction/new-video-for-preview.js +0 -114
  56. package/dist/video-for-rendering.d.ts +0 -3
  57. package/dist/video-for-rendering.js +0 -108
  58. package/dist/video.d.ts +0 -3
  59. package/dist/video.js +0 -37
@@ -1,5 +1,5 @@
1
1
  // src/audio/audio.tsx
2
- import { Internals as Internals14, useRemotionEnvironment as useRemotionEnvironment2 } from "remotion";
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 Internals13,
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 sink.getVideo();
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: await sink.getDuration() };
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
- const keyframeBank = await keyframeManager.requestKeyframeBank({
3220
- packetSink: video.packetSink,
3221
- videoSampleSink: video.sampleSink,
3222
- timestamp: timeInSeconds,
3223
- src,
3224
- logLevel,
3225
- maxCacheSize
3226
- });
3227
- if (keyframeBank === "has-alpha") {
3228
- return {
3229
- type: "cannot-decode-alpha",
3230
- durationInSeconds: await sink.getDuration()
3231
- };
3232
- }
3233
- if (!keyframeBank) {
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: null,
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 = Internals13.useTimelinePosition();
3658
- const videoConfig = Internals13.useUnsafeVideoConfig();
3659
- const { registerRenderAsset, unregisterRenderAsset } = useContext3(Internals13.RenderAssetManager);
3660
- const startsAt = Internals13.useMediaStartsAt();
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(Internals13.SequenceContext);
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 = Internals13.useAudioEnabled();
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
- Internals13.Log.warn({
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
- Internals13.Log.warn({
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
- Internals13.Log.warn({
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 = Internals13.evaluateVolume({
3785
+ const volume = Internals14.evaluateVolume({
3776
3786
  volume: volumeProp,
3777
3787
  frame: volumePropsFrame,
3778
3788
  mediaVolume: 1
3779
3789
  });
3780
- Internals13.warnAboutTooHighVolume(volume);
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 } = Internals14;
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
- Internals14.addSequenceStackTraces(Audio);
3884
+ Internals15.addSequenceStackTraces(Audio);
3875
3885
 
3876
3886
  // src/video/video.tsx
3877
- import { Internals as Internals17, useRemotionEnvironment as useRemotionEnvironment4 } from "remotion";
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 Internals15,
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
- } = Internals15;
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(Internals15.TimelineContext);
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(Internals15.BufferingContextReact);
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 = Internals15.useIsPlayerBuffering(buffering);
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
- Internals15.Log.warn({ logLevel, tag: "@remotion/media" }, `Unknown container format for ${preloadedSrc} (Supported formats: https://www.remotion.dev/docs/mediabunny/formats), falling back to <OffthreadVideo>`);
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
- Internals15.Log.warn({ logLevel, tag: "@remotion/media" }, `Network error fetching ${preloadedSrc}, falling back to <OffthreadVideo>`);
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
- Internals15.Log.warn({ logLevel, tag: "@remotion/media" }, `Cannot decode ${preloadedSrc}, falling back to <OffthreadVideo>`);
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
- Internals15.Log.warn({ logLevel, tag: "@remotion/media" }, `No video or audio tracks found for ${preloadedSrc}, falling back to <OffthreadVideo>`);
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
- Internals15.Log.error({ logLevel, tag: "@remotion/media" }, "[VideoForPreview] Failed to initialize MediaPlayer", error);
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
- Internals15.Log.error({ logLevel, tag: "@remotion/media" }, "[VideoForPreview] MediaPlayer initialization failed", error);
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
- Internals15.Log.trace({ logLevel, tag: "@remotion/media" }, `[VideoForPreview] Disposing MediaPlayer`);
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 [Internals15.OBJECTFIT_CONTAIN_CLASS_NAME, className].filter(Internals15.truthy).join(" ");
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
- Internals15.Log.trace({ logLevel, tag: "@remotion/media" }, `[VideoForPreview] Updating target time to ${currentTime.toFixed(3)}s`);
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 Internals16,
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 = Internals16.useTimelinePosition();
4321
+ const absoluteFrame = Internals17.useTimelinePosition();
4312
4322
  const { fps } = useVideoConfig4();
4313
- const { registerRenderAsset, unregisterRenderAsset } = useContext5(Internals16.RenderAssetManager);
4314
- const startsAt = Internals16.useMediaStartsAt();
4315
- const sequenceContext = useContext5(Internals16.SequenceContext);
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 = Internals16.useAudioEnabled();
4327
- const videoEnabled = Internals16.useVideoEnabled();
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
- Internals16.Log.info({ logLevel, tag: "@remotion/media" }, `Unknown container format for ${src} (Supported formats: https://www.remotion.dev/docs/mediabunny/formats), falling back to <OffthreadVideo>`);
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
- Internals16.Log.warn({ logLevel, tag: "@remotion/media" }, `Cannot decode ${src}, falling back to <OffthreadVideo>`);
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
- Internals16.Log.info({ logLevel, tag: "@remotion/media" }, `Cannot decode alpha component for ${src}, falling back to <OffthreadVideo>`);
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
- Internals16.Log.warn({ logLevel, tag: "@remotion/media" }, `Network error fetching ${src} (no CORS?), falling back to <OffthreadVideo>`);
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 = Internals16.evaluateVolume({
4477
+ const volume = Internals17.evaluateVolume({
4468
4478
  volume: volumeProp,
4469
4479
  frame: volumePropsFrame,
4470
4480
  mediaVolume: 1
4471
4481
  });
4472
- Internals16.warnAboutTooHighVolume(volume);
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 [Internals16.OBJECTFIT_CONTAIN_CLASS_NAME, className].filter(Internals16.truthy).join(" ");
4537
+ return [Internals17.OBJECTFIT_CONTAIN_CLASS_NAME, className].filter(Internals17.truthy).join(" ");
4528
4538
  }, [className]);
4529
4539
  if (replaceWithOffthreadVideo) {
4530
- const fallback = /* @__PURE__ */ jsx5(Internals16.InnerOffthreadVideo, {
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: Internals16.calculateMediaDuration({
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 } = Internals17;
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
- Internals17.addSequenceStackTraces(Video);
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 sink.getVideo();
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: await sink.getDuration() };
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
- const keyframeBank = await keyframeManager.requestKeyframeBank({
42
- packetSink: video.packetSink,
43
- videoSampleSink: video.sampleSink,
44
- timestamp: timeInSeconds,
45
- src,
46
- logLevel,
47
- maxCacheSize,
48
- });
49
- if (keyframeBank === 'has-alpha') {
50
- return {
51
- type: 'cannot-decode-alpha',
52
- durationInSeconds: await sink.getDuration(),
53
- };
54
- }
55
- if (!keyframeBank) {
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: null,
72
+ frame,
59
73
  durationInSeconds: await sink.getDuration(),
60
74
  };
61
75
  }
62
- const frame = await keyframeBank.getFrameFromTimestamp(timeInSeconds);
63
- return { type: 'success', frame, durationInSeconds: await sink.getDuration() };
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.398",
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.2",
25
- "remotion": "4.0.398"
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.398",
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,3 +0,0 @@
1
- import type React from 'react';
2
- import type { AudioProps } from './props';
3
- export declare const AudioForRendering: React.FC<AudioProps>;
@@ -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
@@ -1,3 +0,0 @@
1
- import React from 'react';
2
- import type { AudioProps } from './props';
3
- export declare const Audio: React.FC<AudioProps>;