@renweilong/electron-ffmpeg-player
v0.1.4
Published
A TypeScript React video player component for Electron projects using FFmpeg decoding and Canvas rendering.
Maintainers
Readme
@renweilong/electron-ffmpeg-player
A TypeScript React video player component for Electron projects using FFmpeg decoding and Canvas rendering. This player is designed for high-performance, frame-accurate video playback up to 60fps, making it ideal for desktop applications that require precise video control.
Features
- Frame-Accurate Playback: Utilizes FFmpeg/WASM for decoding and HTML5 Canvas for rendering, ensuring precise frame control.
- 60FPS Support: Optimized pipeline for smooth 60fps video playback.
- Interactive Timeline: Supports highlight markers on the timeline with hover tooltips and seek-to-click.
- Thumbnail Rail: Optional clip-style thumbnail rail with real frame slices, hover preview, and click-to-seek.
- Source Switching With Initial Seek: Supports setting an initial position when switching sources so the player seeks before showing or autoplaying.
- Standard Controls: Play, pause, fast forward, rewind, volume control, and playback rate.
- Built-in Speed Control: Includes a speed selector in the control bar, with support for external rate synchronization.
- Keyframe Stepping: Navigate precisely between keyframes (Next / Prev I-frame).
- Theming: Built-in support for
lightanddarkthemes. - Customizable: Exposes a comprehensive ref handle (
VideoCanvasPlayerHandle) to control playback programmatically.
Installation
npm install @renweilong/electron-ffmpeg-player
# or
yarn add @renweilong/electron-ffmpeg-player
# or
pnpm add @renweilong/electron-ffmpeg-playerMake sure you have react and react-dom installed as they are peer dependencies.
Basic Usage
Import the component and its CSS file in your application:
import React, { useRef } from 'react';
import { VideoCanvasPlayer, VideoCanvasPlayerHandle } from '@renweilong/electron-ffmpeg-player';
import '@renweilong/electron-ffmpeg-player/style.css'; // Don't forget to import styles
const App = () => {
const playerRef = useRef<VideoCanvasPlayerHandle>(null);
const highlights = {
10.5: "Interesting moment",
35.2: "Action starts here",
120.0: "Conclusion"
};
return (
<div style={{ width: '800px', height: '450px' }}>
<VideoCanvasPlayer
ref={playerRef}
src="file:///path/to/your/local/video.mp4"
theme="dark"
targetFps={60}
highlight={highlights}
showThumbnailRail
initialSeekTime={12.5}
autoPlay={true}
onTimeChange={(time, duration) => {
console.log(`Current time: ${time}s / ${duration}s`);
}}
/>
</div>
);
};
export default App;API Reference
VideoCanvasPlayerProps
| Prop | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| src | string | Required | The source URL or file path of the video. |
| theme | "dark" \| "light" | "dark" | The visual theme of the player. |
| targetFps | number | 60 | Target frames per second for playback. Max is 60. |
| highlight | HighlightCollection | undefined | A collection of timestamps and labels to display on the timeline. Supports Map<number, string> or Record<number, string>. |
| showThumbnailRail | boolean | false | Shows a clip-style thumbnail rail below the player with hover preview and click-to-seek. |
| initialSeekTime | number | undefined | Seeks to this time when a source is loaded, before the video is shown. |
| pendingStartTime | number | undefined | A higher-priority source-switch seek time. If provided, it overrides initialSeekTime for the current source load. |
| autoPlay | boolean | false | Whether to start playing automatically. |
| loop | boolean | false | Whether the video should loop when it ends. |
| muted | boolean | false | Whether the audio should be initially muted. |
| playbackRate | number | 1 | Initial playback speed multiplier. |
| fastSeekStep | number | 5 | The number of seconds to jump when fast forwarding or rewinding. |
| ffmpeg | FFmpegAssetConfig | undefined | Custom configuration for FFmpeg core/worker instances. |
| backend | PlaybackBackend | undefined | Custom backend for probe and playback resolution. |
Source Switching Example
<VideoCanvasPlayer
src={nextSource}
pendingStartTime={128.4}
autoPlay
showThumbnailRail
/>When pendingStartTime or initialSeekTime is provided, the player seeks the underlying media element first, then reveals the frame and starts playback if autoPlay is enabled.
Event Callbacks
| Callback | Signature | Description |
| :--- | :--- | :--- |
| onPlay | () => void | Fired when playback starts. |
| onPause | () => void | Fired when playback pauses. |
| onFastForward | (time: number) => void | Fired after fast forwarding. Provides the new time. |
| onFastRewind | (time: number) => void | Fired after fast rewinding. Provides the new time. |
| onNextKeyframe | (time: number) => void | Fired when jumping to the next keyframe. |
| onPreviousKeyframe| (time: number) => void | Fired when jumping to the previous keyframe. |
| onPlaybackRateChange | (rate: number) => void | Fired when the playback speed changes from the built-in control or ref API. |
| onTimeChange | (time: number, duration: number) => void | Fired during playback to indicate the current time stream. |
| onError | (error: Error) => void | Fired when an error occurs during playback or FFmpeg processing. |
VideoCanvasPlayerHandle (Ref API)
You can interact with the player programmatically by passing a ref:
play(): Promise<void>: Starts playback.pause(): void: Pauses playback.seekTo(time: number): void: Seeks the video to the specified time (in seconds).fastForward(seconds?: number): void: Skips forward by default or specified seconds.fastRewind(seconds?: number): void: Skips backward by default or specified seconds.nextKeyframe(): void: Uses FFmpeg probe data to jump to the next keyframe.previousKeyframe(): void: Uses FFmpeg probe data to jump to the previous keyframe.setPlaybackRate(rate: number): void: Updates the playback speed multiplier.getPlaybackRate(): number: Returns the current playback speed multiplier.getCurrentTime(): number: Returns the current video time.getDuration(): number: Returns the total video duration.
License
MIT
