diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..219133a --- /dev/null +++ b/.gitignore @@ -0,0 +1,23 @@ +__pycache__/ +*.pyc +*.pyo +*.pyd +.Python +env/ +venv/ +.env +*.log +*.log.* +*.pid +*.seed +*.pid.lock +coverage/ +.nyc_output/ +.pytest_cache/ +.mypy_cache/ +.idea/ +.vscode/ +*.swp +*.swo +*~ +.DS_Store diff --git a/README.md b/README.md new file mode 100644 index 0000000..a8bcf2e --- /dev/null +++ b/README.md @@ -0,0 +1,84 @@ +# verify-delivery-service + +KTV产线交付质检HTTP服务 — 4项QA检查 + +## 服务说明 + +将KTV产线的交付质检流程封装为HTTP服务,提供统一的质检入口。 + +### 4项QA检查 + +1. **QA1 字幕时间精准性** — 时间单调递增、无重叠、无gap>2s +2. **QA2 字幕歌词正确性** — ASS中歌词与原始歌词逐行比对 +3. **QA3 MTV使用原音频** — 单轨、duration匹配原曲 +4. **QA4 KTV双轨音序** — Track1=伴奏(Accompaniment), Track2=原唱(Original) + +## 部署 + +```bash +git clone git@git.opencomputing.cn:yumoqing/verify_delivery.git +cd verify_delivery +chmod +x start.sh stop.sh +./start.sh +``` + +服务运行在 `http://0.0.0.0:9085` + +## API端点 + +### GET /api/status +服务状态检查 + +### POST /api/submit +提交质检任务 + +参数: +- `mtv_path`: MTV视频路径(可选) +- `ktv_path`: KTV视频路径(可选) +- `ass_path`: ASS字幕路径(可选) +- `lyrics_path`: 原始歌词路径(可选) +- `calibrated_path`: calibrated.json路径(可选,用于QA1) +- `original_duration`: 原曲时长(秒,可选) + +返回: +```json +{ + "status": "submitted", + "task_id": "xxx", + "message": "质检任务已提交" +} +``` + +### GET /api/task?task_id=xxx +查询质检任务结果 + +返回: +```json +{ + "task_id": "xxx", + "status": "completed", + "result": { + "status": "PASSED", + "qa_results": { + "QA1_timeline": {"passed": true, "errors": []}, + "QA2_lyrics": {"passed": true, "errors": []}, + "QA3_mtv": {"passed": true, "errors": []}, + "QA4_ktv": {"passed": true, "errors": []} + }, + "total_errors": 0, + "errors": [] + } +} +``` + +## 技术栈 + +- ahserver (ahserver.webapp) +- longtasks (异步任务队列) +- ffprobe (视频/音频元数据提取) +- Python 3.10 + +## Git仓库 + +- 远端:`git@git.opencomputing.cn:yumoqing/verify_delivery.git` +- 本地:`~/test/verify-delivery-service/` diff --git a/app/api/status.dspy b/app/api/status.dspy new file mode 100644 index 0000000..fb6ee90 --- /dev/null +++ b/app/api/status.dspy @@ -0,0 +1,9 @@ +# -*- coding: utf-8 -*- +import json +result = { + "service": "verify-delivery", + "status": "running", + "checks": ["QA1_timeline", "QA2_lyrics", "QA3_mtv", "QA4_ktv"], + "description": "KTV产线交付质检服务 — 4项QA检查" +} +return json.dumps(result, ensure_ascii=False, indent=2) diff --git a/app/api/submit.dspy b/app/api/submit.dspy new file mode 100644 index 0000000..b09338d --- /dev/null +++ b/app/api/submit.dspy @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +import json + +mtv_path = params.get("mtv_path", "") +ktv_path = params.get("ktv_path", "") +ass_path = params.get("ass_path", "") +lyrics_path = params.get("lyrics_path", "") +calibrated_path = params.get("calibrated_path", "") +original_duration = params.get("original_duration", 0) + +if not any([mtv_path, ktv_path]): + result = {"error": "至少需要提供mtv_path或ktv_path"} + return json.dumps(result, ensure_ascii=False) + +payload = { + "mtv_path": mtv_path, + "ktv_path": ktv_path, + "ass_path": ass_path, + "lyrics_path": lyrics_path, + "calibrated_path": calibrated_path, + "original_duration": original_duration +} + +task_id = longtasks.submit_task(payload) +result = { + "status": "submitted", + "task_id": task_id, + "message": "质检任务已提交,请用 /api/task?task_id=" + str(task_id) + " 查询结果" +} +return json.dumps(result, ensure_ascii=False, indent=2) diff --git a/app/api/task.dspy b/app/api/task.dspy new file mode 100644 index 0000000..5433b04 --- /dev/null +++ b/app/api/task.dspy @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- +import json + +task_id = params.get("task_id", "") +if not task_id: + result = {"error": "缺少 task_id 参数"} + return json.dumps(result, ensure_ascii=False) + +status = longtasks.get_status(task_id) +result = longtasks.get_result(task_id) + +output = { + "task_id": task_id, + "status": status, + "result": result +} +return json.dumps(output, ensure_ascii=False, indent=2) diff --git a/conf/config.json b/conf/config.json new file mode 100644 index 0000000..61efaf3 --- /dev/null +++ b/conf/config.json @@ -0,0 +1,9 @@ +{ + "website": { + "processors": [[".dspy", "dspy"]], + "port": 9085, + "host": "0.0.0.0", + "static_paths": [], + "index_pages": ["index.dspy"] + } +} diff --git a/start.sh b/start.sh new file mode 100644 index 0000000..6724cfa --- /dev/null +++ b/start.sh @@ -0,0 +1,5 @@ +#!/bin/bash +cd "$(dirname "$0")" +nohup /data/ymq/wan22-service/py3/bin/python ah.py > service.log 2>&1 & +echo $! > service.pid +echo "verify-delivery-service started, PID: $!" diff --git a/stop.sh b/stop.sh new file mode 100644 index 0000000..8c39d1d --- /dev/null +++ b/stop.sh @@ -0,0 +1,14 @@ +#!/bin/bash +cd "$(dirname "$0")" +if [ -f service.pid ]; then + pid=$(cat service.pid) + if kill -0 $pid 2>/dev/null; then + kill $pid + echo "verify-delivery-service stopped, PID: $pid" + else + echo "Process $pid not running" + fi + rm -f service.pid +else + echo "service.pid not found" +fi