Skip to content

Commit 5d0d431

Browse files
committed
@remotion/media: Add optional from and durationInFrames with hidden inner Sequence
Made-with: Cursor
1 parent 5e0e674 commit 5d0d431

File tree

4 files changed

+89
-48
lines changed

4 files changed

+89
-48
lines changed

packages/media/src/audio/audio.tsx

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from 'react';
22
import type {SequenceControls, SequenceSchema} from 'remotion';
3-
import {Internals, useRemotionEnvironment} from 'remotion';
3+
import {Internals, Sequence, useRemotionEnvironment} from 'remotion';
44
import {AudioForPreview} from './audio-for-preview';
55
import {AudioForRendering} from './audio-for-rendering';
66
import type {AudioProps} from './props';
@@ -33,7 +33,15 @@ const AudioInner: React.FC<
3333
> = (props) => {
3434
// Should only destruct `trimBefore` and `trimAfter` from props,
3535
// rest gets drilled down
36-
const {name, stack, showInTimeline, controls, ...otherProps} = props;
36+
const {
37+
name,
38+
stack,
39+
showInTimeline,
40+
controls,
41+
from,
42+
durationInFrames,
43+
...otherProps
44+
} = props;
3745
const environment = useRemotionEnvironment();
3846

3947
if (typeof props.src !== 'string') {
@@ -49,17 +57,24 @@ const AudioInner: React.FC<
4957
'Audio',
5058
);
5159

52-
if (environment.isRendering) {
53-
return <AudioForRendering {...otherProps} />;
54-
}
55-
5660
return (
57-
<AudioForPreview
58-
name={name}
59-
{...otherProps}
60-
stack={stack ?? null}
61-
controls={controls}
62-
/>
61+
<Sequence
62+
layout="none"
63+
from={from ?? 0}
64+
durationInFrames={durationInFrames ?? Infinity}
65+
showInTimeline={false}
66+
>
67+
{environment.isRendering ? (
68+
<AudioForRendering {...otherProps} />
69+
) : (
70+
<AudioForPreview
71+
name={name}
72+
{...otherProps}
73+
stack={stack ?? null}
74+
controls={controls}
75+
/>
76+
)}
77+
</Sequence>
6378
);
6479
};
6580

packages/media/src/audio/props.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,14 @@ export type FallbackHtml5AudioProps = {
1111

1212
export type AudioProps = {
1313
src: string;
14+
/**
15+
* When set, `<Audio>` applies timing via an inner `<Sequence layout="none">` that is hidden from the timeline (`showInTimeline={false}`) so the clip still appears once as media.
16+
*/
17+
from?: number;
18+
/**
19+
* When set with `from`, bounds the clip in frames. Defaults to `Infinity` like `<Sequence>`.
20+
*/
21+
durationInFrames?: number;
1422
trimBefore?: number;
1523
trimAfter?: number;
1624
volume?: VolumeProp;

packages/media/src/video/props.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,4 +75,13 @@ export type InnerVideoProps = MandatoryVideoProps &
7575

7676
export type VideoProps = MandatoryVideoProps &
7777
Partial<OuterVideoProps> &
78-
Partial<OptionalVideoProps>;
78+
Partial<OptionalVideoProps> & {
79+
/**
80+
* When set, `<Video>` applies timing via an inner `<Sequence layout="none">` that is hidden from the timeline (`showInTimeline={false}`) so the clip still appears once as media.
81+
*/
82+
from?: number;
83+
/**
84+
* Bounds the clip in frames together with `from`. Defaults to `Infinity` like `<Sequence>`.
85+
*/
86+
durationInFrames?: number;
87+
};

packages/media/src/video/video.tsx

Lines changed: 44 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from 'react';
22
import type {SequenceControls, SequenceSchema} from 'remotion';
3-
import {Internals, useRemotionEnvironment} from 'remotion';
3+
import {Internals, Sequence, useRemotionEnvironment} from 'remotion';
44
import type {InnerVideoProps, VideoProps} from './props';
55
import {VideoForPreview} from './video-for-preview';
66
import {VideoForRendering} from './video-for-rendering';
@@ -214,43 +214,52 @@ const VideoInner: React.FC<
214214
credentials,
215215
controls,
216216
objectFit,
217+
from,
218+
durationInFrames,
217219
}) => {
218220
const fallbackLogLevel = Internals.useLogLevel();
219221
return (
220-
<InnerVideo
221-
audioStreamIndex={audioStreamIndex ?? 0}
222-
className={className}
223-
delayRenderRetries={delayRenderRetries ?? null}
224-
delayRenderTimeoutInMilliseconds={
225-
delayRenderTimeoutInMilliseconds ?? null
226-
}
227-
disallowFallbackToOffthreadVideo={
228-
disallowFallbackToOffthreadVideo ?? false
229-
}
230-
fallbackOffthreadVideoProps={fallbackOffthreadVideoProps ?? {}}
231-
logLevel={logLevel ?? fallbackLogLevel}
232-
loop={loop ?? false}
233-
loopVolumeCurveBehavior={loopVolumeCurveBehavior ?? 'repeat'}
234-
muted={muted ?? false}
235-
name={name}
236-
onVideoFrame={onVideoFrame}
237-
playbackRate={playbackRate ?? 1}
238-
showInTimeline={showInTimeline ?? true}
239-
src={src}
240-
style={style ?? {}}
241-
trimAfter={trimAfter}
242-
trimBefore={trimBefore}
243-
volume={volume ?? 1}
244-
toneFrequency={toneFrequency ?? 1}
245-
stack={stack}
246-
debugOverlay={debugOverlay ?? false}
247-
debugAudioScheduling={debugAudioScheduling ?? false}
248-
headless={headless ?? false}
249-
onError={onError}
250-
credentials={credentials}
251-
controls={controls}
252-
objectFit={objectFit ?? 'contain'}
253-
/>
222+
<Sequence
223+
layout="none"
224+
from={from ?? 0}
225+
durationInFrames={durationInFrames ?? Infinity}
226+
showInTimeline={false}
227+
>
228+
<InnerVideo
229+
audioStreamIndex={audioStreamIndex ?? 0}
230+
className={className}
231+
delayRenderRetries={delayRenderRetries ?? null}
232+
delayRenderTimeoutInMilliseconds={
233+
delayRenderTimeoutInMilliseconds ?? null
234+
}
235+
disallowFallbackToOffthreadVideo={
236+
disallowFallbackToOffthreadVideo ?? false
237+
}
238+
fallbackOffthreadVideoProps={fallbackOffthreadVideoProps ?? {}}
239+
logLevel={logLevel ?? fallbackLogLevel}
240+
loop={loop ?? false}
241+
loopVolumeCurveBehavior={loopVolumeCurveBehavior ?? 'repeat'}
242+
muted={muted ?? false}
243+
name={name}
244+
onVideoFrame={onVideoFrame}
245+
playbackRate={playbackRate ?? 1}
246+
showInTimeline={showInTimeline ?? true}
247+
src={src}
248+
style={style ?? {}}
249+
trimAfter={trimAfter}
250+
trimBefore={trimBefore}
251+
volume={volume ?? 1}
252+
toneFrequency={toneFrequency ?? 1}
253+
stack={stack}
254+
debugOverlay={debugOverlay ?? false}
255+
debugAudioScheduling={debugAudioScheduling ?? false}
256+
headless={headless ?? false}
257+
onError={onError}
258+
credentials={credentials}
259+
controls={controls}
260+
objectFit={objectFit ?? 'contain'}
261+
/>
262+
</Sequence>
254263
);
255264
};
256265

0 commit comments

Comments
 (0)