V

Vuer-Viz

vuer-vizv1.2.0

Publication-Quality Visualizations

Video Display Examples

Display videos with support for multiple sources, glob patterns, interactive scrubbing, and synchronization with charts.

Type Interface

import type { BaseChartProps, SortOrder } from '../../types';

export interface VideoSource {
  src: string;
  type?: string;
}

/**
 * Event emitted when video state changes (scrubbing, playback, etc.)
 * Follows the same pattern as ChartChangeEvent for consistency.
 */
export interface VideoChangeEvent {
  /** Current frame number (0-indexed) */
  frame: number;
  /** Current time in seconds */
  time: number;
  /** Total duration in seconds */
  duration: number;
  /** Progress through video (0-1) */
  progress: number;
  /** Event type */
  type: 'hover' | 'click' | 'scrub' | 'timeupdate' | 'play' | 'pause' | 'ended';
  /** Whether video is currently playing */
  isPlaying: boolean;
  /** Native DOM event (if applicable) */
  nativeEvent?: Event | MouseEvent;
}

export interface VideoProps extends BaseChartProps {
  // Single source or pattern
  src?: string;
  sources?: VideoSource[];

  // Glob pattern support
  glob?: string;
  sortOrder?: SortOrder;

  // Video controls
  controls?: boolean;
  autoplay?: boolean;
  loop?: boolean;
  muted?: boolean;
  preload?: 'auto' | 'metadata' | 'none';

  // Appearance
  poster?: string;
  caption?: string;

  // Frame rate (for frame calculations, defaults to 30)
  fps?: number;

  // Controlled mode - set current time externally
  time?: number | null;

  // Interactive scrubbing - enable mouse hover to scrub frames
  enableScrubbing?: boolean;

  // Use custom controls instead of native browser controls
  customControls?: boolean;

  // Snapshot URL function for efficient frame preview
  snapshotUrl?: (frame: number) => string;

  // Edge padding for custom controls (equal padding from left, right, and bottom)
  edgePadding?: number;

  // Marker styling
  markerWidth?: number;
  markerHeight?: number;
  markerBottom?: number;
  markerColor?: string;

  // Unified change handler (similar to LineChart)
  onChange?: (event: VideoChangeEvent) => void;

  // Legacy callbacks (still supported)
  onPlay?: () => void;
  onPause?: () => void;
  onEnded?: () => void;
  onError?: () => void;
}

Basic Video Player

No video source
Big Buck Bunny - Sample Video
import { Video } from '@vuer-ai/vuer-viz';

export default function BasicVideoExample() {
  return (
    <Video
      src="https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"
      controls={true}
      caption="Big Buck Bunny - Sample Video"
    />
  );
}

Interactive Scrubbing & Chart Synchronization

Enable enableScrubbing to scrub through video frames by moving your mouse over the video. Use the onChange handler and time prop to synchronize with other components like LineChart.

No video source
Lissajous Curve - Drag to scrub
00.20.40.60.8100.20.40.60.81
X Position
Y Position
Time (s)Position

Drag on video or hover over chart to scrub. Play video to see cursors follow.

import { useState } from 'react';
import { Video, LineChart, VerticalMarker, SeriesTooltip } from '@vuer-ai/vuer-viz';
import timeseriesData from './data/lissajous_timeseries.json';
import videoUrl from './data/lissajous_point.mp4';

// Use the generated timeseries data synchronized with the Lissajous video
const { metadata, series: rawSeries } = timeseriesData;
const fps = metadata.fps;

const series = rawSeries.map(s => ({
  label: s.label,
  x: s.x,
  y: s.y,
  color: s.color,
}));

export default function ScrubbingExample() {
  const [time, setTime] = useState<number | null>(null);

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
      <Video
        src={videoUrl}
        width={500}
        height={200}
        fps={fps}
        controls={true}
        customControls={true}
        enableScrubbing={true}
        time={time}
        markerColor="#3b82f6"
        onChange={(e) => {
          if (e.type === 'scrub' || e.type === 'timeupdate') {
            setTime(e.time);
          }
        }}
        caption="Lissajous Curve - Drag to scrub"
      />

      <LineChart
        series={series}
        width={500}
        height={200}
        xLabel="Time (s)"
        yLabel="Position"
        onChange={(e) => e.type === 'hover' && setTime(e.x)}
      >
        <VerticalMarker x={time} color="#3b82f6" />
        <SeriesTooltip x={time} series={series} />
      </LineChart>

      <p style={{ fontSize: '13px', color: '#888' }}>
        Drag on video or hover over chart to scrub. Play video to see cursors follow.
      </p>
    </div>
  );
}

VideoChangeEvent

The onChange handler receives a VideoChangeEvent with:

interface VideoChangeEvent {
  frame: number;      // Current frame number (0-indexed)
  time: number;       // Current time in seconds
  duration: number;   // Total duration in seconds
  progress: number;   // Progress through video (0-1)
  type: 'hover' | 'click' | 'scrub' | 'timeupdate' | 'play' | 'pause' | 'ended';
  isPlaying: boolean; // Whether video is currently playing
}

Controlled Mode

Pass a time prop to control the video position externally:

const [time, setTime] = useState(0);

<Video
  src="video.mp4"
  time={time}
  onChange={(e) => setTime(e.time)}
  enableScrubbing
/>

<LineChart
  series={data}
  onChange={(e) => setTime(e.x)}
>
  <VerticalMarker x={time} />
</LineChart>

Snapshot URL Support

For large videos or ML-generated content, provide a snapshotUrl function to display frame previews efficiently:

<Video
  src="video.mp4"
  enableScrubbing
  snapshotUrl={(frame) => `/api/frames/${videoId}/${frame}.jpg`}
/>

Glob Pattern Support

The Video component supports glob patterns for loading video sequences. This requires server-side implementation to resolve file paths.

📁
Glob pattern: videos/*.mp4
(Server-side implementation required)
Example: Video sequence from pattern
import { Video } from '@vuer-ai/vuer-viz';

export default function GlobVideoExample() {
  return (
    <Video
      glob="videos/*.mp4"
      sortOrder="natural"
      caption="Example: Video sequence from pattern"
    />
  );
}

Features

  • Standard HTML5 video controls
  • Multiple source support (MP4, WebM, Ogg)
  • Glob pattern support with sort options: natural, mtime, name, asc, desc
  • Autoplay, loop, and muted options
  • Poster image support
  • Optional captions
  • Interactive frame scrubbing with enableScrubbing
  • Controlled mode with time prop for synchronization
  • Snapshot URL support for efficient frame preview
  • onChange handler following LineChart's event pattern
  • Playback event callbacks (onPlay, onPause, onEnded)
  • Error handling

← Back to all charts