Files
vlchan/README.md
2025-10-09 16:42:35 +11:00

188 lines
4.7 KiB
Markdown

# VLChan
A Python video player using VLC SDK with synchan server timecode synchronization.
## Features
- VLC-based video playback with full media support
- Real-time synchronization with synchan server
- Reactive programming with RxPY
- **Advanced synchronization with latency compensation**
- **Playback rate adjustment for smooth sync**
- Automatic timecode correction with smart seeking
- Playback state synchronization
- Volume, playback rate, and fullscreen controls
## Installation
1. Install VLC media player on your system:
- Ubuntu/Debian: `sudo apt install vlc`
- macOS: `brew install vlc`
- Windows: Download from [videolan.org](https://www.videolan.org/vlc/)
2. Install the Python package:
```bash
cd vlchan
poetry install
```
## Usage
### Basic Usage
```python
from vlchan import VLChanPlayer
# Create player with video file
player = VLChanPlayer(
synchan_url="http://localhost:3000",
video_path="/path/to/video.mp4"
)
# Start synchronization
player.start_sync()
# Play video
player.play()
# Clean up when done
player.cleanup()
```
### Advanced Usage
```python
from vlchan import VLChanPlayer
def on_state_change(state):
print(f"Synchan state: playing={state.playing}, time={state.currentTime:.2f}s")
# Create player
player = VLChanPlayer("http://localhost:3000", "video.mp4")
# Set up state change callback
player.on_state_change = on_state_change
# Start synchronization
player.start_sync()
# Control playback
player.play()
player.pause()
player.seek(120.5) # Seek to 2 minutes 0.5 seconds
# Adjust settings
player.set_volume(80)
player.set_fullscreen(True)
# Get current state
print(f"Position: {player.get_position():.2f}s")
print(f"Duration: {player.get_duration():.2f}s")
print(f"Playing: {player.is_playing()}")
```
### Command Line Usage
```bash
# Play video with synchan sync
poetry run python -m vlchan.player video.mp4
# Use custom synchan server
poetry run python -m vlchan.player video.mp4 http://192.168.1.100:3000
```
## API Reference
### VLChanPlayer
#### Constructor
- `VLChanPlayer(synchan_url: str, video_path: Optional[str])`
- `synchan_url`: URL of the synchan server (default: "http://localhost:3000")
- `video_path`: Path to video file to load
#### Methods
- `load_video(video_path: str)`: Load a video file
- `start_sync()`: Start synchronization with synchan server
- `stop_sync()`: Stop synchronization
- `play()`: Start playback
- `pause()`: Pause playback
- `stop()`: Stop playback
- `seek(time_seconds: float)`: Seek to specific time
- `set_volume(volume: int)`: Set volume (0-100)
- `get_volume() -> int`: Get current volume
- `set_fullscreen(fullscreen: bool)`: Toggle fullscreen
- `get_position() -> float`: Get current position in seconds
- `get_compensated_position(latency: float) -> float`: Get latency-compensated position
- `get_duration() -> float`: Get video duration in seconds
- `is_playing() -> bool`: Check if playing
- `get_rate() -> float`: Get current playback rate
- `set_rate(rate: float)`: Set playback rate (1.0 = normal speed)
- `cleanup()`: Clean up resources
#### Properties
- `on_state_change`: Callback for synchan state changes
### SynchanState
Data class containing synchronization state:
- `playing: bool`: Whether video should be playing
- `currentTime: float`: Current time position in seconds
- `duration: float`: Total duration in seconds
- `loop: bool`: Whether video should loop
- `latency: float`: Network latency in seconds
## Synchronization
The player uses advanced synchronization logic similar to the synchan VideoPlayer component:
1. **Latency Compensation**: Server time is adjusted by network latency
2. **Smart Seeking**: Large time differences (>1s) trigger immediate seeking
3. **Playback Rate Adjustment**: Small differences are corrected by adjusting playback speed
4. **Rate Formula**: `rate = 1 + min(max(diff * 0.5, -0.05), 0.05)`
5. **Playback State**: Play/pause commands are synchronized
6. **Reconnection**: Automatically attempts to reconnect on connection loss
### Synchronization Algorithm
```python
# Apply latency compensation
compensated_time = server_time + latency / 1000
# Calculate difference
diff = compensated_time - local_time
# Large difference: seek immediately
if diff > 1.0:
player.seek(compensated_time)
# Small difference: adjust playback rate
rate = 1 + min(max(diff * 0.5, -0.05), 0.05)
player.set_rate(rate)
```
## Requirements
- Python 3.11+
- VLC media player
- Synchan server running
## Dependencies
- `python-vlc`: VLC Python bindings
- `reactivex`: Reactive programming
- `python-socketio`: WebSocket client for synchan
- `requests`: HTTP client for synchan API
## Development
```bash
# Install development dependencies
poetry install --with dev
# Run linting
poetry run ruff check .
# Run type checking
poetry run mypy vlchan/
```