Files
360_player/README.md
T
JianMiauandClaude Opus 5 2a9e59357e 初始化 360 全景影片播放器專案並完成 NAS 部署設定
摘要:
將本機開發的 360° 全景影片播放器納入版控,同時把執行環境從 Windows
切換到 Synology NAS,改以 Docker 部署。

根本原因:
專案原本只在有 NVIDIA 顯卡的 Windows 機器上跑,config.json 寫死了
Windows 磁碟機路徑 W:/photo/Badminton,NAS 上無法直接啟動。
另外 DSM 內建的 ffmpeg 拿掉了 VAAPI 編碼器,裸跑只能走 libx264,
Celeron J4025 雙核轉 4K 360 影片的速度無法接受。

影響:
- 在 NAS 上 npm start 會因為找不到影片資料夾而列不出任何影片
- 即使把路徑改對,轉檔仍只能用 CPU,82 分鐘的 4K 360 影片要跑十幾小時

修法:
- config.json 的 videoDir 改為 NAS 實際路徑 /volume1/photo/Badminton
- docker-compose.yml 啟用 devices: /dev/dri,讓容器取得 Intel UHD 600
  的 render node;容器內 Alpine 版 ffmpeg 保有完整 VAAPI 支援,啟動時
  會自動偵測成 vaapi 模式,並保留 libx264 當備援
- .env(不進版控)提供 VIDEO_DIR / CACHE_DIR 等 NAS 路徑給 compose 使用

驗證:
容器啟動 log 顯示「轉檔引擎:VAAPI 硬體編碼(Intel/AMD,/dev/dri)」,
/api/config 回傳 modes: ["vaapi","cpu"],/api/videos 正確辨識來源影片為
3840x1920 equirectangular。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-21 10:57:17 +08:00

124 lines
5.7 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.
# 360 Player
在瀏覽器裡播放 360° 全景影片的本機網頁播放器。
從下拉選單挑選 `W:\photo\Badminton` 裡的影片、選擇播放畫質;低畫質版本由 ffmpeg(NVIDIA NVENC)轉出並快取在本機。
## 啟動
```bash
npm install # 第一次
npm start # 或 node server.js
```
啟動後終端機會列出網址,例如 `http://localhost:8360`;同一區網的其他裝置(手機、平板)可用列出的 `http://192.168.x.x:8360` 連線。
需求:Node.js 18+、`ffmpeg` / `ffprobe` 在 PATH 裡(轉檔用)。有 NVIDIA 顯卡時自動使用 NVDEC + NVENC,沒有就退回 CPUlibx264)。
## 操作
| 動作 | 滑鼠 / 觸控 | 鍵盤 |
|---|---|---|
| 環視 | 拖曳 | ← → ↑ ↓ |
| 縮放(視角) | 滾輪 / 雙指 | `+` `-` |
| 播放 / 暫停 | 點一下畫面 | `空白鍵` / `K` |
| 快退 / 快進 10 秒 | — | `J` / `L` |
| 逐格 | — | `,` / `.` |
| 全螢幕 | 雙擊畫面 | `F` |
| 靜音 | — | `M` |
| 重置視角 | ⌖ 按鈕 | `0` |
- 上方「360° / 平面」按鈕可手動切換投影方式(影片沒有 360 metadata 但是 2:1 比例時會自動判斷為 360)。
- 每部影片的播放位置、偏好畫質、音量都會記住。
## 畫質與轉檔
「畫質」下拉選單列出原始檔與 `config.json` 裡定義的每一級畫質:
- 已轉檔的畫質會顯示 ✓ 與檔案大小,選取後立即切換(保留目前播放進度)。
- 尚未轉檔的畫質選取後會**加入轉檔佇列**,完成時畫面會跳出通知與「切換」按鈕。
- 「轉檔」面板可以看進度(fps、速度、剩餘時間)、取消、刪除已轉檔檔案,
以及**「一次轉出全部畫質」**:來源只讀一次就同時輸出全部畫質。
> 來源放在網路磁碟(例如 RaiDrive)時,讀取速度通常才是瓶頸,
> 而不是 GPU。這種情況下請用「一次轉出全部畫質」,時間和只轉一種幾乎相同。
轉檔輸出:H.264 + AAC、`faststart`(moov 在檔頭,可立即開播、順暢拖動),
並重新寫入 Spherical Video V1 metadata,所以用 VLC / YouTube 開也會被認成 360 影片。
轉出的檔案放在 `cache/`,檔名 `<原檔名>__<畫質id>.mp4`;來源檔案變動(大小或修改時間改變)時會自動視為過期並重轉。
## 部署到 NASDocker
映像檔以 `node:22-alpine` 為基礎,內含 ffmpeg;影片資料夾與快取都用 volume 掛進容器:
| 容器內路徑 | 用途 | 對應環境變數 |
|---|---|---|
| `/videos` | 影片資料夾(唯讀) | `VIDEO_DIR` |
| `/cache` | 轉檔輸出與 probe 快取(需可寫) | `CACHE_DIR` |
```bash
# 1. 把整個專案資料夾複製到 NAS,例如 /volume1/docker/360_player
# 2. 建立 .env,填 NAS 上的實際路徑
cp .env.example .env && vi .env
# 3. 建置並啟動
docker compose up -d --build
# 4. 瀏覽器開 http://NAS-IP:8360
```
Synology Container Manager:「專案」→「新增」→ 選這個資料夾,它會讀取 `docker-compose.yml`
環境變數可在「環境」分頁填(等同 `.env`)。
**NAS 上轉檔速度**
- 沒有 GPU 時走 `libx264`CPU)。NAS 的 CPU 把 4K 360 影片同時轉成三種畫質大約只有個位數 fps,
82 分鐘的影片可能要跑 5–10 小時(可在背景跑,轉檔面板會顯示剩餘時間)。
CPU 很弱可把 `.env``X264_PRESET` 改成 `superfast``ultrafast`
- NAS 有 Intel 內顯時,把 `docker-compose.yml``devices: /dev/dri` 兩行取消註解,
啟動時會自動偵測並改用 VAAPI 硬體編碼(此路徑尚未在實機驗證,偵測失敗會自動退回 CPU)。
- **最快的做法**:在有 NVIDIA 顯卡的電腦上先跑 `npm start` 轉完,再把 `cache/` 裡的
`*.mp4``*.mp4.json` 複製到 NAS 的 `CACHE_DIR`。快取檔只認來源檔的大小與修改時間(容許 2 秒誤差),
所以兩邊看到同一個檔案就能直接共用。
## 設定(`config.json`
```json
{
"port": 8360,
"host": "0.0.0.0",
"videoDir": "W:/photo/Badminton",
"cacheDir": "./cache",
"extensions": [".mp4", ".mov", ".m4v", ".webm"],
"qualities": [
{ "id": "2560", "label": "高", "width": 2560, "bitrate": "10M", "maxrate": "13M" },
{ "id": "1920", "label": "中", "width": 1920, "bitrate": "5M", "maxrate": "7M" },
{ "id": "1280", "label": "低", "width": 1280, "bitrate": "2.5M", "maxrate": "3.5M" }
]
}
```
- `qualities`:每一級只要給寬度,高度依原始比例計算;比原始影片寬的級別會自動略過。
可加 `"nvencPreset": "p6"` 之類的欄位調整 NVENC 預設(預設 `p4`)。
- 環境變數:`PORT=9000` 覆寫埠號;`CONFIG=other.json` 使用另一份設定;`LOG_STREAM=0` 關閉串流請求 log。
## API(給進階使用)
| 方法 | 路徑 | 說明 |
|---|---|---|
| GET | `/api/videos` | 影片清單(含 ffprobe 資訊、各畫質狀態) |
| GET | `/stream/:name?q=original\|<畫質id>` | 影片串流(支援 Range) |
| POST | `/api/transcode` | `{ "name", "quality" }` / `{ "name", "qualities": [] }` / `{ "name", "all": true }` |
| GET | `/api/jobs` | 轉檔工作 |
| DELETE | `/api/jobs/:id` | 取消工作 |
| DELETE | `/api/jobs/finished` | 清除已完成 |
| DELETE | `/api/variant?name=&quality=` | 刪除轉檔檔案 |
| GET | `/api/events` | Server-Sent Events`jobs`(進度)、`finished` |
## 專案結構
```
server.js Express:清單、Range 串流、轉檔 API、SSE
lib/probe.js ffprobe 包裝 + 永續快取(含 360 metadata 判斷)
lib/transcode.js ffmpeg 工作佇列(一次解碼多輸出;CUDA → NVENC → CPU 備援)
lib/spherical.js 把 Spherical Video V1 metadata 注回 MP4
public/ 前端(Three.js 球體貼圖播放器)
cache/ 轉檔輸出與 probe 快取(已 gitignore
```