Video

Video plays video sources with playback controls and a seekable timeline.

npm install @plocks/media

Basics

Render Video with a local source, default transport controls, and custom buttons wired to the imperative ref for play, pause, and seeking.

Loading demo…

import { useRef } from 'react'; import { Asset } from 'expo-asset'; import { Block, Button, Row } from '@plocks/ui'; import { Video } from '@plocks/media'; import type { VideoRef } from '@plocks/media'; // `source.url` takes a URL, so resolve the bundled clip to one. `Image.resolveAssetSource` // is native-only, whereas expo-asset works on web too. const SOURCE = { url: Asset.fromModule(require('../../../../assets/video/demo-clip.mp4')).uri, } as const; export function Demo() { const videoRef = useRef<VideoRef>(null); return ( <Block fullWidth> <Video ref={videoRef} source={SOURCE} /> <Row gap="sm"> <Button size="xs" variant="outline" onPress={() => videoRef.current?.play()}> Play </Button> <Button size="xs" variant="outline" onPress={() => videoRef.current?.pause()}> Pause </Button> <Button size="xs" variant="outline" onPress={() => videoRef.current?.seek(4)}> Skip to 4s </Button> </Row> </Block> ); }

Timeline Events

Pass timeline markers to fire callbacks at specific timestamps and keep a log of playback milestones without polling the player.

Loading demo…

import { useState } from 'react'; import { Asset } from 'expo-asset'; import { Block, Text } from '@plocks/ui'; import { Video } from '@plocks/media'; import type { VideoTimelineEvent } from '@plocks/media'; // `source.url` takes a URL, so resolve the bundled clip to one. `Image.resolveAssetSource` // is native-only, whereas expo-asset works on web too. const SOURCE = { url: Asset.fromModule(require('../../../../assets/video/demo-clip.mp4')).uri, } as const; export function Demo() { const [log, setLog] = useState<string[]>([]); const timeline: VideoTimelineEvent[] = [ { id: 'intro', time: 2, type: 'chapter', data: { title: 'Introduction' }, callback: () => setLog((entries) => [...entries, 'Reached introduction at 2s']), }, { id: 'main-content', time: 5, type: 'chapter', data: { title: 'Main content' }, callback: () => setLog((entries) => [...entries, 'Reached main content at 5s']), }, ]; return ( <Block fullWidth> <Video source={SOURCE} timeline={timeline} /> {log.map((entry, index) => ( <Text key={`${entry}-${index}`} size="xs"> {entry} </Text> ))} </Block> ); }

YouTube Source

Set source.youtube to a YouTube video ID or URL to stream hosted media with the same controls as native sources.

Loading demo…

import { Block } from '@plocks/ui'; import { Video } from '@plocks/media'; export function Demo() { return ( <Block fullWidth> <Video source={{ youtube: 'dQw4w9WgXcQ' }} /> </Block> ); }
Scan to open this page on your phoneplocks.dev/media/Video