FFmpeg drawtext technical evaluation

This commit is contained in:
Accusys
2026-05-08 13:03:15 +08:00
parent 0977a04002
commit 0366eb0f04

View File

@@ -0,0 +1,81 @@
# FFmpeg DrawText 技術選型
## 背景
Momentry 使用 ffmpeg 在影片上繪製 bounding box 和標籤文字(用於 `trace/:id/video``video/bbox` endpoints
## 方案比較
### A. drawtext filter現行
```bash
ffmpeg -i input.mp4 -vf "drawtext=text='Cary Grant':x=100:y=50:fontsize=24:fontcolor=white:box=1:boxcolor=black" output.mp4
```
| 面向 | 評估 |
|------|------|
| 優點 | ffmpeg 內建,不需額外依賴 |
| 缺點 | 每個 frame 只能靜態文字,每變化一次就要重新編碼一段 |
| Unicode | ❌ 需指定 font file否則中文不顯示 |
| 效能 | 每個 bbox 都要 filter多個 bbox 時 chain 複雜 |
| 框線 | 可畫矩形 `drawbox`,但與 drawtext 分開 |
### B. subtitles filter.ass 字幕)
```bash
ffmpeg -i input.mp4 -vf "ass=/tmp/overlay.ass" output.mp4
```
| 面向 | 評估 |
|------|------|
| 優點 | 支援動態位置、漸變、Unicode |
| Unicode | ✅ 內建支援 |
| 效能 | ASS 格式可批次定義,單一 filter chain |
| 缺點 | 需產出 .ass 暫存檔 |
| 複雜度 | 中等 |
### C. showinfo + sed 產生 movi 標記(另類)
| 面向 | 評估 |
|------|------|
| 優點 | 不需要 overlay |
| 缺點 | 無法修改像素,只能 metadata |
| 結論 | 不適用 |
### D. 獨立 render 服務Python + Pillow/OpenCV
```python
from PIL import Image, ImageDraw, ImageFont
frame = Image.open("frame.jpg")
draw = ImageDraw.Draw(frame)
draw.rectangle([x1,y1,x2,y2], outline="red", width=3)
draw.text((x1,y1-10), "Cary Grant", fill="red")
```
| 面向 | 評估 |
|------|------|
| 優點 | 完全控制Unicode OK多邊形/圓形皆可 |
| 缺點 | 需 decode → 繪圖 → encode較慢 |
| Unicode | ✅ 需指定字型檔案 |
| 整合 | 需要額外 HTTP service |
## 結論
| 方案 | Unicode | 效能 | 整合成本 | 建議 |
|------|---------|------|---------|------|
| A. drawtext | ⚠️ 需指定 font | ✅ | 🟢 低 | 現行方案,先解決 Unicode |
| **B. subtitles** | ✅ | ✅ | 🟡 中 | **未來可考慮** |
| D. Python render | ✅ | ❌ 慢 | 🔴 高 | 不適合生產 |
## 現行改善建議
`media_api.rs` 中的 drawtext 缺少 font 指定,導致中文檔名/內容無法顯示:
```diff
- drawtext=text='Cary Grant':fontsize=24:fontcolor=white
+ drawtext=text='Cary Grant':fontsize=24:fontcolor=white:fontfile=/System/Library/Fonts/Supplemental/Arial.ttf
```
macOS 內建中文字型:
- `/System/Library/Fonts/PingFang.ttc` (蘋方,中文)
- `/System/Library/Fonts/Helvetica.ttc` (英文)