@remotion/media 4.0.357 → 4.0.361

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 (38) hide show
  1. package/dist/audio/audio-for-preview.js +29 -13
  2. package/dist/audio/audio-for-rendering.js +8 -6
  3. package/dist/audio-extraction/extract-audio.js +1 -0
  4. package/dist/browser-can-use-webgl2.d.ts +1 -0
  5. package/dist/browser-can-use-webgl2.js +13 -0
  6. package/dist/caches.d.ts +1 -1
  7. package/dist/caches.js +3 -3
  8. package/dist/esm/index.mjs +568 -327
  9. package/dist/extract-frame-and-audio.js +6 -0
  10. package/dist/get-time-in-seconds.d.ts +2 -1
  11. package/dist/get-time-in-seconds.js +10 -10
  12. package/dist/show-in-timeline.d.ts +8 -0
  13. package/dist/show-in-timeline.js +31 -0
  14. package/dist/use-media-in-timeline.d.ts +19 -0
  15. package/dist/use-media-in-timeline.js +103 -0
  16. package/dist/video/media-player.d.ts +11 -5
  17. package/dist/video/media-player.js +74 -36
  18. package/dist/video/video-for-preview.d.ts +9 -9
  19. package/dist/video/video-for-preview.js +43 -20
  20. package/dist/video/video-for-rendering.js +21 -5
  21. package/dist/video-extraction/extract-frame-via-broadcast-channel.d.ts +3 -0
  22. package/dist/video-extraction/extract-frame-via-broadcast-channel.js +17 -0
  23. package/dist/video-extraction/extract-frame.d.ts +3 -0
  24. package/dist/video-extraction/extract-frame.js +7 -0
  25. package/dist/video-extraction/keyframe-manager.d.ts +1 -1
  26. package/dist/video-extraction/keyframe-manager.js +5 -0
  27. package/package.json +54 -54
  28. package/LICENSE.md +0 -49
  29. package/dist/convert-audiodata/apply-tonefrequency.d.ts +0 -2
  30. package/dist/convert-audiodata/apply-tonefrequency.js +0 -43
  31. package/dist/convert-audiodata/wsola.d.ts +0 -13
  32. package/dist/convert-audiodata/wsola.js +0 -197
  33. package/dist/get-sink-weak.d.ts +0 -13
  34. package/dist/get-sink-weak.js +0 -15
  35. package/dist/log.d.ts +0 -10
  36. package/dist/log.js +0 -33
  37. package/dist/video/resolve-playback-time.d.ts +0 -8
  38. package/dist/video/resolve-playback-time.js +0 -22
@@ -1,8 +1,10 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { useContext, useEffect, useMemo, useRef, useState } from 'react';
3
3
  import { Internals, Audio as RemotionAudio, useBufferState, useCurrentFrame, } from 'remotion';
4
+ import { useLoopDisplay } from '../show-in-timeline';
5
+ import { useMediaInTimeline } from '../use-media-in-timeline';
4
6
  import { MediaPlayer } from '../video/media-player';
5
- const { useUnsafeVideoConfig, Timeline, SharedAudioContext, useMediaMutedState, useMediaVolumeState, useFrameForVolumeProp, evaluateVolume, warnAboutTooHighVolume, usePreload, useMediaInTimeline, SequenceContext, } = Internals;
7
+ const { useUnsafeVideoConfig, Timeline, SharedAudioContext, useMediaMutedState, useMediaVolumeState, useFrameForVolumeProp, evaluateVolume, warnAboutTooHighVolume, usePreload, SequenceContext, } = Internals;
6
8
  const NewAudioForPreview = ({ src, playbackRate, logLevel, muted, volume, loopVolumeCurveBehavior, loop, trimAfter, trimBefore, name, showInTimeline, stack, disallowFallbackToHtml5Audio, toneFrequency, audioStreamIndex, fallbackHtml5AudioProps, }) => {
7
9
  const videoConfig = useUnsafeVideoConfig();
8
10
  const frame = useCurrentFrame();
@@ -34,8 +36,14 @@ const NewAudioForPreview = ({ src, playbackRate, logLevel, muted, volume, loopVo
34
36
  const currentTimeRef = useRef(currentTime);
35
37
  currentTimeRef.current = currentTime;
36
38
  const preloadedSrc = usePreload(src);
37
- const [timelineId] = useState(() => String(Math.random()));
38
39
  const parentSequence = useContext(SequenceContext);
40
+ const loopDisplay = useLoopDisplay({
41
+ loop,
42
+ mediaDurationInSeconds: videoConfig.durationInFrames,
43
+ playbackRate,
44
+ trimAfter,
45
+ trimBefore,
46
+ });
39
47
  useMediaInTimeline({
40
48
  volume,
41
49
  mediaVolume,
@@ -43,11 +51,13 @@ const NewAudioForPreview = ({ src, playbackRate, logLevel, muted, volume, loopVo
43
51
  src,
44
52
  playbackRate,
45
53
  displayName: name ?? null,
46
- id: timelineId,
47
54
  stack,
48
55
  showInTimeline,
49
56
  premountDisplay: parentSequence?.premountDisplay ?? null,
50
57
  postmountDisplay: parentSequence?.postmountDisplay ?? null,
58
+ loopDisplay,
59
+ trimAfter,
60
+ trimBefore,
51
61
  });
52
62
  useEffect(() => {
53
63
  if (!sharedAudioContext)
@@ -60,10 +70,9 @@ const NewAudioForPreview = ({ src, playbackRate, logLevel, muted, volume, loopVo
60
70
  logLevel,
61
71
  sharedAudioContext: sharedAudioContext.audioContext,
62
72
  loop,
63
- trimAfterSeconds: trimAfter ? trimAfter / videoConfig.fps : undefined,
64
- trimBeforeSeconds: trimBefore
65
- ? trimBefore / videoConfig.fps
66
- : undefined,
73
+ trimAfter,
74
+ trimBefore,
75
+ fps: videoConfig.fps,
67
76
  canvas: null,
68
77
  playbackRate,
69
78
  audioStreamIndex: audioStreamIndex ?? 0,
@@ -76,7 +85,7 @@ const NewAudioForPreview = ({ src, playbackRate, logLevel, muted, volume, loopVo
76
85
  if (disallowFallbackToHtml5Audio) {
77
86
  throw new Error(`Unknown container format ${preloadedSrc}, and 'disallowFallbackToHtml5Audio' was set.`);
78
87
  }
79
- Internals.Log.warn({ logLevel, tag: '@remotion/media' }, `Unknown container format for ${preloadedSrc} (Supported formats: https://www.remotion.dev/docs/mediabunny/formats), falling back to <Audio>`);
88
+ Internals.Log.warn({ logLevel, tag: '@remotion/media' }, `Unknown container format for ${preloadedSrc} (Supported formats: https://www.remotion.dev/docs/mediabunny/formats), falling back to <Html5Audio>`);
80
89
  setShouldFallbackToNativeAudio(true);
81
90
  return;
82
91
  }
@@ -84,7 +93,7 @@ const NewAudioForPreview = ({ src, playbackRate, logLevel, muted, volume, loopVo
84
93
  if (disallowFallbackToHtml5Audio) {
85
94
  throw new Error(`Network error fetching ${preloadedSrc}, and 'disallowFallbackToHtml5Audio' was set.`);
86
95
  }
87
- Internals.Log.warn({ logLevel, tag: '@remotion/media' }, `Network error fetching ${preloadedSrc}, falling back to <Audio>`);
96
+ Internals.Log.warn({ logLevel, tag: '@remotion/media' }, `Network error fetching ${preloadedSrc}, falling back to <Html5Audio>`);
88
97
  setShouldFallbackToNativeAudio(true);
89
98
  return;
90
99
  }
@@ -92,7 +101,7 @@ const NewAudioForPreview = ({ src, playbackRate, logLevel, muted, volume, loopVo
92
101
  if (disallowFallbackToHtml5Audio) {
93
102
  throw new Error(`Cannot decode ${preloadedSrc}, and 'disallowFallbackToHtml5Audio' was set.`);
94
103
  }
95
- Internals.Log.warn({ logLevel, tag: '@remotion/media' }, `Cannot decode ${preloadedSrc}, falling back to <Audio>`);
104
+ Internals.Log.warn({ logLevel, tag: '@remotion/media' }, `Cannot decode ${preloadedSrc}, falling back to <Html5Audio>`);
96
105
  setShouldFallbackToNativeAudio(true);
97
106
  return;
98
107
  }
@@ -100,7 +109,7 @@ const NewAudioForPreview = ({ src, playbackRate, logLevel, muted, volume, loopVo
100
109
  if (disallowFallbackToHtml5Audio) {
101
110
  throw new Error(`No video or audio tracks found for ${preloadedSrc}, and 'disallowFallbackToHtml5Audio' was set.`);
102
111
  }
103
- Internals.Log.warn({ logLevel, tag: '@remotion/media' }, `No video or audio tracks found for ${preloadedSrc}, falling back to <Audio>`);
112
+ Internals.Log.warn({ logLevel, tag: '@remotion/media' }, `No video or audio tracks found for ${preloadedSrc}, falling back to <Html5Audio>`);
104
113
  setShouldFallbackToNativeAudio(true);
105
114
  return;
106
115
  }
@@ -193,7 +202,7 @@ const NewAudioForPreview = ({ src, playbackRate, logLevel, muted, volume, loopVo
193
202
  return;
194
203
  }
195
204
  audioPlayer.setVolume(userPreferredVolume);
196
- }, [userPreferredVolume, mediaPlayerReady, logLevel]);
205
+ }, [userPreferredVolume, mediaPlayerReady]);
197
206
  const effectivePlaybackRate = useMemo(() => playbackRate * globalPlaybackRate, [playbackRate, globalPlaybackRate]);
198
207
  useEffect(() => {
199
208
  const audioPlayer = mediaPlayerRef.current;
@@ -201,7 +210,14 @@ const NewAudioForPreview = ({ src, playbackRate, logLevel, muted, volume, loopVo
201
210
  return;
202
211
  }
203
212
  audioPlayer.setPlaybackRate(effectivePlaybackRate);
204
- }, [effectivePlaybackRate, mediaPlayerReady, logLevel]);
213
+ }, [effectivePlaybackRate, mediaPlayerReady]);
214
+ useEffect(() => {
215
+ const audioPlayer = mediaPlayerRef.current;
216
+ if (!audioPlayer || !mediaPlayerReady) {
217
+ return;
218
+ }
219
+ audioPlayer.setFps(videoConfig.fps);
220
+ }, [videoConfig.fps, mediaPlayerReady]);
205
221
  if (shouldFallbackToNativeAudio && !disallowFallbackToHtml5Audio) {
206
222
  return (_jsx(RemotionAudio, { src: src, muted: muted, volume: volume, startFrom: trimBefore, endAt: trimAfter, playbackRate: playbackRate, loopVolumeCurveBehavior: loopVolumeCurveBehavior, name: name, loop: loop, showInTimeline: showInTimeline, stack: stack ?? undefined, toneFrequency: toneFrequency, audioStreamIndex: audioStreamIndex, pauseWhenBuffering: fallbackHtml5AudioProps?.pauseWhenBuffering, ...fallbackHtml5AudioProps }));
207
223
  }
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { useContext, useLayoutEffect, useMemo, useState } from 'react';
3
- import { Audio, cancelRender, Internals, random, useCurrentFrame, useDelayRender, useRemotionEnvironment, } from 'remotion';
3
+ import { cancelRender, Html5Audio, Internals, random, useCurrentFrame, useDelayRender, useRemotionEnvironment, } from 'remotion';
4
4
  import { applyVolume } from '../convert-audiodata/apply-volume';
5
5
  import { TARGET_SAMPLE_RATE } from '../convert-audiodata/resample-audiodata';
6
6
  import { frameForVolumeProp } from '../looped-frame';
@@ -69,7 +69,7 @@ export const AudioForRendering = ({ volume: volumeProp, playbackRate, src, muted
69
69
  if (disallowFallbackToHtml5Audio) {
70
70
  cancelRender(new Error(`Unknown container format ${src}, and 'disallowFallbackToHtml5Audio' was set. Failing the render.`));
71
71
  }
72
- Internals.Log.warn({ logLevel, tag: '@remotion/media' }, `Unknown container format for ${src} (Supported formats: https://www.remotion.dev/docs/mediabunny/formats), falling back to <Audio>`);
72
+ Internals.Log.warn({ logLevel, tag: '@remotion/media' }, `Unknown container format for ${src} (Supported formats: https://www.remotion.dev/docs/mediabunny/formats), falling back to <Html5Audio>`);
73
73
  setReplaceWithHtml5Audio(true);
74
74
  return;
75
75
  }
@@ -77,15 +77,18 @@ export const AudioForRendering = ({ volume: volumeProp, playbackRate, src, muted
77
77
  if (disallowFallbackToHtml5Audio) {
78
78
  cancelRender(new Error(`Cannot decode ${src}, and 'disallowFallbackToHtml5Audio' was set. Failing the render.`));
79
79
  }
80
- Internals.Log.warn({ logLevel, tag: '@remotion/media' }, `Cannot decode ${src}, falling back to <Audio>`);
80
+ Internals.Log.warn({ logLevel, tag: '@remotion/media' }, `Cannot decode ${src}, falling back to <Html5Audio>`);
81
81
  setReplaceWithHtml5Audio(true);
82
82
  return;
83
83
  }
84
+ if (result.type === 'cannot-decode-alpha') {
85
+ 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.`);
86
+ }
84
87
  if (result.type === 'network-error') {
85
88
  if (disallowFallbackToHtml5Audio) {
86
89
  cancelRender(new Error(`Cannot decode ${src}, and 'disallowFallbackToHtml5Audio' was set. Failing the render.`));
87
90
  }
88
- Internals.Log.warn({ logLevel, tag: '@remotion/media' }, `Network error fetching ${src}, falling back to <Audio>`);
91
+ Internals.Log.warn({ logLevel, tag: '@remotion/media' }, `Network error fetching ${src}, falling back to <Html5Audio>`);
89
92
  setReplaceWithHtml5Audio(true);
90
93
  return;
91
94
  }
@@ -153,8 +156,7 @@ export const AudioForRendering = ({ volume: volumeProp, playbackRate, src, muted
153
156
  replaceWithHtml5Audio,
154
157
  ]);
155
158
  if (replaceWithHtml5Audio) {
156
- // TODO: Loop and other props
157
- return (_jsx(Audio, { src: src, playbackRate: playbackRate, muted: muted, loop: loop, volume: volumeProp, delayRenderRetries: delayRenderRetries, delayRenderTimeoutInMilliseconds: delayRenderTimeoutInMilliseconds, style: style, loopVolumeCurveBehavior: loopVolumeCurveBehavior, audioStreamIndex: audioStreamIndex, useWebAudioApi: fallbackHtml5AudioProps?.useWebAudioApi, onError: fallbackHtml5AudioProps?.onError, toneFrequency: toneFrequency, acceptableTimeShiftInSeconds: fallbackHtml5AudioProps?.acceptableTimeShiftInSeconds, name: name, showInTimeline: showInTimeline }));
159
+ return (_jsx(Html5Audio, { src: src, playbackRate: playbackRate, muted: muted, loop: loop, volume: volumeProp, delayRenderRetries: delayRenderRetries, delayRenderTimeoutInMilliseconds: delayRenderTimeoutInMilliseconds, style: style, loopVolumeCurveBehavior: loopVolumeCurveBehavior, audioStreamIndex: audioStreamIndex, useWebAudioApi: fallbackHtml5AudioProps?.useWebAudioApi, onError: fallbackHtml5AudioProps?.onError, toneFrequency: toneFrequency, acceptableTimeShiftInSeconds: fallbackHtml5AudioProps?.acceptableTimeShiftInSeconds, name: name, showInTimeline: showInTimeline }));
158
160
  }
159
161
  return null;
160
162
  };
@@ -28,6 +28,7 @@ const extractAudioInternal = async ({ src, timeInSeconds: unloopedTimeInSeconds,
28
28
  playbackRate,
29
29
  trimBefore,
30
30
  fps,
31
+ ifNoMediaDuration: 'fail',
31
32
  });
32
33
  if (timeInSeconds === null) {
33
34
  return { data: null, durationInSeconds: mediaDurationInSeconds };
@@ -0,0 +1 @@
1
+ export declare const canBrowserUseWebGl2: () => boolean;
@@ -0,0 +1,13 @@
1
+ let browserCanUseWebGl2 = null;
2
+ const browserCanUseWebGl2Uncached = () => {
3
+ const canvas = new OffscreenCanvas(1, 1);
4
+ const context = canvas.getContext('webgl2');
5
+ return context !== null;
6
+ };
7
+ export const canBrowserUseWebGl2 = () => {
8
+ if (browserCanUseWebGl2 !== null) {
9
+ return browserCanUseWebGl2;
10
+ }
11
+ browserCanUseWebGl2 = browserCanUseWebGl2Uncached();
12
+ return browserCanUseWebGl2;
13
+ };
package/dist/caches.d.ts CHANGED
@@ -7,7 +7,7 @@ export declare const keyframeManager: {
7
7
  videoSampleSink: import("mediabunny").VideoSampleSink;
8
8
  src: string;
9
9
  logLevel: LogLevel;
10
- }) => Promise<import("./video-extraction/keyframe-bank").KeyframeBank | null>;
10
+ }) => Promise<import("./video-extraction/keyframe-bank").KeyframeBank | "has-alpha" | null>;
11
11
  getCacheStats: () => Promise<{
12
12
  count: number;
13
13
  totalSize: number;
package/dist/caches.js CHANGED
@@ -28,9 +28,9 @@ const getUncachedMaxCacheSize = (logLevel) => {
28
28
  if (window.remotion_initialMemoryAvailable !== undefined &&
29
29
  window.remotion_initialMemoryAvailable !== null) {
30
30
  const value = window.remotion_initialMemoryAvailable / 2;
31
- if (value < 240 * 1024 * 1024) {
32
- Internals.Log.verbose({ logLevel, tag: '@remotion/media' }, `Using cache size set based on minimum value of 240MB (which is more than half of the available system memory!)`);
33
- return 240 * 1024 * 1024;
31
+ if (value < 500 * 1024 * 1024) {
32
+ Internals.Log.verbose({ logLevel, tag: '@remotion/media' }, `Using cache size set based on minimum value of 500MB (which is more than half of the available system memory!)`);
33
+ return 500 * 1024 * 1024;
34
34
  }
35
35
  if (value > 20000 * 1024 * 1024) {
36
36
  Internals.Log.verbose({ logLevel, tag: '@remotion/media' }, `Using cache size set based on maximum value of 20GB (which is less than half of the available system memory)`);