# Momentry Chunk 資料結構說明 > **對象**: marcom 團隊 > **版本**: V1.0 | **日期**: 2026-03-25 --- ## 1. 什麼是 Chunk? Chunk(片段)是影片處理後的最小單位。當影片上傳後,系統會自動: 1. **分析** - 偵測場景、人臉、姿態 2. **轉換** - 語音轉文字(ASR) 3. **分段** - 將內容切割成可搜尋的片段 4. **向量化** - 產生可搜尋的特徵向量 每個 Chunk 就是一個**可獨立搜尋的內容單位**。 --- ## 2. Chunk 資料結構 ### 2.1 主要欄位 | 欄位名 | 類型 | 說明 | 範例 | |--------|------|------|------| | `uuid` | 字串 (32) | 影片唯一識別碼 | `952f5854b9febad1` | | `chunk_id` | 字串 (64) | Chunk 唯一識別碼 | `asr_00001` | | `chunk_index` | 整數 | Chunk 順序號碼 | `1` | | `chunk_type` | 字串 (32) | Chunk 類型 | `sentence` | | `start_time` | 浮點數 | 開始時間(秒) | `12.5` | | `end_time` | 浮點數 | 結束時間(秒) | `18.3` | | `content` | JSONB | 詳細內容 | 見下方 | | `vector_id` | 字串 (64) | 向量 ID | `vec_12345` | | `text_content` | 文字 | 純文字內容 | `這是一段話` | | `fps` | 浮點數 | 影片幀率 | `24.0` | | `start_frame` | 整數 | 開始幀數 | `300` | | `end_frame` | 整數 | 結束幀數 | `439` | | `frame_count` | 整數 | 總幀數 | `139` | ### 2.2 Chunk 類型說明 | 類型 | ID | 說明 | 來源處理器 | |------|-----|------|-----------| | `sentence` | `sentence` | 語音轉文字片段 | ASR 處理 | | `time` | `time_based` | 固定時間分段 | 系統自動切割 | | `cut` | `cut` | 場景變化片段 | CUT 處理 | | `trace` | `trace` | 軌跡追蹤片段 | YOLO 追蹤處理 | | `story` | `story` | 故事線片段(父子區塊) | Story 分析處理 | **父子區塊關係**: - `story` 是**父區塊**,可包含多個 `sentence`、`cut`、`trace` 子區塊 - 透過 `parent_chunk_id` 和 `child_chunk_ids` 建立階層關係 --- ## 3. Content JSON 結構 每個 Chunk 的 `content` 欄位包含詳細的處理結果: ### 3.1 ASR Chunk(語音轉文字) ```json { "text": "今天天氣非常好,我們去郊外踏青吧", "words": [ { "word": "今天", "start": 12.5, "end": 12.8, "confidence": 0.95 }, { "word": "天氣", "start": 12.8, "end": 13.1, "confidence": 0.92 } ], "language": "zh-TW", "speaker": null } ``` ### 3.2 Cut Chunk(場景偵測) ```json { "scenes": [ { "scene_id": "cut_001", "start_time": 12.5, "end_time": 45.2, "transition": "cut", "confidence": 0.98 } ] } ``` ### 3.3 Trace Chunk(軌跡追蹤) ```json { "track_id": "track_001", "object_class": "person", "frames": [ { "frame": 300, "bbox": [120, 80, 200, 300], "confidence": 0.95 }, { "frame": 301, "bbox": [122, 82, 202, 302], "confidence": 0.94 } ], "total_frames": 180 } ``` ### 3.4 Story Chunk(故事線) ```json { "story_id": "story_001", "title": "開場介紹", "summary": "主持人介紹節目主題", "child_chunk_ids": ["sentence_00001", "sentence_00002", "cut_00001"], "tags": ["intro", "host"] } ``` ### 3.5 Metadata(其他偵測資訊) 人臉(Face)、文字辨識(OCR)、姿態(Pose)等偵測結果會附加在 `metadata` 欄位: ```json { "metadata": { "faces": [ { "bbox": [120, 80, 200, 180], "confidence": 0.87, "emotion": "neutral" } ], "ocr": { "text": "MOMENTRY", "confidence": 0.96 }, "pose": { "keypoints": [ {"name": "nose", "x": 192, "y": 85, "confidence": 0.95} ] } } } ``` --- ## 4. 時間格式說明 ### 4.1 秒數格式(常用) ``` 格式: 秒.幀數 範例: 1234.60 = 第 1234 秒 + 第 60 幀 ``` ### 4.2 時間軸格式 ``` 格式: HH:MM:SS.FF 範例: 00:20:34.12 = 20分34秒12幀 ``` ### 4.3 幀數計算 ``` 幀數 = 秒數 × fps 例如: 12.5秒 × 24fps = 300幀 ``` --- ## 5. 實際資料範例 假設有一個影片,包含以下處理結果: ### 5.1 語音片段 ```json { "uuid": "952f5854b9febad1", "chunk_id": "asr_00001", "chunk_type": "sentence", "start_time": 12.5, "end_time": 18.3, "content": { "text": "今天天氣非常好,我們去郊外踏青吧", "language": "zh-TW" }, "text_content": "今天天氣非常好,我們去郊外踏青吧", "start_frame": 300, "end_frame": 439, "fps": 24.0 } ``` ### 5.2 場景片段 ```json { "uuid": "952f5854b9febad1", "chunk_id": "cut_00001", "chunk_type": "cut", "start_time": 45.0, "end_time": 120.5, "content": { "scenes": [{ "scene_id": "cut_001", "transition": "cut", "confidence": 0.98 }] }, "start_frame": 1080, "end_frame": 2892, "fps": 24.0 } ``` --- ## 6. 如何使用 Chunk ### 6.1 API 取得 Chunk 使用搜尋 API 取得 Chunk: ```bash curl -X POST "https://api.momentry.ddns.net/api/v1/search" \ -H "X-API-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "query": "關鍵字", "limit": 10 }' ``` **指定影片搜尋**: ```bash curl -X POST "https://api.momentry.ddns.net/api/v1/search" \ -H "X-API-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "query": "關鍵字", "uuid": "39567a0eb16f39fd", "limit": 5 }' ``` ### 6.2 搜尋相關片段 當使用者搜尋「天氣」時,系統會: 1. 將「天氣」轉換為向量 2. 在向量資料庫中搜尋相似向量 3. 找到相關的 Chunk 4. 返回時間軸和內容 ### 6.3 播放指定片段 取得 Chunk 後可播放: ``` 開始時間: 12.5 秒 結束時間: 18.3 秒 影片 UUID: 39567a0eb16f39fd ``` **播放器連結格式**: ``` /player?uuid={uuid}&start={start_time}&end={end_time} ``` ### 6.4 組合多個 Chunk 多個相關 Chunk 可以組合成一個章節或故事線。 ### 6.5 Story Chunk(父子關係) Story Chunk 可包含多個子 Chunk: ```json { "chunk_id": "story_001", "chunk_type": "story", "content": { "story_id": "story_001", "title": "開場介紹", "child_chunk_ids": ["sentence_00001", "sentence_00002", "cut_00001"] } } ``` --- ## 7. API 回應格式 ### /search 回應 ```json { "results": [ { "uuid": "39567a0eb16f39fd", "chunk_id": "sentence_1471", "chunk_type": "sentence", "start_time": 5309.08, "end_time": 5311.08, "text": "influenced by a vital way,", "score": 0.68 } ], "query": "關鍵字" } ``` ### /n8n/search 回應 ```json { "query": "關鍵字", "count": 1, "hits": [ { "id": "sentence_1471", "vid": "39567a0eb16f39fd", "start": 5309.08, "end": 5311.08, "title": "Chunk sentence_1471", "text": "influenced by a vital way,", "score": 0.68, "file_path": "/Users/accusys/momentry/var/sftpgo/data/demo/video.mp4" } ] } ``` > **注意**: `file_path` 是影片的實際路徑,可用於本地播放。 --- ## 8. 快速參考 | 項目 | 說明 | |------|------| | UUID | 影片唯一識別碼(16位 hex) | | Chunk ID | 片段識別碼(如 `sentence_00001`) | | chunk_type | 片段類型(sentence/time/cut/trace/story) | | start_time | 開始時間(秒) | | end_time | 結束時間(秒) | | text_content | 純文字內容 | | content | 詳細 JSON 結構 | | metadata | 人臉、OCR、姿態等偵測結果 | | parent_chunk_id | 父區塊 ID(用於 story 區塊) | | child_chunk_ids | 子區塊 ID 列表(story 區塊專用) | | --- ## 附錄:版本歷史 | 版本 | 日期 | 內容 | 操作人 | |------|------|------|--------| | V1.0 | 2026-03-25 | 初版建立 | OpenCode | | V1.1 | 2026-03-25 | 新增 API 取得 Chunk 方式、播放連結格式 | OpenCode |