@remotion/media 4.0.382 → 4.0.384
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/audio/audio-for-preview.js +35 -35
- package/dist/audio/audio-for-rendering.js +8 -4
- package/dist/audio-extraction/extract-audio.js +71 -58
- package/dist/audio-iterator-manager.d.ts +1 -1
- package/dist/audio-iterator-manager.js +3 -2
- package/dist/esm/index.mjs +165 -126
- package/dist/extract-frame-and-audio.js +1 -1
- package/dist/is-type-of-error.d.ts +7 -0
- package/dist/is-type-of-error.js +20 -0
- package/dist/media-player.d.ts +3 -2
- package/dist/media-player.js +28 -4
- package/dist/video/video-for-preview.js +33 -33
- package/dist/video/video-for-rendering.js +4 -2
- package/dist/video-extraction/get-frames-since-keyframe.js +1 -1
- package/package.json +4 -4
|
@@ -10,6 +10,8 @@ const AudioForPreviewAssertedShowing = ({ src, playbackRate, logLevel, muted, vo
|
|
|
10
10
|
const videoConfig = useUnsafeVideoConfig();
|
|
11
11
|
const frame = useCurrentFrame();
|
|
12
12
|
const mediaPlayerRef = useRef(null);
|
|
13
|
+
const initialTrimBeforeRef = useRef(trimBefore);
|
|
14
|
+
const initialTrimAfterRef = useRef(trimAfter);
|
|
13
15
|
const [mediaPlayerReady, setMediaPlayerReady] = useState(false);
|
|
14
16
|
const [shouldFallbackToNativeAudio, setShouldFallbackToNativeAudio] = useState(false);
|
|
15
17
|
const [playing] = Timeline.usePlayingState();
|
|
@@ -62,11 +64,11 @@ const AudioForPreviewAssertedShowing = ({ src, playbackRate, logLevel, muted, vo
|
|
|
62
64
|
trimAfter,
|
|
63
65
|
trimBefore,
|
|
64
66
|
});
|
|
65
|
-
const
|
|
66
|
-
if (!
|
|
67
|
+
const bufferingContext = useContext(Internals.BufferingContextReact);
|
|
68
|
+
if (!bufferingContext) {
|
|
67
69
|
throw new Error('useMediaPlayback must be used inside a <BufferingContext>');
|
|
68
70
|
}
|
|
69
|
-
const isPlayerBuffering = Internals.useIsPlayerBuffering(
|
|
71
|
+
const isPlayerBuffering = Internals.useIsPlayerBuffering(bufferingContext);
|
|
70
72
|
useEffect(() => {
|
|
71
73
|
if (!sharedAudioContext)
|
|
72
74
|
return;
|
|
@@ -78,8 +80,8 @@ const AudioForPreviewAssertedShowing = ({ src, playbackRate, logLevel, muted, vo
|
|
|
78
80
|
logLevel,
|
|
79
81
|
sharedAudioContext: sharedAudioContext.audioContext,
|
|
80
82
|
loop,
|
|
81
|
-
trimAfter,
|
|
82
|
-
trimBefore,
|
|
83
|
+
trimAfter: initialTrimAfterRef.current,
|
|
84
|
+
trimBefore: initialTrimBeforeRef.current,
|
|
83
85
|
fps: videoConfig.fps,
|
|
84
86
|
canvas: null,
|
|
85
87
|
playbackRate,
|
|
@@ -159,8 +161,6 @@ const AudioForPreviewAssertedShowing = ({ src, playbackRate, logLevel, muted, vo
|
|
|
159
161
|
sharedAudioContext,
|
|
160
162
|
currentTimeRef,
|
|
161
163
|
loop,
|
|
162
|
-
trimAfter,
|
|
163
|
-
trimBefore,
|
|
164
164
|
playbackRate,
|
|
165
165
|
videoConfig.fps,
|
|
166
166
|
audioStreamIndex,
|
|
@@ -170,7 +170,7 @@ const AudioForPreviewAssertedShowing = ({ src, playbackRate, logLevel, muted, vo
|
|
|
170
170
|
isPostmounting,
|
|
171
171
|
globalPlaybackRate,
|
|
172
172
|
]);
|
|
173
|
-
|
|
173
|
+
useLayoutEffect(() => {
|
|
174
174
|
const audioPlayer = mediaPlayerRef.current;
|
|
175
175
|
if (!audioPlayer)
|
|
176
176
|
return;
|
|
@@ -182,16 +182,21 @@ const AudioForPreviewAssertedShowing = ({ src, playbackRate, logLevel, muted, vo
|
|
|
182
182
|
}
|
|
183
183
|
}, [isPlayerBuffering, logLevel, playing]);
|
|
184
184
|
useLayoutEffect(() => {
|
|
185
|
-
const
|
|
186
|
-
if (!
|
|
185
|
+
const mediaPlayer = mediaPlayerRef.current;
|
|
186
|
+
if (!mediaPlayer || !mediaPlayerReady) {
|
|
187
187
|
return;
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
188
|
+
}
|
|
189
|
+
mediaPlayer.setTrimBefore(trimBefore, currentTimeRef.current);
|
|
190
|
+
}, [trimBefore, mediaPlayerReady]);
|
|
191
|
+
useLayoutEffect(() => {
|
|
192
|
+
const mediaPlayer = mediaPlayerRef.current;
|
|
193
|
+
if (!mediaPlayer || !mediaPlayerReady) {
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
mediaPlayer.setTrimAfter(trimAfter, currentTimeRef.current);
|
|
197
|
+
}, [trimAfter, mediaPlayerReady]);
|
|
193
198
|
const effectiveMuted = muted || mediaMuted || userPreferredVolume <= 0;
|
|
194
|
-
|
|
199
|
+
useLayoutEffect(() => {
|
|
195
200
|
const audioPlayer = mediaPlayerRef.current;
|
|
196
201
|
if (!audioPlayer || !mediaPlayerReady)
|
|
197
202
|
return;
|
|
@@ -211,55 +216,50 @@ const AudioForPreviewAssertedShowing = ({ src, playbackRate, logLevel, muted, vo
|
|
|
211
216
|
}
|
|
212
217
|
audioPlayer.setPlaybackRate(playbackRate);
|
|
213
218
|
}, [playbackRate, mediaPlayerReady]);
|
|
214
|
-
|
|
219
|
+
useLayoutEffect(() => {
|
|
215
220
|
const audioPlayer = mediaPlayerRef.current;
|
|
216
221
|
if (!audioPlayer || !mediaPlayerReady) {
|
|
217
222
|
return;
|
|
218
223
|
}
|
|
219
224
|
audioPlayer.setGlobalPlaybackRate(globalPlaybackRate);
|
|
220
225
|
}, [globalPlaybackRate, mediaPlayerReady]);
|
|
221
|
-
|
|
226
|
+
useLayoutEffect(() => {
|
|
222
227
|
const audioPlayer = mediaPlayerRef.current;
|
|
223
228
|
if (!audioPlayer || !mediaPlayerReady) {
|
|
224
229
|
return;
|
|
225
230
|
}
|
|
226
231
|
audioPlayer.setFps(videoConfig.fps);
|
|
227
232
|
}, [videoConfig.fps, mediaPlayerReady]);
|
|
228
|
-
|
|
229
|
-
const mediaPlayer = mediaPlayerRef.current;
|
|
230
|
-
if (!mediaPlayer || !mediaPlayerReady) {
|
|
231
|
-
return;
|
|
232
|
-
}
|
|
233
|
-
mediaPlayer.setTrimBefore(trimBefore);
|
|
234
|
-
}, [trimBefore, mediaPlayerReady]);
|
|
235
|
-
useEffect(() => {
|
|
236
|
-
const mediaPlayer = mediaPlayerRef.current;
|
|
237
|
-
if (!mediaPlayer || !mediaPlayerReady) {
|
|
238
|
-
return;
|
|
239
|
-
}
|
|
240
|
-
mediaPlayer.setTrimAfter(trimAfter);
|
|
241
|
-
}, [trimAfter, mediaPlayerReady]);
|
|
242
|
-
useEffect(() => {
|
|
233
|
+
useLayoutEffect(() => {
|
|
243
234
|
const mediaPlayer = mediaPlayerRef.current;
|
|
244
235
|
if (!mediaPlayer || !mediaPlayerReady) {
|
|
245
236
|
return;
|
|
246
237
|
}
|
|
247
238
|
mediaPlayer.setLoop(loop);
|
|
248
239
|
}, [loop, mediaPlayerReady]);
|
|
249
|
-
|
|
240
|
+
useLayoutEffect(() => {
|
|
250
241
|
const mediaPlayer = mediaPlayerRef.current;
|
|
251
242
|
if (!mediaPlayer || !mediaPlayerReady) {
|
|
252
243
|
return;
|
|
253
244
|
}
|
|
254
245
|
mediaPlayer.setIsPremounting(isPremounting);
|
|
255
246
|
}, [isPremounting, mediaPlayerReady]);
|
|
256
|
-
|
|
247
|
+
useLayoutEffect(() => {
|
|
257
248
|
const mediaPlayer = mediaPlayerRef.current;
|
|
258
249
|
if (!mediaPlayer || !mediaPlayerReady) {
|
|
259
250
|
return;
|
|
260
251
|
}
|
|
261
252
|
mediaPlayer.setIsPostmounting(isPostmounting);
|
|
262
253
|
}, [isPostmounting, mediaPlayerReady]);
|
|
254
|
+
useLayoutEffect(() => {
|
|
255
|
+
const audioPlayer = mediaPlayerRef.current;
|
|
256
|
+
if (!audioPlayer || !mediaPlayerReady)
|
|
257
|
+
return;
|
|
258
|
+
audioPlayer.seekTo(currentTime).catch(() => {
|
|
259
|
+
// Might be disposed
|
|
260
|
+
});
|
|
261
|
+
Internals.Log.trace({ logLevel, tag: '@remotion/media' }, `[AudioForPreview] Updating target time to ${currentTime.toFixed(3)}s`);
|
|
262
|
+
}, [currentTime, logLevel, mediaPlayerReady]);
|
|
263
263
|
if (shouldFallbackToNativeAudio && !disallowFallbackToHtml5Audio) {
|
|
264
264
|
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, crossOrigin: fallbackHtml5AudioProps?.crossOrigin, ...fallbackHtml5AudioProps }));
|
|
265
265
|
}
|
|
@@ -6,7 +6,7 @@ import { applyVolume } from '../convert-audiodata/apply-volume';
|
|
|
6
6
|
import { TARGET_SAMPLE_RATE } from '../convert-audiodata/resample-audiodata';
|
|
7
7
|
import { frameForVolumeProp } from '../looped-frame';
|
|
8
8
|
import { extractFrameViaBroadcastChannel } from '../video-extraction/extract-frame-via-broadcast-channel';
|
|
9
|
-
export const AudioForRendering = ({ volume: volumeProp, playbackRate, src, muted, loopVolumeCurveBehavior, delayRenderRetries, delayRenderTimeoutInMilliseconds, logLevel, loop, fallbackHtml5AudioProps, audioStreamIndex, showInTimeline, style, name, disallowFallbackToHtml5Audio, toneFrequency, trimAfter, trimBefore, }) => {
|
|
9
|
+
export const AudioForRendering = ({ volume: volumeProp, playbackRate, src, muted, loopVolumeCurveBehavior, delayRenderRetries, delayRenderTimeoutInMilliseconds, logLevel = window.remotion_logLevel ?? 'info', loop, fallbackHtml5AudioProps, audioStreamIndex, showInTimeline, style, name, disallowFallbackToHtml5Audio, toneFrequency, trimAfter, trimBefore, }) => {
|
|
10
10
|
const frame = useCurrentFrame();
|
|
11
11
|
const absoluteFrame = Internals.useTimelinePosition();
|
|
12
12
|
const videoConfig = Internals.useUnsafeVideoConfig();
|
|
@@ -25,13 +25,14 @@ export const AudioForRendering = ({ volume: volumeProp, playbackRate, src, muted
|
|
|
25
25
|
const sequenceContext = useContext(Internals.SequenceContext);
|
|
26
26
|
// Generate a string that's as unique as possible for this asset
|
|
27
27
|
// but at the same time the same on all threads
|
|
28
|
-
const id = useMemo(() => `media-
|
|
28
|
+
const id = useMemo(() => `media-audio-${random(src)}-${sequenceContext?.cumulatedFrom}-${sequenceContext?.relativeFrom}-${sequenceContext?.durationInFrames}`, [
|
|
29
29
|
src,
|
|
30
30
|
sequenceContext?.cumulatedFrom,
|
|
31
31
|
sequenceContext?.relativeFrom,
|
|
32
32
|
sequenceContext?.durationInFrames,
|
|
33
33
|
]);
|
|
34
34
|
const maxCacheSize = useMaxMediaCacheSize(logLevel ?? window.remotion_logLevel);
|
|
35
|
+
const audioEnabled = Internals.useAudioEnabled();
|
|
35
36
|
useLayoutEffect(() => {
|
|
36
37
|
const timestamp = frame / fps;
|
|
37
38
|
const durationInSeconds = 1 / fps;
|
|
@@ -43,7 +44,7 @@ export const AudioForRendering = ({ volume: volumeProp, playbackRate, src, muted
|
|
|
43
44
|
timeoutInMilliseconds: delayRenderTimeoutInMilliseconds ?? undefined,
|
|
44
45
|
});
|
|
45
46
|
const shouldRenderAudio = (() => {
|
|
46
|
-
if (!
|
|
47
|
+
if (!audioEnabled) {
|
|
47
48
|
return false;
|
|
48
49
|
}
|
|
49
50
|
if (muted) {
|
|
@@ -124,7 +125,9 @@ export const AudioForRendering = ({ volume: volumeProp, playbackRate, src, muted
|
|
|
124
125
|
registerRenderAsset({
|
|
125
126
|
type: 'inline-audio',
|
|
126
127
|
id,
|
|
127
|
-
audio:
|
|
128
|
+
audio: environment.isClientSideRendering
|
|
129
|
+
? audio.data
|
|
130
|
+
: Array.from(audio.data),
|
|
128
131
|
frame: absoluteFrame,
|
|
129
132
|
timestamp: audio.timestamp,
|
|
130
133
|
duration: (audio.numberOfFrames / TARGET_SAMPLE_RATE) * 1000000,
|
|
@@ -167,6 +170,7 @@ export const AudioForRendering = ({ volume: volumeProp, playbackRate, src, muted
|
|
|
167
170
|
trimBefore,
|
|
168
171
|
replaceWithHtml5Audio,
|
|
169
172
|
maxCacheSize,
|
|
173
|
+
audioEnabled,
|
|
170
174
|
]);
|
|
171
175
|
if (replaceWithHtml5Audio) {
|
|
172
176
|
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 }));
|
|
@@ -4,6 +4,7 @@ import { convertAudioData, fixFloatingPoint, } from '../convert-audiodata/conver
|
|
|
4
4
|
import { TARGET_NUMBER_OF_CHANNELS, TARGET_SAMPLE_RATE, } from '../convert-audiodata/resample-audiodata';
|
|
5
5
|
import { getSink } from '../get-sink';
|
|
6
6
|
import { getTimeInSeconds } from '../get-time-in-seconds';
|
|
7
|
+
import { isNetworkError, isUnsupportedConfigurationError, } from '../is-type-of-error';
|
|
7
8
|
const extractAudioInternal = async ({ src, timeInSeconds: unloopedTimeInSeconds, durationInSeconds: durationNotYetApplyingPlaybackRate, logLevel, loop, playbackRate, audioStreamIndex, trimBefore, trimAfter, fps, maxCacheSize, }) => {
|
|
8
9
|
const { getAudio, actualMatroskaTimestamps, isMatroska, getDuration } = await getSink(src, logLevel);
|
|
9
10
|
let mediaDurationInSeconds = null;
|
|
@@ -47,70 +48,82 @@ const extractAudioInternal = async ({ src, timeInSeconds: unloopedTimeInSeconds,
|
|
|
47
48
|
maxCacheSize,
|
|
48
49
|
});
|
|
49
50
|
const durationInSeconds = durationNotYetApplyingPlaybackRate * playbackRate;
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
sample.
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
51
|
+
try {
|
|
52
|
+
const samples = await sampleIterator.getSamples(timeInSeconds, durationInSeconds);
|
|
53
|
+
audioManager.logOpenFrames();
|
|
54
|
+
const audioDataArray = [];
|
|
55
|
+
for (let i = 0; i < samples.length; i++) {
|
|
56
|
+
const sample = samples[i];
|
|
57
|
+
// Less than 1 sample would be included - we did not need it after all!
|
|
58
|
+
if (Math.abs(sample.timestamp - (timeInSeconds + durationInSeconds)) *
|
|
59
|
+
sample.sampleRate <
|
|
60
|
+
1) {
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
// Less than 1 sample would be included - we did not need it after all!
|
|
64
|
+
if (sample.timestamp + sample.duration <= timeInSeconds) {
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
const isFirstSample = i === 0;
|
|
68
|
+
const isLastSample = i === samples.length - 1;
|
|
69
|
+
const audioDataRaw = sample.toAudioData();
|
|
70
|
+
// amount of samples to shave from start and end
|
|
71
|
+
let trimStartInSeconds = 0;
|
|
72
|
+
let trimEndInSeconds = 0;
|
|
73
|
+
let leadingSilence = null;
|
|
74
|
+
if (isFirstSample) {
|
|
75
|
+
trimStartInSeconds = fixFloatingPoint(timeInSeconds - sample.timestamp);
|
|
76
|
+
if (trimStartInSeconds < 0) {
|
|
77
|
+
const silenceFrames = Math.ceil(fixFloatingPoint(-trimStartInSeconds * TARGET_SAMPLE_RATE));
|
|
78
|
+
leadingSilence = {
|
|
79
|
+
data: new Int16Array(silenceFrames * TARGET_NUMBER_OF_CHANNELS),
|
|
80
|
+
numberOfFrames: silenceFrames,
|
|
81
|
+
timestamp: timeInSeconds * 1000000,
|
|
82
|
+
durationInMicroSeconds: (silenceFrames / TARGET_SAMPLE_RATE) * 1000000,
|
|
83
|
+
};
|
|
84
|
+
trimStartInSeconds = 0;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (isLastSample) {
|
|
88
|
+
trimEndInSeconds =
|
|
89
|
+
// clamp to 0 in case the audio ends early
|
|
90
|
+
Math.max(0, sample.timestamp +
|
|
91
|
+
sample.duration -
|
|
92
|
+
(timeInSeconds + durationInSeconds));
|
|
83
93
|
}
|
|
94
|
+
const audioData = convertAudioData({
|
|
95
|
+
audioData: audioDataRaw,
|
|
96
|
+
trimStartInSeconds,
|
|
97
|
+
trimEndInSeconds,
|
|
98
|
+
playbackRate,
|
|
99
|
+
audioDataTimestamp: sample.timestamp,
|
|
100
|
+
isLast: isLastSample,
|
|
101
|
+
});
|
|
102
|
+
audioDataRaw.close();
|
|
103
|
+
if (audioData.numberOfFrames === 0) {
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
if (leadingSilence) {
|
|
107
|
+
audioDataArray.push(leadingSilence);
|
|
108
|
+
}
|
|
109
|
+
audioDataArray.push(audioData);
|
|
84
110
|
}
|
|
85
|
-
if (
|
|
86
|
-
|
|
87
|
-
// clamp to 0 in case the audio ends early
|
|
88
|
-
Math.max(0, sample.timestamp +
|
|
89
|
-
sample.duration -
|
|
90
|
-
(timeInSeconds + durationInSeconds));
|
|
111
|
+
if (audioDataArray.length === 0) {
|
|
112
|
+
return { data: null, durationInSeconds: mediaDurationInSeconds };
|
|
91
113
|
}
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
});
|
|
100
|
-
audioDataRaw.close();
|
|
101
|
-
if (audioData.numberOfFrames === 0) {
|
|
102
|
-
continue;
|
|
114
|
+
const combined = combineAudioDataAndClosePrevious(audioDataArray);
|
|
115
|
+
return { data: combined, durationInSeconds: mediaDurationInSeconds };
|
|
116
|
+
}
|
|
117
|
+
catch (err) {
|
|
118
|
+
const error = err;
|
|
119
|
+
if (isNetworkError(error)) {
|
|
120
|
+
return 'network-error';
|
|
103
121
|
}
|
|
104
|
-
if (
|
|
105
|
-
|
|
122
|
+
if (isUnsupportedConfigurationError(error)) {
|
|
123
|
+
return 'cannot-decode';
|
|
106
124
|
}
|
|
107
|
-
|
|
108
|
-
}
|
|
109
|
-
if (audioDataArray.length === 0) {
|
|
110
|
-
return { data: null, durationInSeconds: mediaDurationInSeconds };
|
|
125
|
+
throw err;
|
|
111
126
|
}
|
|
112
|
-
const combined = combineAudioDataAndClosePrevious(audioDataArray);
|
|
113
|
-
return { data: combined, durationInSeconds: mediaDurationInSeconds };
|
|
114
127
|
};
|
|
115
128
|
let queue = Promise.resolve(undefined);
|
|
116
129
|
export const extractAudio = (params) => {
|
|
@@ -46,7 +46,7 @@ export declare const audioIteratorManager: ({ audioTrack, delayPlaybackHandleIfN
|
|
|
46
46
|
moveQueuedChunksToPauseQueue: () => void;
|
|
47
47
|
getNumberOfChunksAfterResuming: () => number;
|
|
48
48
|
} | null;
|
|
49
|
-
|
|
49
|
+
destroyIterator: () => void;
|
|
50
50
|
seek: ({ newTime, nonce, fps, playbackRate, getIsPlaying, scheduleAudioNode, bufferState, }: {
|
|
51
51
|
newTime: number;
|
|
52
52
|
nonce: Nonce;
|
|
@@ -102,7 +102,8 @@ export const audioIteratorManager = ({ audioTrack, delayPlaybackHandleIfNotPremo
|
|
|
102
102
|
});
|
|
103
103
|
return;
|
|
104
104
|
}
|
|
105
|
-
const
|
|
105
|
+
const queuedPeriod = audioBufferIterator.getQueuedPeriod();
|
|
106
|
+
const currentTimeIsAlreadyQueued = isAlreadyQueued(newTime, queuedPeriod);
|
|
106
107
|
if (!currentTimeIsAlreadyQueued) {
|
|
107
108
|
const audioSatisfyResult = await audioBufferIterator.tryToSatisfySeek(newTime, null, (buffer) => {
|
|
108
109
|
if (!nonce.isStale()) {
|
|
@@ -192,7 +193,7 @@ export const audioIteratorManager = ({ audioTrack, delayPlaybackHandleIfNotPremo
|
|
|
192
193
|
resumeScheduledAudioChunks,
|
|
193
194
|
pausePlayback,
|
|
194
195
|
getAudioBufferIterator: () => audioBufferIterator,
|
|
195
|
-
|
|
196
|
+
destroyIterator: () => {
|
|
196
197
|
audioBufferIterator?.destroy();
|
|
197
198
|
audioBufferIterator = null;
|
|
198
199
|
},
|
package/dist/esm/index.mjs
CHANGED
|
@@ -377,7 +377,8 @@ var audioIteratorManager = ({
|
|
|
377
377
|
});
|
|
378
378
|
return;
|
|
379
379
|
}
|
|
380
|
-
const
|
|
380
|
+
const queuedPeriod = audioBufferIterator.getQueuedPeriod();
|
|
381
|
+
const currentTimeIsAlreadyQueued = isAlreadyQueued(newTime, queuedPeriod);
|
|
381
382
|
if (!currentTimeIsAlreadyQueued) {
|
|
382
383
|
const audioSatisfyResult = await audioBufferIterator.tryToSatisfySeek(newTime, null, (buffer) => {
|
|
383
384
|
if (!nonce.isStale()) {
|
|
@@ -465,7 +466,7 @@ var audioIteratorManager = ({
|
|
|
465
466
|
resumeScheduledAudioChunks,
|
|
466
467
|
pausePlayback,
|
|
467
468
|
getAudioBufferIterator: () => audioBufferIterator,
|
|
468
|
-
|
|
469
|
+
destroyIterator: () => {
|
|
469
470
|
audioBufferIterator?.destroy();
|
|
470
471
|
audioBufferIterator = null;
|
|
471
472
|
},
|
|
@@ -538,13 +539,16 @@ var drawPreviewOverlay = ({
|
|
|
538
539
|
}
|
|
539
540
|
};
|
|
540
541
|
|
|
541
|
-
// src/is-
|
|
542
|
+
// src/is-type-of-error.ts
|
|
542
543
|
function isNetworkError(error) {
|
|
543
544
|
if (error.message.includes("Failed to fetch") || error.message.includes("Load failed") || error.message.includes("NetworkError when attempting to fetch resource")) {
|
|
544
545
|
return true;
|
|
545
546
|
}
|
|
546
547
|
return false;
|
|
547
548
|
}
|
|
549
|
+
function isUnsupportedConfigurationError(error) {
|
|
550
|
+
return error.message.includes("Unsupported configuration");
|
|
551
|
+
}
|
|
548
552
|
|
|
549
553
|
// src/nonce-manager.ts
|
|
550
554
|
var makeNonceManager = () => {
|
|
@@ -1048,11 +1052,33 @@ class MediaPlayer {
|
|
|
1048
1052
|
}
|
|
1049
1053
|
this.audioIteratorManager.setVolume(volume);
|
|
1050
1054
|
}
|
|
1051
|
-
|
|
1055
|
+
updateAfterTrimChange(unloopedTimeInSeconds) {
|
|
1056
|
+
if (!this.audioIteratorManager && !this.videoIteratorManager) {
|
|
1057
|
+
return;
|
|
1058
|
+
}
|
|
1059
|
+
const newMediaTime = getTimeInSeconds({
|
|
1060
|
+
unloopedTimeInSeconds,
|
|
1061
|
+
playbackRate: this.playbackRate,
|
|
1062
|
+
loop: this.loop,
|
|
1063
|
+
trimBefore: this.trimBefore,
|
|
1064
|
+
trimAfter: this.trimAfter,
|
|
1065
|
+
mediaDurationInSeconds: this.totalDuration ?? null,
|
|
1066
|
+
fps: this.fps,
|
|
1067
|
+
ifNoMediaDuration: "infinity",
|
|
1068
|
+
src: this.src
|
|
1069
|
+
});
|
|
1070
|
+
if (newMediaTime !== null) {
|
|
1071
|
+
this.setPlaybackTime(newMediaTime, this.playbackRate * this.globalPlaybackRate);
|
|
1072
|
+
}
|
|
1073
|
+
this.audioIteratorManager?.destroyIterator();
|
|
1074
|
+
}
|
|
1075
|
+
setTrimBefore(trimBefore, unloopedTimeInSeconds) {
|
|
1052
1076
|
this.trimBefore = trimBefore;
|
|
1077
|
+
this.updateAfterTrimChange(unloopedTimeInSeconds);
|
|
1053
1078
|
}
|
|
1054
|
-
setTrimAfter(trimAfter) {
|
|
1079
|
+
setTrimAfter(trimAfter, unloopedTimeInSeconds) {
|
|
1055
1080
|
this.trimAfter = trimAfter;
|
|
1081
|
+
this.updateAfterTrimChange(unloopedTimeInSeconds);
|
|
1056
1082
|
}
|
|
1057
1083
|
setDebugOverlay(debugOverlay) {
|
|
1058
1084
|
this.debugOverlay = debugOverlay;
|
|
@@ -1102,7 +1128,7 @@ class MediaPlayer {
|
|
|
1102
1128
|
}
|
|
1103
1129
|
this.nonceManager.createAsyncOperation();
|
|
1104
1130
|
this.videoIteratorManager?.destroy();
|
|
1105
|
-
this.audioIteratorManager?.
|
|
1131
|
+
this.audioIteratorManager?.destroyIterator();
|
|
1106
1132
|
this.input.dispose();
|
|
1107
1133
|
}
|
|
1108
1134
|
scheduleAudioNode = (node, mediaTimestamp) => {
|
|
@@ -1344,6 +1370,8 @@ var AudioForPreviewAssertedShowing = ({
|
|
|
1344
1370
|
const videoConfig = useUnsafeVideoConfig();
|
|
1345
1371
|
const frame = useCurrentFrame2();
|
|
1346
1372
|
const mediaPlayerRef = useRef(null);
|
|
1373
|
+
const initialTrimBeforeRef = useRef(trimBefore);
|
|
1374
|
+
const initialTrimAfterRef = useRef(trimAfter);
|
|
1347
1375
|
const [mediaPlayerReady, setMediaPlayerReady] = useState2(false);
|
|
1348
1376
|
const [shouldFallbackToNativeAudio, setShouldFallbackToNativeAudio] = useState2(false);
|
|
1349
1377
|
const [playing] = Timeline.usePlayingState();
|
|
@@ -1396,11 +1424,11 @@ var AudioForPreviewAssertedShowing = ({
|
|
|
1396
1424
|
trimAfter,
|
|
1397
1425
|
trimBefore
|
|
1398
1426
|
});
|
|
1399
|
-
const
|
|
1400
|
-
if (!
|
|
1427
|
+
const bufferingContext = useContext2(Internals6.BufferingContextReact);
|
|
1428
|
+
if (!bufferingContext) {
|
|
1401
1429
|
throw new Error("useMediaPlayback must be used inside a <BufferingContext>");
|
|
1402
1430
|
}
|
|
1403
|
-
const isPlayerBuffering = Internals6.useIsPlayerBuffering(
|
|
1431
|
+
const isPlayerBuffering = Internals6.useIsPlayerBuffering(bufferingContext);
|
|
1404
1432
|
useEffect2(() => {
|
|
1405
1433
|
if (!sharedAudioContext)
|
|
1406
1434
|
return;
|
|
@@ -1412,8 +1440,8 @@ var AudioForPreviewAssertedShowing = ({
|
|
|
1412
1440
|
logLevel,
|
|
1413
1441
|
sharedAudioContext: sharedAudioContext.audioContext,
|
|
1414
1442
|
loop,
|
|
1415
|
-
trimAfter,
|
|
1416
|
-
trimBefore,
|
|
1443
|
+
trimAfter: initialTrimAfterRef.current,
|
|
1444
|
+
trimBefore: initialTrimBeforeRef.current,
|
|
1417
1445
|
fps: videoConfig.fps,
|
|
1418
1446
|
canvas: null,
|
|
1419
1447
|
playbackRate,
|
|
@@ -1489,8 +1517,6 @@ var AudioForPreviewAssertedShowing = ({
|
|
|
1489
1517
|
sharedAudioContext,
|
|
1490
1518
|
currentTimeRef,
|
|
1491
1519
|
loop,
|
|
1492
|
-
trimAfter,
|
|
1493
|
-
trimBefore,
|
|
1494
1520
|
playbackRate,
|
|
1495
1521
|
videoConfig.fps,
|
|
1496
1522
|
audioStreamIndex,
|
|
@@ -1500,7 +1526,7 @@ var AudioForPreviewAssertedShowing = ({
|
|
|
1500
1526
|
isPostmounting,
|
|
1501
1527
|
globalPlaybackRate
|
|
1502
1528
|
]);
|
|
1503
|
-
|
|
1529
|
+
useLayoutEffect(() => {
|
|
1504
1530
|
const audioPlayer = mediaPlayerRef.current;
|
|
1505
1531
|
if (!audioPlayer)
|
|
1506
1532
|
return;
|
|
@@ -1511,14 +1537,21 @@ var AudioForPreviewAssertedShowing = ({
|
|
|
1511
1537
|
}
|
|
1512
1538
|
}, [isPlayerBuffering, logLevel, playing]);
|
|
1513
1539
|
useLayoutEffect(() => {
|
|
1514
|
-
const
|
|
1515
|
-
if (!
|
|
1540
|
+
const mediaPlayer = mediaPlayerRef.current;
|
|
1541
|
+
if (!mediaPlayer || !mediaPlayerReady) {
|
|
1516
1542
|
return;
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
}, [
|
|
1543
|
+
}
|
|
1544
|
+
mediaPlayer.setTrimBefore(trimBefore, currentTimeRef.current);
|
|
1545
|
+
}, [trimBefore, mediaPlayerReady]);
|
|
1546
|
+
useLayoutEffect(() => {
|
|
1547
|
+
const mediaPlayer = mediaPlayerRef.current;
|
|
1548
|
+
if (!mediaPlayer || !mediaPlayerReady) {
|
|
1549
|
+
return;
|
|
1550
|
+
}
|
|
1551
|
+
mediaPlayer.setTrimAfter(trimAfter, currentTimeRef.current);
|
|
1552
|
+
}, [trimAfter, mediaPlayerReady]);
|
|
1520
1553
|
const effectiveMuted = muted || mediaMuted || userPreferredVolume <= 0;
|
|
1521
|
-
|
|
1554
|
+
useLayoutEffect(() => {
|
|
1522
1555
|
const audioPlayer = mediaPlayerRef.current;
|
|
1523
1556
|
if (!audioPlayer || !mediaPlayerReady)
|
|
1524
1557
|
return;
|
|
@@ -1538,55 +1571,48 @@ var AudioForPreviewAssertedShowing = ({
|
|
|
1538
1571
|
}
|
|
1539
1572
|
audioPlayer.setPlaybackRate(playbackRate);
|
|
1540
1573
|
}, [playbackRate, mediaPlayerReady]);
|
|
1541
|
-
|
|
1574
|
+
useLayoutEffect(() => {
|
|
1542
1575
|
const audioPlayer = mediaPlayerRef.current;
|
|
1543
1576
|
if (!audioPlayer || !mediaPlayerReady) {
|
|
1544
1577
|
return;
|
|
1545
1578
|
}
|
|
1546
1579
|
audioPlayer.setGlobalPlaybackRate(globalPlaybackRate);
|
|
1547
1580
|
}, [globalPlaybackRate, mediaPlayerReady]);
|
|
1548
|
-
|
|
1581
|
+
useLayoutEffect(() => {
|
|
1549
1582
|
const audioPlayer = mediaPlayerRef.current;
|
|
1550
1583
|
if (!audioPlayer || !mediaPlayerReady) {
|
|
1551
1584
|
return;
|
|
1552
1585
|
}
|
|
1553
1586
|
audioPlayer.setFps(videoConfig.fps);
|
|
1554
1587
|
}, [videoConfig.fps, mediaPlayerReady]);
|
|
1555
|
-
|
|
1556
|
-
const mediaPlayer = mediaPlayerRef.current;
|
|
1557
|
-
if (!mediaPlayer || !mediaPlayerReady) {
|
|
1558
|
-
return;
|
|
1559
|
-
}
|
|
1560
|
-
mediaPlayer.setTrimBefore(trimBefore);
|
|
1561
|
-
}, [trimBefore, mediaPlayerReady]);
|
|
1562
|
-
useEffect2(() => {
|
|
1563
|
-
const mediaPlayer = mediaPlayerRef.current;
|
|
1564
|
-
if (!mediaPlayer || !mediaPlayerReady) {
|
|
1565
|
-
return;
|
|
1566
|
-
}
|
|
1567
|
-
mediaPlayer.setTrimAfter(trimAfter);
|
|
1568
|
-
}, [trimAfter, mediaPlayerReady]);
|
|
1569
|
-
useEffect2(() => {
|
|
1588
|
+
useLayoutEffect(() => {
|
|
1570
1589
|
const mediaPlayer = mediaPlayerRef.current;
|
|
1571
1590
|
if (!mediaPlayer || !mediaPlayerReady) {
|
|
1572
1591
|
return;
|
|
1573
1592
|
}
|
|
1574
1593
|
mediaPlayer.setLoop(loop);
|
|
1575
1594
|
}, [loop, mediaPlayerReady]);
|
|
1576
|
-
|
|
1595
|
+
useLayoutEffect(() => {
|
|
1577
1596
|
const mediaPlayer = mediaPlayerRef.current;
|
|
1578
1597
|
if (!mediaPlayer || !mediaPlayerReady) {
|
|
1579
1598
|
return;
|
|
1580
1599
|
}
|
|
1581
1600
|
mediaPlayer.setIsPremounting(isPremounting);
|
|
1582
1601
|
}, [isPremounting, mediaPlayerReady]);
|
|
1583
|
-
|
|
1602
|
+
useLayoutEffect(() => {
|
|
1584
1603
|
const mediaPlayer = mediaPlayerRef.current;
|
|
1585
1604
|
if (!mediaPlayer || !mediaPlayerReady) {
|
|
1586
1605
|
return;
|
|
1587
1606
|
}
|
|
1588
1607
|
mediaPlayer.setIsPostmounting(isPostmounting);
|
|
1589
1608
|
}, [isPostmounting, mediaPlayerReady]);
|
|
1609
|
+
useLayoutEffect(() => {
|
|
1610
|
+
const audioPlayer = mediaPlayerRef.current;
|
|
1611
|
+
if (!audioPlayer || !mediaPlayerReady)
|
|
1612
|
+
return;
|
|
1613
|
+
audioPlayer.seekTo(currentTime).catch(() => {});
|
|
1614
|
+
Internals6.Log.trace({ logLevel, tag: "@remotion/media" }, `[AudioForPreview] Updating target time to ${currentTime.toFixed(3)}s`);
|
|
1615
|
+
}, [currentTime, logLevel, mediaPlayerReady]);
|
|
1590
1616
|
if (shouldFallbackToNativeAudio && !disallowFallbackToHtml5Audio) {
|
|
1591
1617
|
return /* @__PURE__ */ jsx(RemotionAudio, {
|
|
1592
1618
|
src,
|
|
@@ -2902,61 +2928,72 @@ var extractAudioInternal = async ({
|
|
|
2902
2928
|
maxCacheSize
|
|
2903
2929
|
});
|
|
2904
2930
|
const durationInSeconds = durationNotYetApplyingPlaybackRate * playbackRate;
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2931
|
+
try {
|
|
2932
|
+
const samples = await sampleIterator.getSamples(timeInSeconds, durationInSeconds);
|
|
2933
|
+
audioManager.logOpenFrames();
|
|
2934
|
+
const audioDataArray = [];
|
|
2935
|
+
for (let i = 0;i < samples.length; i++) {
|
|
2936
|
+
const sample = samples[i];
|
|
2937
|
+
if (Math.abs(sample.timestamp - (timeInSeconds + durationInSeconds)) * sample.sampleRate < 1) {
|
|
2938
|
+
continue;
|
|
2939
|
+
}
|
|
2940
|
+
if (sample.timestamp + sample.duration <= timeInSeconds) {
|
|
2941
|
+
continue;
|
|
2942
|
+
}
|
|
2943
|
+
const isFirstSample = i === 0;
|
|
2944
|
+
const isLastSample = i === samples.length - 1;
|
|
2945
|
+
const audioDataRaw = sample.toAudioData();
|
|
2946
|
+
let trimStartInSeconds = 0;
|
|
2947
|
+
let trimEndInSeconds = 0;
|
|
2948
|
+
let leadingSilence = null;
|
|
2949
|
+
if (isFirstSample) {
|
|
2950
|
+
trimStartInSeconds = fixFloatingPoint2(timeInSeconds - sample.timestamp);
|
|
2951
|
+
if (trimStartInSeconds < 0) {
|
|
2952
|
+
const silenceFrames = Math.ceil(fixFloatingPoint2(-trimStartInSeconds * TARGET_SAMPLE_RATE));
|
|
2953
|
+
leadingSilence = {
|
|
2954
|
+
data: new Int16Array(silenceFrames * TARGET_NUMBER_OF_CHANNELS),
|
|
2955
|
+
numberOfFrames: silenceFrames,
|
|
2956
|
+
timestamp: timeInSeconds * 1e6,
|
|
2957
|
+
durationInMicroSeconds: silenceFrames / TARGET_SAMPLE_RATE * 1e6
|
|
2958
|
+
};
|
|
2959
|
+
trimStartInSeconds = 0;
|
|
2960
|
+
}
|
|
2961
|
+
}
|
|
2962
|
+
if (isLastSample) {
|
|
2963
|
+
trimEndInSeconds = Math.max(0, sample.timestamp + sample.duration - (timeInSeconds + durationInSeconds));
|
|
2964
|
+
}
|
|
2965
|
+
const audioData = convertAudioData({
|
|
2966
|
+
audioData: audioDataRaw,
|
|
2967
|
+
trimStartInSeconds,
|
|
2968
|
+
trimEndInSeconds,
|
|
2969
|
+
playbackRate,
|
|
2970
|
+
audioDataTimestamp: sample.timestamp,
|
|
2971
|
+
isLast: isLastSample
|
|
2972
|
+
});
|
|
2973
|
+
audioDataRaw.close();
|
|
2974
|
+
if (audioData.numberOfFrames === 0) {
|
|
2975
|
+
continue;
|
|
2976
|
+
}
|
|
2977
|
+
if (leadingSilence) {
|
|
2978
|
+
audioDataArray.push(leadingSilence);
|
|
2933
2979
|
}
|
|
2980
|
+
audioDataArray.push(audioData);
|
|
2934
2981
|
}
|
|
2935
|
-
if (
|
|
2936
|
-
|
|
2982
|
+
if (audioDataArray.length === 0) {
|
|
2983
|
+
return { data: null, durationInSeconds: mediaDurationInSeconds };
|
|
2937
2984
|
}
|
|
2938
|
-
const
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
isLast: isLastSample
|
|
2945
|
-
});
|
|
2946
|
-
audioDataRaw.close();
|
|
2947
|
-
if (audioData.numberOfFrames === 0) {
|
|
2948
|
-
continue;
|
|
2985
|
+
const combined = combineAudioDataAndClosePrevious(audioDataArray);
|
|
2986
|
+
return { data: combined, durationInSeconds: mediaDurationInSeconds };
|
|
2987
|
+
} catch (err) {
|
|
2988
|
+
const error = err;
|
|
2989
|
+
if (isNetworkError(error)) {
|
|
2990
|
+
return "network-error";
|
|
2949
2991
|
}
|
|
2950
|
-
if (
|
|
2951
|
-
|
|
2992
|
+
if (isUnsupportedConfigurationError(error)) {
|
|
2993
|
+
return "cannot-decode";
|
|
2952
2994
|
}
|
|
2953
|
-
|
|
2954
|
-
}
|
|
2955
|
-
if (audioDataArray.length === 0) {
|
|
2956
|
-
return { data: null, durationInSeconds: mediaDurationInSeconds };
|
|
2995
|
+
throw err;
|
|
2957
2996
|
}
|
|
2958
|
-
const combined = combineAudioDataAndClosePrevious(audioDataArray);
|
|
2959
|
-
return { data: combined, durationInSeconds: mediaDurationInSeconds };
|
|
2960
2997
|
};
|
|
2961
2998
|
var queue = Promise.resolve(undefined);
|
|
2962
2999
|
var extractAudio = (params) => {
|
|
@@ -3394,7 +3431,7 @@ var AudioForRendering = ({
|
|
|
3394
3431
|
loopVolumeCurveBehavior,
|
|
3395
3432
|
delayRenderRetries,
|
|
3396
3433
|
delayRenderTimeoutInMilliseconds,
|
|
3397
|
-
logLevel,
|
|
3434
|
+
logLevel = window.remotion_logLevel ?? "info",
|
|
3398
3435
|
loop,
|
|
3399
3436
|
fallbackHtml5AudioProps,
|
|
3400
3437
|
audioStreamIndex,
|
|
@@ -3422,13 +3459,14 @@ var AudioForRendering = ({
|
|
|
3422
3459
|
const { delayRender, continueRender } = useDelayRender();
|
|
3423
3460
|
const [replaceWithHtml5Audio, setReplaceWithHtml5Audio] = useState3(false);
|
|
3424
3461
|
const sequenceContext = useContext3(Internals13.SequenceContext);
|
|
3425
|
-
const id = useMemo3(() => `media-
|
|
3462
|
+
const id = useMemo3(() => `media-audio-${random(src)}-${sequenceContext?.cumulatedFrom}-${sequenceContext?.relativeFrom}-${sequenceContext?.durationInFrames}`, [
|
|
3426
3463
|
src,
|
|
3427
3464
|
sequenceContext?.cumulatedFrom,
|
|
3428
3465
|
sequenceContext?.relativeFrom,
|
|
3429
3466
|
sequenceContext?.durationInFrames
|
|
3430
3467
|
]);
|
|
3431
3468
|
const maxCacheSize = useMaxMediaCacheSize(logLevel ?? window.remotion_logLevel);
|
|
3469
|
+
const audioEnabled = Internals13.useAudioEnabled();
|
|
3432
3470
|
useLayoutEffect2(() => {
|
|
3433
3471
|
const timestamp = frame / fps;
|
|
3434
3472
|
const durationInSeconds = 1 / fps;
|
|
@@ -3440,7 +3478,7 @@ var AudioForRendering = ({
|
|
|
3440
3478
|
timeoutInMilliseconds: delayRenderTimeoutInMilliseconds ?? undefined
|
|
3441
3479
|
});
|
|
3442
3480
|
const shouldRenderAudio = (() => {
|
|
3443
|
-
if (!
|
|
3481
|
+
if (!audioEnabled) {
|
|
3444
3482
|
return false;
|
|
3445
3483
|
}
|
|
3446
3484
|
if (muted) {
|
|
@@ -3520,7 +3558,7 @@ var AudioForRendering = ({
|
|
|
3520
3558
|
registerRenderAsset({
|
|
3521
3559
|
type: "inline-audio",
|
|
3522
3560
|
id,
|
|
3523
|
-
audio: Array.from(audio.data),
|
|
3561
|
+
audio: environment.isClientSideRendering ? audio.data : Array.from(audio.data),
|
|
3524
3562
|
frame: absoluteFrame,
|
|
3525
3563
|
timestamp: audio.timestamp,
|
|
3526
3564
|
duration: audio.numberOfFrames / TARGET_SAMPLE_RATE * 1e6,
|
|
@@ -3561,7 +3599,8 @@ var AudioForRendering = ({
|
|
|
3561
3599
|
trimAfter,
|
|
3562
3600
|
trimBefore,
|
|
3563
3601
|
replaceWithHtml5Audio,
|
|
3564
|
-
maxCacheSize
|
|
3602
|
+
maxCacheSize,
|
|
3603
|
+
audioEnabled
|
|
3565
3604
|
]);
|
|
3566
3605
|
if (replaceWithHtml5Audio) {
|
|
3567
3606
|
return /* @__PURE__ */ jsx2(Html5Audio, {
|
|
@@ -3668,6 +3707,8 @@ var VideoForPreviewAssertedShowing = ({
|
|
|
3668
3707
|
const videoConfig = useUnsafeVideoConfig2();
|
|
3669
3708
|
const frame = useCurrentFrame4();
|
|
3670
3709
|
const mediaPlayerRef = useRef2(null);
|
|
3710
|
+
const initialTrimBeforeRef = useRef2(trimBefore);
|
|
3711
|
+
const initialTrimAfterRef = useRef2(trimAfter);
|
|
3671
3712
|
const [mediaPlayerReady, setMediaPlayerReady] = useState4(false);
|
|
3672
3713
|
const [shouldFallbackToNativeVideo, setShouldFallbackToNativeVideo] = useState4(false);
|
|
3673
3714
|
const [playing] = Timeline2.usePlayingState();
|
|
@@ -3738,8 +3779,8 @@ var VideoForPreviewAssertedShowing = ({
|
|
|
3738
3779
|
logLevel,
|
|
3739
3780
|
sharedAudioContext: sharedAudioContext.audioContext,
|
|
3740
3781
|
loop,
|
|
3741
|
-
trimAfter,
|
|
3742
|
-
trimBefore,
|
|
3782
|
+
trimAfter: initialTrimAfterRef.current,
|
|
3783
|
+
trimBefore: initialTrimBeforeRef.current,
|
|
3743
3784
|
fps: videoConfig.fps,
|
|
3744
3785
|
playbackRate,
|
|
3745
3786
|
audioStreamIndex,
|
|
@@ -3812,8 +3853,6 @@ var VideoForPreviewAssertedShowing = ({
|
|
|
3812
3853
|
logLevel,
|
|
3813
3854
|
sharedAudioContext,
|
|
3814
3855
|
loop,
|
|
3815
|
-
trimAfter,
|
|
3816
|
-
trimBefore,
|
|
3817
3856
|
videoConfig.fps,
|
|
3818
3857
|
playbackRate,
|
|
3819
3858
|
disallowFallbackToOffthreadVideo,
|
|
@@ -3837,97 +3876,97 @@ var VideoForPreviewAssertedShowing = ({
|
|
|
3837
3876
|
mediaPlayer.pause();
|
|
3838
3877
|
}
|
|
3839
3878
|
}, [isPlayerBuffering, playing, logLevel, mediaPlayerReady]);
|
|
3840
|
-
|
|
3879
|
+
useEffect3(() => {
|
|
3841
3880
|
const mediaPlayer = mediaPlayerRef.current;
|
|
3842
|
-
if (!mediaPlayer || !mediaPlayerReady)
|
|
3881
|
+
if (!mediaPlayer || !mediaPlayerReady) {
|
|
3843
3882
|
return;
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
}, [
|
|
3847
|
-
const effectiveMuted = isSequenceHidden || muted || mediaMuted || userPreferredVolume <= 0;
|
|
3883
|
+
}
|
|
3884
|
+
mediaPlayer.setTrimBefore(trimBefore, currentTimeRef.current);
|
|
3885
|
+
}, [trimBefore, mediaPlayerReady]);
|
|
3848
3886
|
useEffect3(() => {
|
|
3887
|
+
const mediaPlayer = mediaPlayerRef.current;
|
|
3888
|
+
if (!mediaPlayer || !mediaPlayerReady) {
|
|
3889
|
+
return;
|
|
3890
|
+
}
|
|
3891
|
+
mediaPlayer.setTrimAfter(trimAfter, currentTimeRef.current);
|
|
3892
|
+
}, [trimAfter, mediaPlayerReady]);
|
|
3893
|
+
const effectiveMuted = isSequenceHidden || muted || mediaMuted || userPreferredVolume <= 0;
|
|
3894
|
+
useLayoutEffect3(() => {
|
|
3849
3895
|
const mediaPlayer = mediaPlayerRef.current;
|
|
3850
3896
|
if (!mediaPlayer || !mediaPlayerReady)
|
|
3851
3897
|
return;
|
|
3852
3898
|
mediaPlayer.setMuted(effectiveMuted);
|
|
3853
3899
|
}, [effectiveMuted, mediaPlayerReady]);
|
|
3854
|
-
|
|
3900
|
+
useLayoutEffect3(() => {
|
|
3855
3901
|
const mediaPlayer = mediaPlayerRef.current;
|
|
3856
3902
|
if (!mediaPlayer || !mediaPlayerReady) {
|
|
3857
3903
|
return;
|
|
3858
3904
|
}
|
|
3859
3905
|
mediaPlayer.setVolume(userPreferredVolume);
|
|
3860
3906
|
}, [userPreferredVolume, mediaPlayerReady]);
|
|
3861
|
-
|
|
3907
|
+
useLayoutEffect3(() => {
|
|
3862
3908
|
const mediaPlayer = mediaPlayerRef.current;
|
|
3863
3909
|
if (!mediaPlayer || !mediaPlayerReady) {
|
|
3864
3910
|
return;
|
|
3865
3911
|
}
|
|
3866
3912
|
mediaPlayer.setDebugOverlay(debugOverlay);
|
|
3867
3913
|
}, [debugOverlay, mediaPlayerReady]);
|
|
3868
|
-
|
|
3914
|
+
useLayoutEffect3(() => {
|
|
3869
3915
|
const mediaPlayer = mediaPlayerRef.current;
|
|
3870
3916
|
if (!mediaPlayer || !mediaPlayerReady) {
|
|
3871
3917
|
return;
|
|
3872
3918
|
}
|
|
3873
3919
|
mediaPlayer.setPlaybackRate(playbackRate);
|
|
3874
3920
|
}, [playbackRate, mediaPlayerReady]);
|
|
3875
|
-
|
|
3921
|
+
useLayoutEffect3(() => {
|
|
3876
3922
|
const mediaPlayer = mediaPlayerRef.current;
|
|
3877
3923
|
if (!mediaPlayer || !mediaPlayerReady) {
|
|
3878
3924
|
return;
|
|
3879
3925
|
}
|
|
3880
3926
|
mediaPlayer.setGlobalPlaybackRate(globalPlaybackRate);
|
|
3881
3927
|
}, [globalPlaybackRate, mediaPlayerReady]);
|
|
3882
|
-
|
|
3928
|
+
useLayoutEffect3(() => {
|
|
3883
3929
|
const mediaPlayer = mediaPlayerRef.current;
|
|
3884
3930
|
if (!mediaPlayer || !mediaPlayerReady) {
|
|
3885
3931
|
return;
|
|
3886
3932
|
}
|
|
3887
3933
|
mediaPlayer.setLoop(loop);
|
|
3888
3934
|
}, [loop, mediaPlayerReady]);
|
|
3889
|
-
|
|
3935
|
+
useLayoutEffect3(() => {
|
|
3890
3936
|
const mediaPlayer = mediaPlayerRef.current;
|
|
3891
3937
|
if (!mediaPlayer || !mediaPlayerReady) {
|
|
3892
3938
|
return;
|
|
3893
3939
|
}
|
|
3894
3940
|
mediaPlayer.setIsPremounting(isPremounting);
|
|
3895
3941
|
}, [isPremounting, mediaPlayerReady]);
|
|
3896
|
-
|
|
3942
|
+
useLayoutEffect3(() => {
|
|
3897
3943
|
const mediaPlayer = mediaPlayerRef.current;
|
|
3898
3944
|
if (!mediaPlayer || !mediaPlayerReady) {
|
|
3899
3945
|
return;
|
|
3900
3946
|
}
|
|
3901
3947
|
mediaPlayer.setIsPostmounting(isPostmounting);
|
|
3902
3948
|
}, [isPostmounting, mediaPlayerReady]);
|
|
3903
|
-
|
|
3949
|
+
useLayoutEffect3(() => {
|
|
3904
3950
|
const mediaPlayer = mediaPlayerRef.current;
|
|
3905
3951
|
if (!mediaPlayer || !mediaPlayerReady) {
|
|
3906
3952
|
return;
|
|
3907
3953
|
}
|
|
3908
3954
|
mediaPlayer.setFps(videoConfig.fps);
|
|
3909
3955
|
}, [videoConfig.fps, mediaPlayerReady]);
|
|
3910
|
-
|
|
3956
|
+
useLayoutEffect3(() => {
|
|
3911
3957
|
const mediaPlayer = mediaPlayerRef.current;
|
|
3912
3958
|
if (!mediaPlayer || !mediaPlayerReady) {
|
|
3913
3959
|
return;
|
|
3914
3960
|
}
|
|
3915
3961
|
mediaPlayer.setVideoFrameCallback(onVideoFrame ?? null);
|
|
3916
3962
|
}, [onVideoFrame, mediaPlayerReady]);
|
|
3917
|
-
|
|
3918
|
-
const mediaPlayer = mediaPlayerRef.current;
|
|
3919
|
-
if (!mediaPlayer || !mediaPlayerReady) {
|
|
3920
|
-
return;
|
|
3921
|
-
}
|
|
3922
|
-
mediaPlayer.setTrimBefore(trimBefore);
|
|
3923
|
-
}, [trimBefore, mediaPlayerReady]);
|
|
3924
|
-
useEffect3(() => {
|
|
3963
|
+
useLayoutEffect3(() => {
|
|
3925
3964
|
const mediaPlayer = mediaPlayerRef.current;
|
|
3926
|
-
if (!mediaPlayer || !mediaPlayerReady)
|
|
3965
|
+
if (!mediaPlayer || !mediaPlayerReady)
|
|
3927
3966
|
return;
|
|
3928
|
-
}
|
|
3929
|
-
|
|
3930
|
-
}, [
|
|
3967
|
+
mediaPlayer.seekTo(currentTime).catch(() => {});
|
|
3968
|
+
Internals15.Log.trace({ logLevel, tag: "@remotion/media" }, `[VideoForPreview] Updating target time to ${currentTime.toFixed(3)}s`);
|
|
3969
|
+
}, [currentTime, logLevel, mediaPlayerReady]);
|
|
3931
3970
|
const actualStyle = useMemo4(() => {
|
|
3932
3971
|
return {
|
|
3933
3972
|
...style,
|
|
@@ -4115,7 +4154,7 @@ var VideoForRendering = ({
|
|
|
4115
4154
|
cancelRender3(new Error(`Cannot decode ${src}, and 'disallowFallbackToOffthreadVideo' was set. Failing the render.`));
|
|
4116
4155
|
}
|
|
4117
4156
|
if (window.remotion_isMainTab) {
|
|
4118
|
-
Internals16.Log.
|
|
4157
|
+
Internals16.Log.warn({ logLevel, tag: "@remotion/media" }, `Cannot decode ${src}, falling back to <OffthreadVideo>`);
|
|
4119
4158
|
}
|
|
4120
4159
|
setReplaceWithOffthreadVideo({
|
|
4121
4160
|
durationInSeconds: result.durationInSeconds
|
|
@@ -4189,7 +4228,7 @@ var VideoForRendering = ({
|
|
|
4189
4228
|
registerRenderAsset({
|
|
4190
4229
|
type: "inline-audio",
|
|
4191
4230
|
id,
|
|
4192
|
-
audio: Array.from(audio.data),
|
|
4231
|
+
audio: environment.isClientSideRendering ? audio.data : Array.from(audio.data),
|
|
4193
4232
|
frame: absoluteFrame,
|
|
4194
4233
|
timestamp: audio.timestamp,
|
|
4195
4234
|
duration: audio.numberOfFrames / TARGET_SAMPLE_RATE * 1e6,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { extractAudio } from './audio-extraction/extract-audio';
|
|
2
|
-
import { isNetworkError } from './is-
|
|
2
|
+
import { isNetworkError } from './is-type-of-error';
|
|
3
3
|
import { extractFrame } from './video-extraction/extract-frame';
|
|
4
4
|
import { rotateFrame } from './video-extraction/rotate-frame';
|
|
5
5
|
export const extractFrameAndAudio = async ({ src, timeInSeconds, logLevel, durationInSeconds, playbackRate, includeAudio, includeVideo, loop, audioStreamIndex, trimAfter, trimBefore, fps, maxCacheSize, }) => {
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility to check if error is network error
|
|
3
|
+
* @param error
|
|
4
|
+
* @returns
|
|
5
|
+
*/
|
|
6
|
+
export function isNetworkError(error) {
|
|
7
|
+
if (
|
|
8
|
+
// Chrome
|
|
9
|
+
error.message.includes('Failed to fetch') ||
|
|
10
|
+
// Safari
|
|
11
|
+
error.message.includes('Load failed') ||
|
|
12
|
+
// Firefox
|
|
13
|
+
error.message.includes('NetworkError when attempting to fetch resource')) {
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
export function isUnsupportedConfigurationError(error) {
|
|
19
|
+
return error.message.includes('Unsupported configuration');
|
|
20
|
+
}
|
package/dist/media-player.d.ts
CHANGED
|
@@ -70,8 +70,9 @@ export declare class MediaPlayer {
|
|
|
70
70
|
pause(): void;
|
|
71
71
|
setMuted(muted: boolean): void;
|
|
72
72
|
setVolume(volume: number): void;
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
private updateAfterTrimChange;
|
|
74
|
+
setTrimBefore(trimBefore: number | undefined, unloopedTimeInSeconds: number): void;
|
|
75
|
+
setTrimAfter(trimAfter: number | undefined, unloopedTimeInSeconds: number): void;
|
|
75
76
|
setDebugOverlay(debugOverlay: boolean): void;
|
|
76
77
|
private updateAfterPlaybackRateChange;
|
|
77
78
|
setPlaybackRate(rate: number): void;
|
package/dist/media-player.js
CHANGED
|
@@ -4,7 +4,7 @@ import { audioIteratorManager, } from './audio-iterator-manager';
|
|
|
4
4
|
import { calculatePlaybackTime } from './calculate-playbacktime';
|
|
5
5
|
import { drawPreviewOverlay } from './debug-overlay/preview-overlay';
|
|
6
6
|
import { getTimeInSeconds } from './get-time-in-seconds';
|
|
7
|
-
import { isNetworkError } from './is-
|
|
7
|
+
import { isNetworkError } from './is-type-of-error';
|
|
8
8
|
import { makeNonceManager } from './nonce-manager';
|
|
9
9
|
import { videoIteratorManager } from './video-iterator-manager';
|
|
10
10
|
export class MediaPlayer {
|
|
@@ -284,11 +284,35 @@ export class MediaPlayer {
|
|
|
284
284
|
}
|
|
285
285
|
this.audioIteratorManager.setVolume(volume);
|
|
286
286
|
}
|
|
287
|
-
|
|
287
|
+
updateAfterTrimChange(unloopedTimeInSeconds) {
|
|
288
|
+
if (!this.audioIteratorManager && !this.videoIteratorManager) {
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
const newMediaTime = getTimeInSeconds({
|
|
292
|
+
unloopedTimeInSeconds,
|
|
293
|
+
playbackRate: this.playbackRate,
|
|
294
|
+
loop: this.loop,
|
|
295
|
+
trimBefore: this.trimBefore,
|
|
296
|
+
trimAfter: this.trimAfter,
|
|
297
|
+
mediaDurationInSeconds: this.totalDuration ?? null,
|
|
298
|
+
fps: this.fps,
|
|
299
|
+
ifNoMediaDuration: 'infinity',
|
|
300
|
+
src: this.src,
|
|
301
|
+
});
|
|
302
|
+
if (newMediaTime !== null) {
|
|
303
|
+
this.setPlaybackTime(newMediaTime, this.playbackRate * this.globalPlaybackRate);
|
|
304
|
+
}
|
|
305
|
+
// audio iterator will be re-created on next play/seek
|
|
306
|
+
// video iterator doesn't need to be re-created
|
|
307
|
+
this.audioIteratorManager?.destroyIterator();
|
|
308
|
+
}
|
|
309
|
+
setTrimBefore(trimBefore, unloopedTimeInSeconds) {
|
|
288
310
|
this.trimBefore = trimBefore;
|
|
311
|
+
this.updateAfterTrimChange(unloopedTimeInSeconds);
|
|
289
312
|
}
|
|
290
|
-
setTrimAfter(trimAfter) {
|
|
313
|
+
setTrimAfter(trimAfter, unloopedTimeInSeconds) {
|
|
291
314
|
this.trimAfter = trimAfter;
|
|
315
|
+
this.updateAfterTrimChange(unloopedTimeInSeconds);
|
|
292
316
|
}
|
|
293
317
|
setDebugOverlay(debugOverlay) {
|
|
294
318
|
this.debugOverlay = debugOverlay;
|
|
@@ -345,7 +369,7 @@ export class MediaPlayer {
|
|
|
345
369
|
// Mark all async operations as stale
|
|
346
370
|
this.nonceManager.createAsyncOperation();
|
|
347
371
|
this.videoIteratorManager?.destroy();
|
|
348
|
-
this.audioIteratorManager?.
|
|
372
|
+
this.audioIteratorManager?.destroyIterator();
|
|
349
373
|
this.input.dispose();
|
|
350
374
|
}
|
|
351
375
|
getPlaybackTime() {
|
|
@@ -12,6 +12,8 @@ const VideoForPreviewAssertedShowing = ({ src: unpreloadedSrc, style, playbackRa
|
|
|
12
12
|
const videoConfig = useUnsafeVideoConfig();
|
|
13
13
|
const frame = useCurrentFrame();
|
|
14
14
|
const mediaPlayerRef = useRef(null);
|
|
15
|
+
const initialTrimBeforeRef = useRef(trimBefore);
|
|
16
|
+
const initialTrimAfterRef = useRef(trimAfter);
|
|
15
17
|
const [mediaPlayerReady, setMediaPlayerReady] = useState(false);
|
|
16
18
|
const [shouldFallbackToNativeVideo, setShouldFallbackToNativeVideo] = useState(false);
|
|
17
19
|
const [playing] = Timeline.usePlayingState();
|
|
@@ -82,8 +84,8 @@ const VideoForPreviewAssertedShowing = ({ src: unpreloadedSrc, style, playbackRa
|
|
|
82
84
|
logLevel,
|
|
83
85
|
sharedAudioContext: sharedAudioContext.audioContext,
|
|
84
86
|
loop,
|
|
85
|
-
trimAfter,
|
|
86
|
-
trimBefore,
|
|
87
|
+
trimAfter: initialTrimAfterRef.current,
|
|
88
|
+
trimBefore: initialTrimBeforeRef.current,
|
|
87
89
|
fps: videoConfig.fps,
|
|
88
90
|
playbackRate,
|
|
89
91
|
audioStreamIndex,
|
|
@@ -160,8 +162,6 @@ const VideoForPreviewAssertedShowing = ({ src: unpreloadedSrc, style, playbackRa
|
|
|
160
162
|
logLevel,
|
|
161
163
|
sharedAudioContext,
|
|
162
164
|
loop,
|
|
163
|
-
trimAfter,
|
|
164
|
-
trimBefore,
|
|
165
165
|
videoConfig.fps,
|
|
166
166
|
playbackRate,
|
|
167
167
|
disallowFallbackToOffthreadVideo,
|
|
@@ -188,99 +188,99 @@ const VideoForPreviewAssertedShowing = ({ src: unpreloadedSrc, style, playbackRa
|
|
|
188
188
|
mediaPlayer.pause();
|
|
189
189
|
}
|
|
190
190
|
}, [isPlayerBuffering, playing, logLevel, mediaPlayerReady]);
|
|
191
|
-
|
|
191
|
+
useEffect(() => {
|
|
192
192
|
const mediaPlayer = mediaPlayerRef.current;
|
|
193
|
-
if (!mediaPlayer || !mediaPlayerReady)
|
|
193
|
+
if (!mediaPlayer || !mediaPlayerReady) {
|
|
194
194
|
return;
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
Internals.Log.trace({ logLevel, tag: '@remotion/media' }, `[VideoForPreview] Updating target time to ${currentTime.toFixed(3)}s`);
|
|
199
|
-
}, [currentTime, logLevel, mediaPlayerReady]);
|
|
200
|
-
const effectiveMuted = isSequenceHidden || muted || mediaMuted || userPreferredVolume <= 0;
|
|
195
|
+
}
|
|
196
|
+
mediaPlayer.setTrimBefore(trimBefore, currentTimeRef.current);
|
|
197
|
+
}, [trimBefore, mediaPlayerReady]);
|
|
201
198
|
useEffect(() => {
|
|
199
|
+
const mediaPlayer = mediaPlayerRef.current;
|
|
200
|
+
if (!mediaPlayer || !mediaPlayerReady) {
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
mediaPlayer.setTrimAfter(trimAfter, currentTimeRef.current);
|
|
204
|
+
}, [trimAfter, mediaPlayerReady]);
|
|
205
|
+
const effectiveMuted = isSequenceHidden || muted || mediaMuted || userPreferredVolume <= 0;
|
|
206
|
+
useLayoutEffect(() => {
|
|
202
207
|
const mediaPlayer = mediaPlayerRef.current;
|
|
203
208
|
if (!mediaPlayer || !mediaPlayerReady)
|
|
204
209
|
return;
|
|
205
210
|
mediaPlayer.setMuted(effectiveMuted);
|
|
206
211
|
}, [effectiveMuted, mediaPlayerReady]);
|
|
207
|
-
|
|
212
|
+
useLayoutEffect(() => {
|
|
208
213
|
const mediaPlayer = mediaPlayerRef.current;
|
|
209
214
|
if (!mediaPlayer || !mediaPlayerReady) {
|
|
210
215
|
return;
|
|
211
216
|
}
|
|
212
217
|
mediaPlayer.setVolume(userPreferredVolume);
|
|
213
218
|
}, [userPreferredVolume, mediaPlayerReady]);
|
|
214
|
-
|
|
219
|
+
useLayoutEffect(() => {
|
|
215
220
|
const mediaPlayer = mediaPlayerRef.current;
|
|
216
221
|
if (!mediaPlayer || !mediaPlayerReady) {
|
|
217
222
|
return;
|
|
218
223
|
}
|
|
219
224
|
mediaPlayer.setDebugOverlay(debugOverlay);
|
|
220
225
|
}, [debugOverlay, mediaPlayerReady]);
|
|
221
|
-
|
|
226
|
+
useLayoutEffect(() => {
|
|
222
227
|
const mediaPlayer = mediaPlayerRef.current;
|
|
223
228
|
if (!mediaPlayer || !mediaPlayerReady) {
|
|
224
229
|
return;
|
|
225
230
|
}
|
|
226
231
|
mediaPlayer.setPlaybackRate(playbackRate);
|
|
227
232
|
}, [playbackRate, mediaPlayerReady]);
|
|
228
|
-
|
|
233
|
+
useLayoutEffect(() => {
|
|
229
234
|
const mediaPlayer = mediaPlayerRef.current;
|
|
230
235
|
if (!mediaPlayer || !mediaPlayerReady) {
|
|
231
236
|
return;
|
|
232
237
|
}
|
|
233
238
|
mediaPlayer.setGlobalPlaybackRate(globalPlaybackRate);
|
|
234
239
|
}, [globalPlaybackRate, mediaPlayerReady]);
|
|
235
|
-
|
|
240
|
+
useLayoutEffect(() => {
|
|
236
241
|
const mediaPlayer = mediaPlayerRef.current;
|
|
237
242
|
if (!mediaPlayer || !mediaPlayerReady) {
|
|
238
243
|
return;
|
|
239
244
|
}
|
|
240
245
|
mediaPlayer.setLoop(loop);
|
|
241
246
|
}, [loop, mediaPlayerReady]);
|
|
242
|
-
|
|
247
|
+
useLayoutEffect(() => {
|
|
243
248
|
const mediaPlayer = mediaPlayerRef.current;
|
|
244
249
|
if (!mediaPlayer || !mediaPlayerReady) {
|
|
245
250
|
return;
|
|
246
251
|
}
|
|
247
252
|
mediaPlayer.setIsPremounting(isPremounting);
|
|
248
253
|
}, [isPremounting, mediaPlayerReady]);
|
|
249
|
-
|
|
254
|
+
useLayoutEffect(() => {
|
|
250
255
|
const mediaPlayer = mediaPlayerRef.current;
|
|
251
256
|
if (!mediaPlayer || !mediaPlayerReady) {
|
|
252
257
|
return;
|
|
253
258
|
}
|
|
254
259
|
mediaPlayer.setIsPostmounting(isPostmounting);
|
|
255
260
|
}, [isPostmounting, mediaPlayerReady]);
|
|
256
|
-
|
|
261
|
+
useLayoutEffect(() => {
|
|
257
262
|
const mediaPlayer = mediaPlayerRef.current;
|
|
258
263
|
if (!mediaPlayer || !mediaPlayerReady) {
|
|
259
264
|
return;
|
|
260
265
|
}
|
|
261
266
|
mediaPlayer.setFps(videoConfig.fps);
|
|
262
267
|
}, [videoConfig.fps, mediaPlayerReady]);
|
|
263
|
-
|
|
268
|
+
useLayoutEffect(() => {
|
|
264
269
|
const mediaPlayer = mediaPlayerRef.current;
|
|
265
270
|
if (!mediaPlayer || !mediaPlayerReady) {
|
|
266
271
|
return;
|
|
267
272
|
}
|
|
268
273
|
mediaPlayer.setVideoFrameCallback(onVideoFrame ?? null);
|
|
269
274
|
}, [onVideoFrame, mediaPlayerReady]);
|
|
270
|
-
|
|
271
|
-
const mediaPlayer = mediaPlayerRef.current;
|
|
272
|
-
if (!mediaPlayer || !mediaPlayerReady) {
|
|
273
|
-
return;
|
|
274
|
-
}
|
|
275
|
-
mediaPlayer.setTrimBefore(trimBefore);
|
|
276
|
-
}, [trimBefore, mediaPlayerReady]);
|
|
277
|
-
useEffect(() => {
|
|
275
|
+
useLayoutEffect(() => {
|
|
278
276
|
const mediaPlayer = mediaPlayerRef.current;
|
|
279
|
-
if (!mediaPlayer || !mediaPlayerReady)
|
|
277
|
+
if (!mediaPlayer || !mediaPlayerReady)
|
|
280
278
|
return;
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
279
|
+
mediaPlayer.seekTo(currentTime).catch(() => {
|
|
280
|
+
// Might be disposed
|
|
281
|
+
});
|
|
282
|
+
Internals.Log.trace({ logLevel, tag: '@remotion/media' }, `[VideoForPreview] Updating target time to ${currentTime.toFixed(3)}s`);
|
|
283
|
+
}, [currentTime, logLevel, mediaPlayerReady]);
|
|
284
284
|
const actualStyle = useMemo(() => {
|
|
285
285
|
return {
|
|
286
286
|
...style,
|
|
@@ -92,7 +92,7 @@ export const VideoForRendering = ({ volume: volumeProp, playbackRate, src, muted
|
|
|
92
92
|
cancelRender(new Error(`Cannot decode ${src}, and 'disallowFallbackToOffthreadVideo' was set. Failing the render.`));
|
|
93
93
|
}
|
|
94
94
|
if (window.remotion_isMainTab) {
|
|
95
|
-
Internals.Log.
|
|
95
|
+
Internals.Log.warn({ logLevel, tag: '@remotion/media' }, `Cannot decode ${src}, falling back to <OffthreadVideo>`);
|
|
96
96
|
}
|
|
97
97
|
setReplaceWithOffthreadVideo({
|
|
98
98
|
durationInSeconds: result.durationInSeconds,
|
|
@@ -165,7 +165,9 @@ export const VideoForRendering = ({ volume: volumeProp, playbackRate, src, muted
|
|
|
165
165
|
registerRenderAsset({
|
|
166
166
|
type: 'inline-audio',
|
|
167
167
|
id,
|
|
168
|
-
audio:
|
|
168
|
+
audio: environment.isClientSideRendering
|
|
169
|
+
? audio.data
|
|
170
|
+
: Array.from(audio.data),
|
|
169
171
|
frame: absoluteFrame,
|
|
170
172
|
timestamp: audio.timestamp,
|
|
171
173
|
duration: (audio.numberOfFrames / TARGET_SAMPLE_RATE) * 1000000,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ALL_FORMATS, AudioSampleSink, EncodedPacketSink, Input, MATROSKA, UrlSource, VideoSampleSink, WEBM, } from 'mediabunny';
|
|
2
|
-
import { isNetworkError } from '../is-
|
|
2
|
+
import { isNetworkError } from '../is-type-of-error';
|
|
3
3
|
import { makeKeyframeBank } from './keyframe-bank';
|
|
4
4
|
import { rememberActualMatroskaTimestamps } from './remember-actual-matroska-timestamps';
|
|
5
5
|
const getRetryDelay = (() => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remotion/media",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.384",
|
|
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.25.
|
|
25
|
-
"remotion": "4.0.
|
|
24
|
+
"mediabunny": "1.25.8",
|
|
25
|
+
"remotion": "4.0.384"
|
|
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.384",
|
|
33
33
|
"@vitest/browser-webdriverio": "4.0.7",
|
|
34
34
|
"eslint": "9.19.0",
|
|
35
35
|
"react": "19.2.1",
|