478 lines
9.0 KiB
Markdown
478 lines
9.0 KiB
Markdown
# 视频播放器控制系统 API 文档
|
||
|
||
## 概述
|
||
|
||
本文档描述了视频播放器控制系统的完整API接口,包括控制端(Controller)和播放端(Player)之间的通信协议。系统采用WebSocket进行实时通信,支持播放控制、状态同步等功能。
|
||
|
||
## 通信协议
|
||
|
||
### 连接方式
|
||
- 协议:WebSocket
|
||
- 默认端口:8080
|
||
- 连接URL:`ws://{host}:{port}/ws`
|
||
|
||
### 消息格式
|
||
所有消息均采用JSON格式,包含以下基本结构:
|
||
|
||
```json
|
||
{
|
||
"type": "command|status|response",
|
||
"data": {...}
|
||
}
|
||
```
|
||
|
||
## 控制端 API (Tauri Commands)
|
||
|
||
### 连接管理
|
||
|
||
#### 连接到播放器
|
||
```rust
|
||
connect_to_player(config: ConnectionConfig) -> Result<ApiResponse<PlayerState>, String>
|
||
```
|
||
|
||
**参数:**
|
||
```json
|
||
{
|
||
"host": "127.0.0.1",
|
||
"port": 8080,
|
||
"timeout": 10,
|
||
"autoReconnect": true,
|
||
"reconnectInterval": 5
|
||
}
|
||
```
|
||
|
||
**返回:**
|
||
```json
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"connectionStatus": "connected",
|
||
"playbackStatus": "stopped",
|
||
"currentVideo": null,
|
||
"position": 0.0,
|
||
"duration": 0.0,
|
||
"volume": 50.0,
|
||
"isLooping": false,
|
||
"isFullscreen": false,
|
||
"playlist": [],
|
||
"currentPlaylistIndex": null
|
||
},
|
||
"message": "成功连接到视频播放器"
|
||
}
|
||
```
|
||
|
||
#### 断开连接
|
||
```rust
|
||
disconnect_from_player() -> Result<ApiResponse<()>, String>
|
||
```
|
||
|
||
#### 获取连接状态
|
||
```rust
|
||
get_connection_status() -> Result<ApiResponse<PlayerState>, String>
|
||
```
|
||
|
||
#### 更新连接配置
|
||
```rust
|
||
update_connection_config(config: ConnectionConfig) -> Result<ApiResponse<()>, String>
|
||
```
|
||
|
||
### 播放控制
|
||
|
||
#### 发送播放命令
|
||
```rust
|
||
send_playback_command(command: PlaybackCommand) -> Result<ApiResponse<()>, String>
|
||
```
|
||
|
||
**支持的命令类型:**
|
||
|
||
1. **播放**
|
||
```json
|
||
{
|
||
"type": "play"
|
||
}
|
||
```
|
||
|
||
2. **暂停**
|
||
```json
|
||
{
|
||
"type": "pause"
|
||
}
|
||
```
|
||
|
||
3. **停止**
|
||
```json
|
||
{
|
||
"type": "stop"
|
||
}
|
||
```
|
||
|
||
4. **跳转**
|
||
```json
|
||
{
|
||
"type": "seek",
|
||
"position": 60.5
|
||
}
|
||
```
|
||
|
||
5. **设置音量**
|
||
```json
|
||
{
|
||
"type": "setVolume",
|
||
"volume": 75.0
|
||
}
|
||
```
|
||
|
||
6. **设置循环**
|
||
```json
|
||
{
|
||
"type": "setLoop",
|
||
"enabled": true
|
||
}
|
||
```
|
||
|
||
7. **切换全屏**
|
||
```json
|
||
{
|
||
"type": "toggleFullscreen"
|
||
}
|
||
```
|
||
|
||
8. **加载视频**
|
||
```json
|
||
{
|
||
"type": "loadVideo",
|
||
"path": "/path/to/video.mp4"
|
||
}
|
||
```
|
||
|
||
9. **设置播放列表**
|
||
```json
|
||
{
|
||
"type": "setPlaylist",
|
||
"videos": ["/path/to/video1.mp4", "/path/to/video2.mp4"]
|
||
}
|
||
```
|
||
|
||
10. **播放列表中的指定视频**
|
||
```json
|
||
{
|
||
"type": "playFromPlaylist",
|
||
"index": 0
|
||
}
|
||
```
|
||
|
||
### 设置管理
|
||
|
||
#### 加载应用设置
|
||
```rust
|
||
load_app_settings() -> Result<ApiResponse<AppSettings>, String>
|
||
```
|
||
|
||
#### 保存应用设置
|
||
```rust
|
||
save_app_settings(settings: AppSettings) -> Result<ApiResponse<()>, String>
|
||
```
|
||
|
||
#### 重置应用设置
|
||
```rust
|
||
reset_app_settings() -> Result<ApiResponse<AppSettings>, String>
|
||
```
|
||
|
||
#### 导出设置到文件
|
||
```rust
|
||
export_settings_to_file() -> Result<ApiResponse<String>, String>
|
||
```
|
||
|
||
#### 从文件导入设置
|
||
```rust
|
||
import_settings_from_file() -> Result<ApiResponse<AppSettings>, String>
|
||
```
|
||
|
||
### 文件操作
|
||
|
||
#### 选择视频文件(多选)
|
||
```rust
|
||
select_video_files() -> Result<ApiResponse<Vec<String>>, String>
|
||
```
|
||
|
||
#### 选择单个视频文件
|
||
```rust
|
||
select_single_video_file() -> Result<ApiResponse<String>, String>
|
||
```
|
||
|
||
#### 获取视频信息
|
||
```rust
|
||
get_video_info(file_path: String) -> Result<ApiResponse<VideoInfo>, String>
|
||
```
|
||
|
||
#### 验证视频文件
|
||
```rust
|
||
validate_video_files(file_paths: Vec<String>) -> Result<ApiResponse<Vec<VideoInfo>>, String>
|
||
```
|
||
|
||
#### 获取支持的视频格式
|
||
```rust
|
||
get_supported_video_formats() -> Result<ApiResponse<Vec<String>>, String>
|
||
```
|
||
|
||
#### 打开文件位置
|
||
```rust
|
||
open_file_location(file_path: String) -> Result<ApiResponse<()>, String>
|
||
```
|
||
|
||
## 播放端 API 规范
|
||
|
||
### WebSocket 服务端实现
|
||
|
||
播放端需要实现一个WebSocket服务器,监听控制端的连接和命令。
|
||
|
||
#### 基本结构
|
||
```rust
|
||
// 启动WebSocket服务器
|
||
async fn start_websocket_server(host: &str, port: u16) -> Result<(), Box<dyn Error>>
|
||
|
||
// 处理客户端连接
|
||
async fn handle_client_connection(websocket: WebSocketStream) -> Result<(), Box<dyn Error>>
|
||
|
||
// 处理接收到的命令
|
||
async fn handle_command(command: PlaybackCommand) -> Result<(), Box<dyn Error>>
|
||
|
||
// 发送状态更新
|
||
async fn send_status_update(status: PlayerState) -> Result<(), Box<dyn Error>>
|
||
```
|
||
|
||
#### 必需实现的功能
|
||
|
||
1. **连接管理**
|
||
- 接受控制端连接
|
||
- 处理连接断开
|
||
- 心跳检测
|
||
|
||
2. **命令处理**
|
||
- 播放/暂停/停止
|
||
- 音量调节
|
||
- 播放位置控制
|
||
- 全屏切换
|
||
- 视频文件加载
|
||
|
||
3. **状态同步**
|
||
- 定期发送播放状态
|
||
- 响应状态查询
|
||
- 事件驱动的状态更新
|
||
|
||
### 状态同步消息
|
||
|
||
播放端应定期或在状态改变时向控制端发送状态信息:
|
||
|
||
```json
|
||
{
|
||
"type": "status",
|
||
"data": {
|
||
"playbackStatus": "playing|paused|stopped|loading",
|
||
"currentVideo": {
|
||
"path": "/path/to/current/video.mp4",
|
||
"title": "Video Title",
|
||
"duration": 3600.0,
|
||
"size": 1024000000,
|
||
"format": "mp4"
|
||
},
|
||
"position": 120.5,
|
||
"duration": 3600.0,
|
||
"volume": 75.0,
|
||
"isLooping": false,
|
||
"isFullscreen": true,
|
||
"playlist": [
|
||
{
|
||
"path": "/path/to/video1.mp4",
|
||
"title": "Video 1",
|
||
"duration": 1800.0
|
||
}
|
||
],
|
||
"currentPlaylistIndex": 0
|
||
}
|
||
}
|
||
```
|
||
|
||
### 事件通知
|
||
|
||
播放端可以发送特定事件通知:
|
||
|
||
#### 视频播放完成
|
||
```json
|
||
{
|
||
"type": "event",
|
||
"event": "playbackFinished",
|
||
"data": {
|
||
"videoPath": "/path/to/finished/video.mp4"
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 播放错误
|
||
```json
|
||
{
|
||
"type": "event",
|
||
"event": "playbackError",
|
||
"data": {
|
||
"error": "Failed to load video file",
|
||
"videoPath": "/path/to/problematic/video.mp4"
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 播放列表改变
|
||
```json
|
||
{
|
||
"type": "event",
|
||
"event": "playlistChanged",
|
||
"data": {
|
||
"playlist": [...],
|
||
"currentIndex": 0
|
||
}
|
||
}
|
||
```
|
||
|
||
## 数据类型定义
|
||
|
||
### PlayerState
|
||
```typescript
|
||
interface PlayerState {
|
||
connectionStatus: "connected" | "connecting" | "disconnected" | { error: string }
|
||
playbackStatus: "playing" | "paused" | "stopped" | "loading"
|
||
currentVideo?: VideoInfo
|
||
position: number
|
||
duration: number
|
||
volume: number
|
||
isLooping: boolean
|
||
isFullscreen: boolean
|
||
playlist: VideoInfo[]
|
||
currentPlaylistIndex?: number
|
||
}
|
||
```
|
||
|
||
### VideoInfo
|
||
```typescript
|
||
interface VideoInfo {
|
||
path: string
|
||
title: string
|
||
duration?: number
|
||
size?: number
|
||
format?: string
|
||
}
|
||
```
|
||
|
||
### ConnectionConfig
|
||
```typescript
|
||
interface ConnectionConfig {
|
||
host: string
|
||
port: number
|
||
timeout: number
|
||
autoReconnect: boolean
|
||
reconnectInterval: number
|
||
}
|
||
```
|
||
|
||
### AppSettings
|
||
```typescript
|
||
interface AppSettings {
|
||
connection: ConnectionConfig
|
||
defaultVolume: number
|
||
defaultLoop: boolean
|
||
autoFullscreen: boolean
|
||
playbackEndBehavior: "stop" | "next" | "repeat"
|
||
theme: string
|
||
language: string
|
||
showNotifications: boolean
|
||
debugMode: boolean
|
||
cacheSize: number
|
||
proxy?: string
|
||
}
|
||
```
|
||
|
||
## 错误处理
|
||
|
||
### 常见错误代码
|
||
|
||
- `CONNECTION_FAILED`: 无法连接到播放器
|
||
- `CONNECTION_TIMEOUT`: 连接超时
|
||
- `INVALID_COMMAND`: 无效的播放命令
|
||
- `FILE_NOT_FOUND`: 视频文件未找到
|
||
- `UNSUPPORTED_FORMAT`: 不支持的视频格式
|
||
- `PLAYBACK_ERROR`: 播放过程中出错
|
||
|
||
### 错误响应格式
|
||
```json
|
||
{
|
||
"success": false,
|
||
"error": "CONNECTION_FAILED",
|
||
"message": "无法连接到视频播放器 192.168.1.100:8080"
|
||
}
|
||
```
|
||
|
||
## 最佳实践
|
||
|
||
1. **连接管理**
|
||
- 实现自动重连机制
|
||
- 使用心跳检测维护连接
|
||
- 优雅处理连接断开
|
||
|
||
2. **状态同步**
|
||
- 播放状态改变时立即通知
|
||
- 定期发送状态更新(建议每秒一次)
|
||
- 使用事件驱动的状态更新
|
||
|
||
3. **错误处理**
|
||
- 提供详细的错误信息
|
||
- 实现重试机制
|
||
- 记录详细的调试日志
|
||
|
||
4. **性能优化**
|
||
- 避免频繁的状态更新
|
||
- 使用压缩传输大量数据
|
||
- 实现客户端缓存
|
||
|
||
## 示例实现
|
||
|
||
### 播放端基础WebSocket服务器(Rust)
|
||
|
||
```rust
|
||
use tokio_tungstenite::{accept_async, tungstenite::Message};
|
||
use tokio::net::{TcpListener, TcpStream};
|
||
use futures_util::{StreamExt, SinkExt};
|
||
|
||
async fn start_player_server() -> Result<(), Box<dyn Error>> {
|
||
let listener = TcpListener::bind("0.0.0.0:8080").await?;
|
||
println!("视频播放器服务器启动在 0.0.0.0:8080");
|
||
|
||
while let Ok((stream, _)) = listener.accept().await {
|
||
tokio::spawn(handle_connection(stream));
|
||
}
|
||
|
||
Ok(())
|
||
}
|
||
|
||
async fn handle_connection(stream: TcpStream) -> Result<(), Box<dyn Error>> {
|
||
let ws_stream = accept_async(stream).await?;
|
||
let (mut ws_sender, mut ws_receiver) = ws_stream.split();
|
||
|
||
while let Some(msg) = ws_receiver.next().await {
|
||
match msg? {
|
||
Message::Text(text) => {
|
||
// 解析并处理播放命令
|
||
if let Ok(command) = serde_json::from_str::<PlaybackCommand>(&text) {
|
||
handle_playback_command(command).await?;
|
||
}
|
||
}
|
||
Message::Ping(data) => {
|
||
ws_sender.send(Message::Pong(data)).await?;
|
||
}
|
||
_ => {}
|
||
}
|
||
}
|
||
|
||
Ok(())
|
||
}
|
||
```
|
||
|
||
这份API文档为视频播放器的开发提供了完整的接口规范,确保控制端和播放端之间的良好协作。
|