Function

useTimelineMediaSync

High-level synchronization for external media surfaces.

Usage notes

The hook remains media-library agnostic: apps provide an adapter for decoding, rendering, and audio scheduling, while the hook handles active layer lookup, first-content seeking, external-clock playback, rate changes, and pause state. It builds on useTimelineMediaPlayback for external-clock playback. For packaged adapters, prefer the higher-level HTML and Mediabunny hooks first; use this hook when you are building a custom clock or preview surface.

Signature

Type Definition
useTimelineMediaSync(options: UseTimelineMediaSyncOptions<LayerName>): UseTimelineMediaSyncResult<LayerName>

Type parameters

NameConstraintDefaultDescription
LayerNamestringstringNamed media layer keys inferred from `options.layers`, such as `"visuals" | "audio"`.

Parameters

NameTypeDescription
optionsUseTimelineMediaSyncOptions<LayerName>External media adapter, readiness state, active layers, and callbacks.

Returns

Media transport state, active layer data, and synchronized playback commands.

Examples

tsx Example
import { useMemo, useRef } from 'react';
import { useTimelineMediaSync } from '@techsquidtv/canvas-timeline-react';
const previewLayerSelectors = {
visuals: { trackKind: 'visual', sourceId: 'source-1' },
audio: { trackKind: 'audio', sourceId: 'source-1' },
} as const;
export function CustomMediaPreview() {
const mediaTimeRef = useRef(0);
const layers = useMemo(() => previewLayerSelectors, []);
const mediaSync = useTimelineMediaSync({
ready: true,
layers,
adapter: {
getClockTime: () => mediaTimeRef.current,
startClock: (timelineTime, playbackRate) => {
mediaTimeRef.current = timelineTime.v / timelineTime.r;
console.info(`Start media at ${playbackRate}x`);
return true;
},
stopClock: () => {
console.info('Pause external media');
},
syncLayers: ({ activeLayers }) => {
const visualClip = activeLayers.primary.visuals?.clip;
console.info(visualClip ? `Render ${visualClip.id}` : 'No visual clip');
},
},
});
return (
<button type="button" onClick={() => void mediaSync.play()}>
{mediaSync.playing ? 'Playing' : 'Play'}
</button>
);
}