Files
momentry_core/docs/JSON_OUTPUT_SPEC.md
accusys 383201cacd feat: Initial v0.9 release with API Key authentication
## v0.9.20260325_144654

### Features
- API Key Authentication System
- Job Worker System
- V2 Backup Versioning

### Bug Fixes
- get_processor_results_by_job column mapping

Co-authored-by: OpenCode
2026-03-25 14:53:41 +08:00

13 KiB
Raw Blame History

Momentry JSON 輸出檔案規範

項目 內容
建立者 Warren
建立時間 2026-03-16
文件版本 V1.0

版本歷史

版本 日期 目的 操作人 工具/模型
V1.0 2026-03-16 創建文件 Warren OpenCode / MiniMax M2.5

本文檔定義 Momentry Core 系統中所有 JSON 輸出檔案的結構、命名規範與儲存位置。


1. 輸出檔案總覽

1.1 檔案類型

類型 前綴 說明 狀態
Probe {uuid}.probe.json 影片元數據 已實作
ASR {uuid}.asr.json 語音識別結果 已實作
ASRx {uuid}.asrx.json 說話者分離 🔜 規劃中
OCR {uuid}.ocr.json 文字辨識結果 🔜 規劃中
YOLO {uuid}.yolo.json 物件偵測結果 🔜 規劃中
Face {uuid}.face.json 人臉偵測結果 🔜 規劃中
Pose {uuid}.pose.json 姿態估計結果 🔜 規劃中
Thumbnail {uuid}/thumb_XXX.jpg 縮圖檔案 已實作

1.2 命名規範

{UUID}.{類型}.json

範例:
1636719dc31f78ac.probe.json  - 影片探測結果
1636719dc31f78ac.asr.json   - 語音識別結果
1636719dc31f78ac.ocr.json    - 文字辨識結果
  • UUID: 16 字元,基於檔案路徑計算
  • 類型: 小寫 snake_case
  • 副檔名: .json

2. 輸出目錄結構

2.1 預設輸出位置

momentry_core_0.1/
├── {uuid}.probe.json          # 影片探測
├── {uuid}.asr.json           # 語音識別
├── {uuid}.asrx.json         # 說話者分離
├── {uuid}.ocr.json           # 文字辨識
├── {uuid}.yolo.json          # 物件偵測
├── {uuid}.face.json          # 人臉偵測
├── {uuid}.pose.json          # 姿態估計
└── thumbnails/
    └── {uuid}/
        ├── thumb_000.jpg
        ├── thumb_001.jpg
        └── ...

2.2 儲存策略

資料類型 儲存位置 說明
JSON 檔案 專案根目錄 方便快速存取
縮圖 thumbnails/{uuid}/ 分離儲存
資料庫 PostgreSQL 長期儲存

3. JSON 結構定義

3.1 Probe (影片探測)

檔案: {uuid}.probe.json

{
  "streams": [
    {
      "index": 0,
      "codec_name": "h264",
      "codec_type": "video",
      "width": 1920,
      "height": 1080,
      "r_frame_rate": "60000/1001",
      "duration": "6879.329524",
      "sample_rate": null,
      "channels": null
    },
    {
      "index": 1,
      "codec_name": "aac",
      "codec_type": "audio",
      "width": null,
      "height": null,
      "r_frame_rate": "0/0",
      "duration": "6879.245333",
      "sample_rate": "48000",
      "channels": 2
    }
  ],
  "format": {
    "filename": "/path/to/video.mov",
    "format_name": "mov,mp4,m4a,3gp,3g2,mj2",
    "duration": "6879.329524",
    "size": "2361629896",
    "bit_rate": "2748000"
  }
}

欄位說明:

欄位 類型 說明
streams Array 媒體串流陣列
streams[].index Integer 串流索引
streams[].codec_name String 編碼名稱
streams[].codec_type String 串流類型 (video/audio)
streams[].width Integer 寬度 (video)
streams[].height Integer 高度 (video)
streams[].r_frame_rate String 幀率
streams[].duration String 持續時間 (秒)
streams[].sample_rate String 採樣率 (audio)
streams[].channels Integer 聲道數 (audio)
format Object 檔案格式資訊
format.filename String 原始檔案路徑
format.format_name String 格式名稱
format.duration String 總時長 (秒)
format.size String 檔案大小 (bytes)
format.bit_rate String 位元率

3.2 ASR (語音識別)

檔案: {uuid}.asr.json

{
  "language": "en",
  "language_probability": 0.9945855736732483,
  "segments": [
    {
      "start": 0.0,
      "end": 19.04,
      "text": "Hello and welcome to the old-time movie show."
    },
    {
      "start": 19.04,
      "end": 25.44,
      "text": "Today we are featuring the 1963 comedy mystery film Charade."
    }
  ]
}

欄位說明:

欄位 類型 說明
language String 偵測語言代碼 (ISO 639-1)
language_probability Float 語言偵測機率 (0-1)
segments Array 語音分段陣列
segments[].start Float 開始時間 (秒)
segments[].end Float 結束時間 (秒)
segments[].text String 識別文字

3.3 ASRx (說話者分離)

檔案: {uuid}.asrx.json

{
  "language": "en",
  "language_probability": 0.95,
  "segments": [
    {
      "start": 0.0,
      "end": 19.04,
      "text": "Hello and welcome to the old-time movie show.",
      "speaker_id": "SPEAKER_00",
      "speaker_embedding": [0.123, -0.456, ...]
    },
    {
      "start": 19.04,
      "end": 25.44,
      "text": "Today we are featuring the 1963 comedy mystery film Charade.",
      "speaker_id": "SPEAKER_01",
      "speaker_embedding": [0.789, -0.123, ...]
    }
  ]
}

欄位說明:

欄位 類型 說明
language String 偵測語言代碼
language_probability Float 語言偵測機率
segments Array 語音分段陣列
segments[].start Float 開始時間 (秒)
segments[].end Float 結束時間 (秒)
segments[].text String 識別文字
segments[].speaker_id String 說話者 ID
segments[].speaker_embedding Array 說話者嵌入向量 (可選)

3.4 OCR (文字辨識)

檔案: {uuid}.ocr.json

{
  "segments": [
    {
      "start": 10.5,
      "end": 12.3,
      "text": "EXAMPLE TEXT",
      "boxes": [
        {
          "x1": 100,
          "y1": 50,
          "x2": 400,
          "y2": 100
        }
      ],
      "confidence": 0.95
    }
  ]
}

欄位說明:

欄位 類型 說明
segments Array OCR 分段陣列
segments[].start Float 開始時間 (秒)
segments[].end Float 結束時間 (秒)
segments[].text String 辨識文字
segments[].boxes Array 文字邊界框陣列
segments[].boxes[].x1 Integer 左上 X 座標
segments[].boxes[].y1 Integer 左上 Y 座標
segments[].boxes[].x2 Integer 右下 X 座標
segments[].boxes[].y2 Integer 右下 Y 座標
segments[].confidence Float 辨識信心度

3.5 YOLO (物件偵測)

檔案: {uuid}.yolo.json

{
  "segments": [
    {
      "start": 0.0,
      "end": 1.0,
      "objects": [
        {
          "class": "person",
          "confidence": 0.92,
          "box": {
            "x1": 150,
            "y1": 200,
            "x2": 400,
            "y2": 800
          }
        },
        {
          "class": "car",
          "confidence": 0.87,
          "box": {
            "x1": 800,
            "y1": 400,
            "x2": 1200,
            "y2": 700
          }
        }
      ]
    }
  ]
}

欄位說明:

欄位 類型 說明
segments Array 時間分段陣列
segments[].start Float 開始時間 (秒)
segments[].end Float 結束時間 (秒)
segments[].objects Array 偵測物件陣列
segments[].objects[].class String 物件類別
segments[].objects[].confidence Float 偵測信心度
segments[].objects[].box Object 邊界框

3.6 Face (人臉偵測)

檔案: {uuid}.face.json

{
  "segments": [
    {
      "start": 0.0,
      "end": 1.0,
      "faces": [
        {
          "face_id": "face_001",
          "box": {
            "x1": 100,
            "y1": 50,
            "x2": 300,
            "y2": 350
          },
          "embedding": [0.123, -0.456, ...],
          "emotion": "happy",
          "age": 35,
          "gender": "female"
        }
      ]
    }
  ]
}

欄位說明:

欄位 類型 說明
segments Array 時間分段陣列
segments[].start Float 開始時間 (秒)
segments[].end Float 結束時間 (秒)
segments[].faces Array 人臉陣列
segments[].faces[].face_id String 人臉 ID
segments[].faces[].box Object 邊界框
segments[].faces[].embedding Array 人臉嵌入向量
segments[].faces[].emotion String 情緒分類 (可選)
segments[].faces[].age Integer 年齡估計 (可選)
segments[].faces[].gender String 性別估計 (可選)

3.7 Pose (姿態估計)

檔案: {uuid}.pose.json

{
  "segments": [
    {
      "start": 0.0,
      "end": 1.0,
      "poses": [
        {
          "person_id": "person_001",
          "keypoints": {
            "nose": {"x": 320, "y": 120, "confidence": 0.98},
            "left_eye": {"x": 335, "y": 110, "confidence": 0.95},
            "right_eye": {"x": 305, "y": 110, "confidence": 0.93},
            "left_shoulder": {"x": 280, "y": 180, "confidence": 0.91},
            "right_shoulder": {"x": 360, "y": 180, "confidence": 0.89}
          },
          "confidence": 0.92
        }
      ]
    }
  ]
}

欄位說明:

欄位 類型 說明
segments Array 時間分段陣列
segments[].start Float 開始時間 (秒)
segments[].end Float 結束時間 (秒)
segments[].poses Array 姿態陣列
segments[].poses[].person_id String 人員 ID
segments[].poses[].keypoints Object 關鍵點
segments[].poses[].keypoints.{name} Object 各關鍵點
segments[].poses[].keypoints.{name}.x Integer X 座標
segments[].poses[].keypoints.{name}.y Integer Y 座標
segments[].poses[].keypoints.{name}.confidence Float 信心度
segments[].poses[].confidence Float 整體信心度

4. 處理流程

4.1 處理管線

影片檔案
    │
    ▼
┌─────────────────┐
│  1. Register    │  建立 UUID註冊影片
└────────┬────────┘
         │
    ┌────▼────┐
    │ 2. Probe │  ffprobe 擷取元數據
    └────┬────┘
         │ {uuid}.probe.json
    ┌────▼─────┐
    │ 3. ASR   │  faster-whisper 語音識別
    └────┬─────┘
         │ {uuid}.asr.json
    ┌────▼──────┐
    │ 4. ASRx   │  說話者分離 (pyannote)
    └────┬──────┘
         │ {uuid}.asrx.json
    ┌────▼────┐
    │ 5. OCR   │  Tesseract 文字辨識
    └────┬────┘
         │ {uuid}.ocr.json
    ┌────▼────┐
    │ 6. YOLO │  物件偵測
    └────┬────┘
         │ {uuid}.yolo.json
    ┌────▼────┐
    │ 7. Face │  人臉偵測
    └────┬────┘
         │ {uuid}.face.json
    ┌────▼────┐
    │ 8. Pose │  姿態估計
    └────┬────┘
         │ {uuid}.pose.json
    ┌────▼──────┐
    │ 9. Chunk  │  轉換為資料庫 chunks
    └───────────┘

4.2 失敗處理

階段 失敗時 處理
Probe 無法讀取影片 終止流程,輸出錯誤
ASR 無音軌 產生空 segments繼續流程
OCR/YOLO/Face/Pose 處理失敗 跳過該階段,記錄日誌

5. 資料庫儲存

5.1 Chunk 結構

CREATE TABLE chunks (
    id BIGSERIAL PRIMARY KEY,
    uuid VARCHAR(16) NOT NULL,
    chunk_id VARCHAR(64) NOT NULL,
    chunk_index INTEGER NOT NULL,
    chunk_type VARCHAR(32) NOT NULL,
    start_time DOUBLE PRECISION NOT NULL,
    end_time DOUBLE PRECISION NOT NULL,
    content JSONB NOT NULL,
    created_at TIMESTAMP DEFAULT NOW(),
    UNIQUE(uuid, chunk_id)
);

5.2 轉換範例

// ASR → Chunk (Sentence)
for (i, seg) in asr_result.segments.iter().enumerate() {
    let chunk = Chunk::new(
        uuid.clone(),
        i as u32,
        ChunkType::Sentence,
        seg.start,
        seg.end,
        serde_json::json!({"text": seg.text}),
    );
    db.store_chunk(&chunk).await?;
}

6. 版本歷史

版本 日期 變更
1.0.0 2026-03-16 初始版本

7. 相關文件