docs: expand usage guide and localize csv output
This commit is contained in:
@@ -15,6 +15,38 @@ class ReportRow:
|
||||
size: int
|
||||
|
||||
|
||||
FINAL_STATUS_ZH: dict[str, str] = {
|
||||
"confirmed_broken": "明确损坏",
|
||||
"suspicious": "可疑",
|
||||
"passed_stage1": "第一轮通过",
|
||||
"passed_stage2": "第二轮通过",
|
||||
"skipped": "已跳过",
|
||||
"command_error": "命令异常",
|
||||
}
|
||||
|
||||
|
||||
REASON_CODE_ZH: dict[str, str] = {
|
||||
"ffprobe_exit_nonzero": "ffprobe 返回非零退出码,通常表示容器或头部校验失败",
|
||||
"ffmpeg_exit_nonzero": "ffmpeg 返回非零退出码,通常表示采样或解码失败",
|
||||
"invalid_nal_unit_size": "视频流 NAL 单元尺寸异常,常见于截断文件",
|
||||
"truncating_packet": "视频包被截断,常见于下载中断或文件不完整",
|
||||
"decode_slice_header_error": "视频切片头解析失败,通常表示码流损坏",
|
||||
"corrupt_input_packet": "输入数据包损坏,码流存在明显异常",
|
||||
"hard_error_keyword": "命中高置信度损坏错误关键词",
|
||||
"soft_warning_keyword": "命中软告警关键词,因此升级到第二轮验证",
|
||||
"missing_video_stream": "没有检测到视频流",
|
||||
"missing_format_name": "无法识别容器格式",
|
||||
"invalid_duration": "时长字段异常,因此升级到第二轮验证",
|
||||
"high_risk_extension": "高风险扩展名,因此升级到第二轮验证",
|
||||
"passed_stage1": "容器级快速校验通过",
|
||||
"passed_stage2": "第二轮采样或确认校验通过",
|
||||
"command_error": "外部命令执行异常",
|
||||
"missing_command": "缺少 ffprobe 或 ffmpeg 外部命令",
|
||||
"invalid_probe_output": "ffprobe 输出不是可解析的 JSON",
|
||||
"timeout": "命令执行超时",
|
||||
}
|
||||
|
||||
|
||||
def summarize_reason_counts(rows: list[ReportRow]) -> dict[str, int]:
|
||||
summary: dict[str, int] = {}
|
||||
for row in rows:
|
||||
@@ -44,18 +76,35 @@ def export_jsonl(rows: list[ReportRow], destination: Path) -> None:
|
||||
|
||||
|
||||
def export_csv_summary(rows: list[ReportRow], destination: Path) -> None:
|
||||
with destination.open("w", encoding="utf-8", newline="") as handle:
|
||||
with destination.open("w", encoding="utf-8-sig", newline="") as handle:
|
||||
writer = csv.DictWriter(
|
||||
handle,
|
||||
fieldnames=["final_status", "reason_code", "path", "size"],
|
||||
fieldnames=[
|
||||
"final_status",
|
||||
"final_status_zh",
|
||||
"reason_code",
|
||||
"reason_code_zh",
|
||||
"path",
|
||||
"size",
|
||||
],
|
||||
)
|
||||
writer.writeheader()
|
||||
for row in rows:
|
||||
writer.writerow(
|
||||
{
|
||||
"final_status": row.final_status,
|
||||
"final_status_zh": describe_final_status_zh(row.final_status),
|
||||
"reason_code": row.reason_code,
|
||||
"reason_code_zh": describe_reason_code_zh(row.reason_code),
|
||||
"path": str(row.path),
|
||||
"size": row.size,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def describe_final_status_zh(status: str) -> str:
|
||||
return FINAL_STATUS_ZH.get(status, status)
|
||||
|
||||
|
||||
def describe_reason_code_zh(reason_code: str) -> str:
|
||||
return REASON_CODE_ZH.get(reason_code, reason_code)
|
||||
|
||||
Reference in New Issue
Block a user