Files
momentry_playground/AGENTS.md

374 lines
6.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# MoMentry Playground - AGENTS.md
## 概述
MoMentry Playground 是一個整合式桌面應用程式,提供:
- 多格式媒體播放(視頻、音頻、圖片)
- Markdown/PDF/HTML 檢視
- Frame-精確的視頻控制
- 與 momentry_core 處理模組的進度監控
- Database 查詢功能
## 技術棧
| 元件 | 技術 |
|------|------|
| 語言 | Rust 2021 |
| 桌面框架 | tao + wry |
| 視頻播放 | SDL2 + FFmpeg-sidecar |
| 前端 | HTML/CSS/JS (WebView) |
| 後端接口 | HTTP API (momentry_core port 3002) |
| 數據庫 | PostgreSQL, MongoDB, Qdrant (via API) |
---
## 構建/測試/代碼質量命令
### 構建
```bash
# Debug 構建
cargo build
# Release 構建
cargo build --release
# 運行
cargo run
# 指定功能運行
cargo run --features "youtube,cloud"
```
### 測試
```bash
# 運行所有測試
cargo test
# 運行單個測試
cargo test test_name
# 運行並顯示輸出
cargo test -- --nocapture
# 運行 doc tests
cargo test --doc
```
### 代碼質量
```bash
# 格式化代碼
cargo fmt
# 檢查格式化
cargo fmt -- --check
# Lint + 自動修復
cargo clippy --fix --allow-dirty --allow-staged
# Lint 檢查
cargo clippy
# 類型檢查
cargo check
# 完整檢查(相當於所有以上)
cargo build --all-targets
```
### WASM 目標(如使用 Yew
```bash
# 添加 WASM 目標
rustup target add wasm32-unknown-unknown
# 使用 Trunk 開發
trunk serve
# Production 構建
trunk build --release
```
---
## 代碼風格指南
### 格式規範
- **最大行長**: 100 字符
- **縮進**: 4 空格(使用 `rustfmt` 自動處理)
- **換行**: Unix 風格 (`\n`)
### 命名慣例
```rust
// 類型/結構體/枚舉: PascalCase
struct VideoPlayer;
enum PlaybackState;
trait MediaViewer;
// 函數/方法/變量: snake_case
fn play_video();
let current_frame = 0;
let is_playing = true;
// 常量: SCREAMING_SNAKE_CASE
const MAX_FRAME_BUFFER: usize = 10;
const SEEK_DELAY_MS: u64 = 500;
// 模塊: snake_case
mod video_player;
pub mod ffmpeg;
// 公開 API: 完整單詞
fn get_playback_position() -> Duration;
fn set_volume() -> Result<(), PlayerError>;
```
### 錯誤處理
```rust
// 使用 anyhow 進行應用級錯誤處理
use anyhow::{Context, Result, anyhow};
fn load_video(path: &str) -> Result<VideoFile> {
let file = File::open(path)
.with_context(|| format!("Failed to open video: {}", path))?;
// ...
}
// 定義專用錯誤枚舉
#[derive(Debug, thiserror::Error)]
pub enum PlayerError {
#[error("Codec not supported: {0}")]
UnsupportedCodec(String),
#[error("Seek failed: {0}")]
SeekFailed(String),
#[error("FFmpeg error: {stderr}")]
FFmpegError { stderr: String },
}
```
### 模塊結構
```rust
// src/lib.rs - 庫入口
pub mod player;
pub mod ui;
pub mod viewer;
pub mod api;
// 每個模塊的組織
mod player {
pub mod video; // 公開子模塊
mod controls; // 私有實現
pub use video::{VideoPlayer, VideoEvent};
}
```
### 並發安全
```rust
// 使用 Arc<Mutex<T>> 共享狀態
let player = Arc::new(Mutex::new(VideoPlayer::new()));
// 在多線程間共享 Frame buffer
type FrameBuffer = Arc<Mutex<VecDeque<Frame>>>;
// Spawn 線程時克隆 Arc
let player_clone = Arc::clone(&player);
std::thread::spawn(move || {
// ...
});
```
### 文檔注釋
```rust
/// 視頻播放器核心結構
///
/// # Example
/// ```
/// let player = VideoPlayer::new();
/// player.open("video.mp4")?;
/// player.play()?;
/// ```
pub struct VideoPlayer {
// ...
}
/// 播放事件
#[derive(Debug, Clone, PartialEq)]
pub enum PlayEvent {
/// 播放開始
Play,
/// 播放暫停
Pause,
/// 進度更新 (當前幀, 總幀數)
Progress(u64, u64),
/// 播放結束
End,
}
```
### 依賴管理
```toml
# 明確版本範圍
[dependencies]
anyhow = "1.0"
serde = { version = "1.0", features = ["derive"] }
# 避免使用 * 導入
# 錯誤: use std::collections::*;
# 正確: use std::collections::{HashMap, HashSet};
```
### API 設計
```rust
// 使用 Result 明確錯誤
fn command(&self, cmd: &str) -> Result<String>;
// 公開方法要有文檔
/// 發送播放命令
///
/// # Arguments
/// * `cmd` - 命令字串 ("play", "pause", "seek <time>")
///
/// # Errors
/// 返回無效命令或播放錯誤
pub fn command(&self, cmd: &str) -> Result<String> {
// ...
}
```
---
## WebView 前端規範
### HTML 結構
```html
<div id="app">
<div id="toolbar"><!-- 控制工具欄 --></div>
<div id="input-area"><!-- 命令輸入 --></div>
<div id="media-viewport"><!-- 媒體顯示 --></div>
<div id="controls"><!-- 播放控制 --></div>
<div id="status-bar"><!-- 狀態信息 --></div>
<div id="output-log"><!-- 日誌輸出 --></div>
</div>
```
### JS 命令接口
```javascript
// 發送命令到 Rust 後端
function sendCommand(cmd) {
window.momentry_command(cmd);
}
// 接收後端事件
window.momentry_on_event = function(event) {
console.log('Event:', event);
};
```
### CSS 樣式
```css
:root {
--bg-primary: #1e1e1e;
--bg-secondary: #2d2d2d;
--text-primary: #ffffff;
--accent: #007acc;
--error: #f44747;
}
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: system-ui, sans-serif; }
```
---
## 外部依賴
### FFmpeg (必需)
```bash
# macOS
brew install ffmpeg
# Linux
sudo apt install ffmpeg
# 驗證
ffmpeg -version
ffprobe -version
```
### yt-dlp (YouTube 支援)
```bash
brew install yt-dlp # macOS
pip install yt-dlp # pip
```
---
## 環境變量
```bash
# API 服務地址
export MOMENTRY_API_URL=http://localhost:3002
# 數據庫連接
export DATABASE_URL=postgresql://user:pass@localhost:5432/momentry
export QDRANT_URL=http://localhost:6333
# 輸出目錄
export MOMENTRY_OUTPUT_DIR=./output
# 日誌級別
export RUST_LOG=debug
```
---
## 開發工作流
### 1. 創建功能分支
```bash
git checkout -b feature/video-controls
```
### 2. 開發與測試
```bash
cargo test feature_name
cargo clippy --fix
cargo fmt
cargo build --release
```
### 3. 提交使用Conventional Commits
```bash
git commit -m "feat(player): add frame-precise seeking"
git commit -m "fix(controls): correct volume sync"
git commit -m "docs: update AGENTS.md"
```
### 4. 推送與 PR
```bash
git push -u origin feature/video-controls
# 在 Gitea 創建 PR → main
```
---
## 常見問題
### Q: FFmpeg 路徑找不到
```rust
// 在代碼中指定路徑
let ffmpeg_path = std::path::Path::new("/opt/homebrew/bin/ffmpeg");
VideoDecoder::new(ffmpeg_path)
```
### Q: WebView 不顯示
確保 `index.html` 在正確的資源路徑,或使用 `include_bytes!` 嵌入。
### Q: 編譯緩慢
```bash
# 使用 sccache
cargo install sccache
export RUSTC_WRAPPER=sccache
```