Skip to main content

Different segments at different speeds

If you have a video and want to show different sections of the video at different speeds, use the following snippet.

import {OffthreadVideo, Sequence, staticFile, useCurrentFrame} from 'remotion';

const segments = [
  {
    duration: 100,
    speed: 0.5,
  },
  {
    duration: 100,
    speed: 1,
  },
  {
    duration: 200,
    speed: 2,
  },
  {
    duration: 400,
    speed: 4,
  },
];

type AccumulatedSegment = {
  start: number;
  passedVideoTime: number;
  end: number;
  speed: number;
};

export const accumulateSegments = () => {
  const accumulatedSegments: AccumulatedSegment[] = [];
  let accumulatedDuration = 0;
  let accumulatedPassedVideoTime = 0;

  for (const segment of segments) {
    const duration = segment.duration / segment.speed;
    accumulatedSegments.push({
      end: accumulatedDuration + duration,
      speed: segment.speed,
      start: accumulatedDuration,
      passedVideoTime: accumulatedPassedVideoTime,
    });

    accumulatedPassedVideoTime += segment.duration;
    accumulatedDuration += duration;
  }

  return accumulatedSegments;
};

export const SpeedSegments = () => {
  const frame = useCurrentFrame();
  const accumulated = accumulateSegments();

  const currentSegment = accumulated.find((segment) => frame > segment.start && frame <= segment.end);

  if (!currentSegment) {
    return;
  }

  return (
    <Sequence from={currentSegment.start}>
      <OffthreadVideo
        pauseWhenBuffering
        trimBefore={currentSegment.passedVideoTime}
        // Remotion will automatically add a time fragment to the end of the video URL
        // based on `trimBefore`. Opt out of this by adding one yourself.
        // https://www.remotion.dev/docs/media-fragments
        src={`${staticFile('bigbuckbunny.mp4')}#t=0,`}
        playbackRate={currentSegment.speed}
      />
    </Sequence>
  );
};

See also