https://github.com/diffusionstudio/webcodecs-scroll-sync
https://github.com/diffusionstudio/webcodecs-scroll-sync
Last synced: 6 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/diffusionstudio/webcodecs-scroll-sync
- Owner: diffusionstudio
- License: mit
- Created: 2025-08-10T10:31:40.000Z (6 months ago)
- Default Branch: main
- Last Pushed: 2025-08-10T13:33:04.000Z (6 months ago)
- Last Synced: 2025-08-10T17:45:16.863Z (6 months ago)
- Language: TypeScript
- Size: 8.79 KB
- Stars: 3
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# webcodecs-scroll-sync
A video decoder that synchronizes video playback with scroll position using the WebCodecs API.
## Dependencies
This project requires **mediabunny** as a dependency:
```bash
npm install mediabunny
```
## Files Overview
- `decoder.ts` - Core `FrameDecoder` class that handles video decoding and buffering
- `canvas.tsx` - React component example showing integration with scroll events
- `utils.ts` - Utility functions (assertion helper)
## Basic Usage
### 1. Initialize the Decoder
The `FrameDecoder` must be initialized with a video URL:
```javascript
import { FrameDecoder } from './decoder';
const frameDecoder = new FrameDecoder();
// Initialize with video URL
await frameDecoder.init('https://example.com/your-video.mp4');
```
### 2. Seek to Video Position
Use the `seek()` method to jump to specific video positions based on scroll:
```javascript
// Seek to 50% through the video
frameDecoder.seek(0.5);
// Get current frame for rendering
const currentFrame = frameDecoder.frame;
```
### 3. Render Frames
Draw the current frame to a canvas:
```javascript
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
const drawFrame = () => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
frameDecoder.drawFrame(ctx, canvas.width, canvas.height);
requestAnimationFrame(drawFrame);
};
drawFrame();
```
## React Example
The included `canvas.tsx` demonstrates a complete React implementation with scroll synchronization:
```jsx
import { Canvas } from './canvas';
function App() {
return (
{/* Your scrollable content */}
);
}
```
## Framework Agnostic Usage
While `canvas.tsx` shows a React example, the core decoder can be used with any JavaScript framework:
### Vanilla JavaScript
```javascript
import { FrameDecoder } from './decoder';
const decoder = new FrameDecoder();
await decoder.init('your-video-url.mp4');
window.addEventListener('scroll', () => {
const scrollFraction = window.scrollY / (document.documentElement.scrollHeight - window.innerHeight);
decoder.seek(scrollFraction);
});
```
## Key Features
- **Efficient Buffering**: Maintains optimal frame buffer based on current playback position
- **Smooth Seeking**: Binary search algorithms for fast frame lookup
- **Memory Management**: Automatic cleanup of unused video frames
- **Bidirectional Playback**: Optimized for both forward and backward seeking
- **High Performance**: Uses WebCodecs API for hardware-accelerated video decoding
**Note**: The required buffer range is highly dependent on the density of keyframes in your video footage. Videos with more frequent keyframes will perform better with this decoder.
## Browser Support
Requires browsers with WebCodecs API support:
- Chrome 94+
- Edge 94+
- Opera 80+
- Firefox 130+
- Safari 16.4+
(Firefox for Andriod is not supported)
## Cleanup
Always call `destroy()` when done to free resources:
```javascript
// Cleanup when component unmounts or page unloads
frameDecoder.destroy();
```