feat: frame-based positioning and mark system foundation
Core Changes: - Fix SearchView to use start_frame/end_frame directly (no time*fps conversion) - Add hard_delete support to delete_trace API - VideoPlayer: Main timeline + Mark system foundation - Proxy: Add local routes for auth, media, identity-matches, cluster-results - Add .gitignore to exclude build artifacts and dependencies Design Documents: - Multi-track Mark system design (.opencode/plans/) - Video editing positioning standards research Files Modified: - src/views/SearchView.vue: Frame positioning, ensureMinDuration (240 frames) - src/views/PeopleView.vue: batchDeleteGroups with hard_delete - src/api/index.ts: delete_trace with hard_delete body - src/components/VideoPlayer.vue: Timeline + Mark UI - src-tauri/src/proxy.rs: New local routes - AGENTS.md: Update documentation
This commit is contained in:
147
docs/issues/corrupted-video-seek-issue.md
Normal file
147
docs/issues/corrupted-video-seek-issue.md
Normal file
@@ -0,0 +1,147 @@
|
||||
# 影片 Seek 異常問題
|
||||
|
||||
## 問題描述
|
||||
|
||||
**影片檔案**: `Gamma 8-Director Chih-Lin Yang Shares His Experience:楊智麟導演經驗分享.mp4`
|
||||
**UUID**: `d3f9ae8e471a1fc4d47022c66091b920`
|
||||
**大小**: 219.0 MB
|
||||
**時長**: 298.67 秒(約 5 分鐘)
|
||||
|
||||
**症狀**:
|
||||
- 3 分鐘後 seek 異常
|
||||
- 異常行為:
|
||||
1. 回到影片開頭
|
||||
2. 跳到影片結尾
|
||||
|
||||
## 診斷結果
|
||||
|
||||
### ffprobe 檢測錯誤
|
||||
|
||||
```
|
||||
[h264 @ 0x7ad048e00] Invalid NAL unit size (49912 > 22668).
|
||||
[h264 @ 0x7ad048a80] missing picture in access unit with size 22672
|
||||
[h264 @ 0x7ad048a80] Error splitting the input into NAL units.
|
||||
```
|
||||
|
||||
### 影片結構分析
|
||||
|
||||
| 項目 | 數值 | 狀態 |
|
||||
|------|------|------|
|
||||
| Codec | H.264 High Profile | ✅ |
|
||||
| 解析度 | 1920x1080 | ✅ |
|
||||
| 幀率 | 29.97 fps (30000/1001) | ✅ |
|
||||
| Keyframe 間距 | ~28 幀 (~1 秒) | ✅ |
|
||||
| moov atom 位置 | 28 bytes | ✅ 正確(在開頭) |
|
||||
| stss seek table | 存在 | ✅ |
|
||||
| NAL units | **損壞** | ❌ |
|
||||
|
||||
### Range Requests 測試
|
||||
|
||||
Core API Range requests 運作正常:
|
||||
|
||||
```
|
||||
curl -I -H "Range: bytes=150000000-150001000" ...
|
||||
HTTP/1.1 206 Partial Content
|
||||
content-range: bytes 150000000-150001000/229638144
|
||||
```
|
||||
|
||||
## 根本原因
|
||||
|
||||
**影片檔案本身有損壞的 NAL units**,非 Studio 或 Core API 問題。
|
||||
|
||||
瀏覽器的 H.264 解碼器在遇到損壞的 NAL units 時會:
|
||||
1. 無法正確解碼目標幀
|
||||
2. 嘔試從最近的 keyframe 恢復
|
||||
3. 若恢復失敗,跳回開頭或結尾
|
||||
|
||||
## 解決方案
|
||||
|
||||
### 方案 1: 重新封裝(Remux)
|
||||
|
||||
不重新編碼,僅重新打包容器:
|
||||
|
||||
```bash
|
||||
ffmpeg -i "/Users/accusys/momentry/var/sftpgo/data/demo/Gamma 8-Director Chih-Lin Yang Shares His Experience:楊智麟導演經驗分享.mp4" \
|
||||
-c copy \
|
||||
"/Users/accusys/momentry/var/sftpgo/data/demo/Gamma 8-Director Chih-Lin Yang Shares His Experience_fixed.mp4"
|
||||
```
|
||||
|
||||
優點:快速、不損失畫質
|
||||
缺點:可能無法修復損壞的幀
|
||||
|
||||
### 方案 2: 重新編碼(Transcode)
|
||||
|
||||
完整重新編碼:
|
||||
|
||||
```bash
|
||||
ffmpeg -i "/Users/accusys/momentry/var/sftpgo/data/demo/Gamma 8-Director Chih-Lin Yang Shares His Experience:楊智麟導演經驗分享.mp4" \
|
||||
-c:v libx264 -crf 18 \
|
||||
-c:a aac -b:a 128k \
|
||||
"/Users/accusys/momentry/var/sftpgo/data/demo/Gamma 8-Director Chih-Lin Yang Shares His Experience_reencoded.mp4"
|
||||
```
|
||||
|
||||
優點:完整修復損壞的幀
|
||||
缺點:耗時、些微畫質損失
|
||||
|
||||
### 方案 3: 重新註冊
|
||||
|
||||
修復後需重新註冊到系統:
|
||||
|
||||
```bash
|
||||
# 取消註冊舊檔案
|
||||
curl -X POST http://localhost:8888/api/v1/unregister \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"file_uuid": "d3f9ae8e471a1fc4d47022c66091b920"}'
|
||||
|
||||
# 註冊新檔案
|
||||
curl -X POST http://localhost:8888/api/v1/files/register \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"file_path": "/path/to/fixed_video.mp4"}'
|
||||
```
|
||||
|
||||
## 預防措施
|
||||
|
||||
### 上傳時驗證
|
||||
|
||||
可在檔案註冊時加入驗證:
|
||||
|
||||
```bash
|
||||
ffprobe -v error -count_frames -select_streams v:0 \
|
||||
-show_entries stream=codec_name \
|
||||
-of default=noprint_wrappers=1 input.mp4
|
||||
```
|
||||
|
||||
若有錯誤輸出,標記檔案為「需要檢查」或自動嘗試修復。
|
||||
|
||||
### 定期檢查腳本
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# check_videos.sh
|
||||
for file in /path/to/videos/*.mp4; do
|
||||
errors=$(ffprobe -v error -count_frames "$file" 2>&1 | grep -i "invalid\|error\|corrupt")
|
||||
if [ -n "$errors" ]; then
|
||||
echo "ISSUE: $file"
|
||||
echo "$errors"
|
||||
fi
|
||||
done
|
||||
```
|
||||
|
||||
## 其他影片測試
|
||||
|
||||
測試其他影片均正常,確認問題僅限於此特定檔案。
|
||||
|
||||
## 狀態
|
||||
|
||||
- [x] 問題診斷完成
|
||||
- [ ] 嘗試 remux 修復
|
||||
- [ ] 嘗試 transcode 修復(若 remux 失敗)
|
||||
- [ ] 重新註冊檔案
|
||||
- [ ] 驗證 seek 功能正常
|
||||
|
||||
---
|
||||
|
||||
**建立日期**: 2026-07-22
|
||||
**相關文件**:
|
||||
- `/Users/accusys/momentry_studio/docs/core-api-usage.md`
|
||||
- `/Users/accusys/momentry_studio/docs/core-api-fix-video-range.md`
|
||||
Reference in New Issue
Block a user