mirror of
https://github.com/zoriya/v10.git
synced 2026-08-11 08:29:47 +00:00
@vjs-10/html-media-store
HTML/DOM integration for Video.js media store
Status: Early Development
⚠️ PROTOTYPE - SUBJECT TO CHANGE
This package is in early prototype phase. Expect significant changes including:
- Package restructuring and naming
- Breaking API changes
- Major architectural updates
- Incomplete or experimental features
Not recommended for production use.
Overview
@vjs-10/html-media-store provides DOM-specific integration between @vjs-10/media-store and HTML media elements. It handles bi-directional synchronization between media element state and the reactive store, enabling automatic UI updates across all connected components.
Key Features
- Automatic State Sync - Bi-directional sync between media element and store
- DOM Integration - Native HTMLMediaElement support
- Event Management - Automatic event listener setup and cleanup
- State Mediators - Pre-configured mediators for common patterns
- Memory Safe - Proper cleanup and resource management
Installation
npm install @vjs-10/html-media-store
Quick Start
Basic Integration
import { connectMediaStore } from '@vjs-10/html-media-store';
import { createMediaStore } from '@vjs-10/media-store';
// Create store
const store = createMediaStore();
// Connect to media element
const videoElement = document.querySelector('video');
const connection = connectMediaStore(store, videoElement);
// Store automatically syncs with video state
store.currentTime.subscribe((time) => {
console.log('Current time:', time);
});
// Clean up when done
connection.disconnect();
Core API
connectMediaStore
Connect a media store to an HTMLMediaElement:
import { connectMediaStore } from '@vjs-10/html-media-store';
import { createMediaStore } from '@vjs-10/media-store';
const store = createMediaStore();
const video = document.querySelector('video');
const connection = connectMediaStore(store, video, {
// Optional configuration
autoPlay: false,
syncInterval: 250, // ms between time updates
});
// Returns connection object
interface Connection {
disconnect: () => void; // Clean up listeners
reconnect: () => void; // Re-establish connection
pause: () => void; // Pause sync temporarily
resume: () => void; // Resume sync
}
State Mediators
Pre-configured mediators handle complex state coordination:
import {
setupAudibleMediator,
setupPlayableMediator,
setupTemporalMediator,
} from '@vjs-10/html-media-store';
import { createMediaStore } from '@vjs-10/media-store';
const store = createMediaStore();
const video = document.querySelector('video');
// Playable mediator - play/pause/ended states
const playableMediator = setupPlayableMediator(store, video);
// Audible mediator - volume/muted states
const audibleMediator = setupAudibleMediator(store, video);
// Temporal mediator - time/duration/seeking states
const temporalMediator = setupTemporalMediator(store, video);
// Clean up all mediators
playableMediator.disconnect();
audibleMediator.disconnect();
temporalMediator.disconnect();
State Synchronization
Automatic Sync
The connection automatically syncs these properties:
Playback State:
paused↔video.pausedended↔video.endedseeking↔video.seeking
Time:
currentTime↔video.currentTimeduration↔video.duration
Volume:
volume↔video.volumemuted↔video.muted
Loading:
buffered↔video.bufferedreadyState↔video.readyState
Bi-directional Updates
import { connectMediaStore } from '@vjs-10/html-media-store';
import { createMediaStore } from '@vjs-10/media-store';
const store = createMediaStore();
const video = document.querySelector('video');
connectMediaStore(store, video);
// Update store → updates video
store.paused.set(false); // Video starts playing
// Update video → updates store
video.currentTime = 30; // Store reflects new time
Advanced Usage
Custom Sync Configuration
import { connectMediaStore } from '@vjs-10/html-media-store';
const connection = connectMediaStore(store, video, {
// Sync configuration
syncInterval: 100, // Update frequency (ms)
syncOnSeek: true, // Sync immediately on seek
syncOnPlay: true, // Sync immediately on play
// Event configuration
useCapture: false, // Event capture phase
passive: true, // Passive event listeners
// State configuration
persistVolume: true, // Remember volume in localStorage
persistMuted: true, // Remember muted state
});
Selective State Sync
import { createSyncGroup } from '@vjs-10/html-media-store';
// Only sync specific properties
const syncGroup = createSyncGroup(store, video, {
properties: ['currentTime', 'paused', 'volume'],
events: ['timeupdate', 'play', 'pause', 'volumechange'],
});
syncGroup.start();
syncGroup.stop();
Multiple Elements
import { connectMediaStore } from '@vjs-10/html-media-store';
import { createMediaStore } from '@vjs-10/media-store';
const store = createMediaStore();
// Connect multiple elements to same store
const video1 = document.querySelector('#video1');
const video2 = document.querySelector('#video2');
const connection1 = connectMediaStore(store, video1);
const connection2 = connectMediaStore(store, video2);
// Both videos sync to same state
store.paused.set(false); // Both videos play
Use Cases
Player with Custom Controls
import { connectMediaStore } from '@vjs-10/html-media-store';
import { createMediaStore } from '@vjs-10/media-store';
const store = createMediaStore();
const video = document.querySelector('video');
connectMediaStore(store, video);
// Create custom play button
const playButton = document.querySelector('.play-button');
playButton.addEventListener('click', () => {
store.paused.set(!store.paused.get());
});
// Update button based on state
store.paused.subscribe((paused) => {
playButton.textContent = paused ? 'Play' : 'Pause';
});
Progress Bar Sync
import { connectMediaStore } from '@vjs-10/html-media-store';
import { createMediaStore } from '@vjs-10/media-store';
const store = createMediaStore();
const video = document.querySelector('video');
connectMediaStore(store, video);
const progressBar = document.querySelector('.progress-bar');
// Update progress bar from store
store.currentTime.subscribe((time) => {
const duration = store.duration.get();
const percentage = (time / duration) * 100;
progressBar.style.width = `${percentage}%`;
});
// Seek from progress bar
progressBar.addEventListener('click', (e) => {
const rect = progressBar.getBoundingClientRect();
const x = e.clientX - rect.left;
const percentage = x / rect.width;
const duration = store.duration.get();
store.currentTime.set(duration * percentage);
});
State Persistence
import { connectMediaStore } from '@vjs-10/html-media-store';
import { createMediaStore } from '@vjs-10/media-store';
const store = createMediaStore();
const video = document.querySelector('video');
connectMediaStore(store, video);
// Save state to localStorage
store.volume.subscribe((volume) => {
localStorage.setItem('player-volume', volume.toString());
});
store.currentTime.subscribe((time) => {
if (time > 0) {
localStorage.setItem('player-position', time.toString());
}
});
// Restore state
const savedVolume = localStorage.getItem('player-volume');
if (savedVolume) {
store.volume.set(Number.parseFloat(savedVolume));
}
const savedPosition = localStorage.getItem('player-position');
if (savedPosition) {
store.currentTime.set(Number.parseFloat(savedPosition));
}
API Reference
Functions
// Main connection function
function connectMediaStore(
store: MediaStore,
element: HTMLMediaElement,
options?: ConnectionOptions
): Connection
// Mediator setup functions
function setupPlayableMediator(store: MediaStore, element: HTMLMediaElement): Mediator
function setupAudibleMediator(store: MediaStore, element: HTMLMediaElement): Mediator
function setupTemporalMediator(store: MediaStore, element: HTMLMediaElement): Mediator
Types
interface ConnectionOptions {
syncInterval?: number;
syncOnSeek?: boolean;
syncOnPlay?: boolean;
useCapture?: boolean;
passive?: boolean;
persistVolume?: boolean;
persistMuted?: boolean;
}
interface Connection {
disconnect: () => void;
reconnect: () => void;
pause: () => void;
resume: () => void;
}
interface Mediator {
disconnect: () => void;
pause: () => void;
resume: () => void;
}
Package Dependencies
- Dependencies:
@vjs-10/media-store- State management@vjs-10/html-media-elements- Media element components
- Used by:
@vjs-10/html- Complete HTML player
Development
# Build the package
pnpm build
# Watch mode for development
pnpm dev
# Run tests
pnpm test
# Clean build artifacts
pnpm clean
Related Packages
- @vjs-10/media-store - Core state management
- @vjs-10/html-media-elements - Media elements
- @vjs-10/html - Complete HTML player
- @vjs-10/react-media-store - React equivalent
License
Apache-2.0