diff --git a/.planning/debug/bilibili-video-subtitle-empty.md b/.planning/debug/bilibili-video-subtitle-empty.md new file mode 100644 index 0000000..03da379 --- /dev/null +++ b/.planning/debug/bilibili-video-subtitle-empty.md @@ -0,0 +1,111 @@ +--- +status: verifying +trigger: "kb-workflow 处理 Bilibili 视频 BV16cNMzpExh 时,字幕内容为空,导致生成的笔记没有真实内容" +created: 2026-03-15T10:30:00Z +updated: 2026-03-15T13:30:00Z +--- + +## Current Focus + +hypothesis: 已实现视频下载功能,DownloadProcessor 现在会为 bilibili video 类型下载视频文件 +test: 验证导入成功,等待用户端到端测试 +expecting: video_path 非空,ASR Whisper 能正常执行语音识别 +next_action: 用户验证端到端流程 + +## Symptoms + +expected: 视频字幕应该被提取;如果没有官方字幕,应该通过 Whisper 语音分析生成字幕 +actual: 字幕内容为空,生成的笔记显示"【内容】(完整字幕)部分为空白" +errors: 无显式错误,kb-workflow 命令执行成功,但内容为空 +reproduction: 对 Bilibili 视频 BV16cNMzpExh 运行 kb-workflow process +started: asyncio 修复后首次测试发现 +additional_context: 用户期望即使没有官方字幕,系统也应该执行 Whisper 语音分析生成字幕 + +## Eliminated + + + +## Evidence + +- timestamp: 2026-03-15T10:30:00Z + checked: kb_pipeline/processors/download.py 第 86-99 行 + found: DownloadProcessor 对于 video 类型,content_file 被设置为空字符串(第 93 行:`content_file = ""`) + implication: ASR 步骤无法获得视频文件路径 + +- timestamp: 2026-03-15T10:31:00Z + checked: kb_pipeline/pipeline.py 第 186-192 行 + found: ASRInput 从 download 步骤的 `content_file` 获取 video_path + implication: 如果 download 步骤没有提供有效的 content_file,ASR 将收到空路径 + +- timestamp: 2026-03-15T10:32:00Z + checked: kb_pipeline/processors/asr.py 第 163-290 行 + found: _try_official_subtitle 方法只依赖 bvid 调用 B站 API,不依赖 video_path;但 Whisper 降级需要 video_path + implication: 官方字幕可能正常获取(如果有),但 Whisper 降级会失败 + +- timestamp: 2026-03-15T10:40:00Z + checked: kb_pipeline/processors/asr.py 第 175-177 行和 Python Path("") 行为 + found: `_try_official_subtitle` 第 175 行直接使用 `Path(input_data.video_path)`;当 video_path 为空时,Path("") 的 parent 是 "."(当前目录),stem 是空字符串 + implication: 字幕文件会写入错误的目录(当前工作目录而不是内容目录) + +- timestamp: 2026-03-15T10:42:00Z + checked: kb_pipeline/pipeline.py 第 184-195 行和 ASRInput 构建逻辑 + found: ASRInput 使用 `download_result.get("content_file", "")` 作为 video_path,并传入 `content_dir`;但 ASRProcessor 的 _try_official_subtitle 只用 video_path 而忽略 content_dir + implication: content_dir 已经传入 ASRInput 但没有被正确使用 + +- timestamp: 2026-03-15T12:00:00Z + checked: pipeline.py 第 155-157 行的跳过逻辑 + found: 当 ASR 步骤被跳过(已完成)时,results 字典中不包含 "asr" 键,导致 analyze 步骤找不到字幕文件 + implication: analyze 步骤的 content_file 为空,无法分析内容 + +- timestamp: 2026-03-15T12:10:00Z + checked: 已实现修复 - 在跳过步骤时添加用户确认和文件扫描逻辑 + found: _populate_skipped_step_results 方法能扫描 content_dir 找到现有的字幕文件({platform}_{content_id}_subtitle.json) + implication: 跳过 ASR 步骤时,results["asr"]["output_files"]["json"] 会被正确填充 + +- timestamp: 2026-03-15T13:00:00Z + checked: kb_pipeline/processors/download.py 第 93-113 行的内容获取逻辑 + found: content_file 只在 content_type in ["article", "answer", "zhuanlan"] 时被设置,video 类型被忽略 + implication: **这是根本原因** - video 类型没有下载视频文件,导致 ASR Whisper 无法执行 + +- timestamp: 2026-03-15T13:05:00Z + checked: kb-bilibili-content/bilibili_content.py 的 download_video 方法 + found: 已有完整的 yt-dlp 视频下载实现,支持多种画质选择 + implication: 可以复用此逻辑,但只需要下载音频(Whisper 只需要音频) + +## Resolution + +root_cause: | + **核心问题:DownloadProcessor 对于 video 类型只获取元数据,不下载视频文件** + + 在 kb_pipeline/processors/download.py 第 93-113 行: + - 只有 content_type in ["article", "answer", "zhuanlan"] 时才调用 adapter.fetch_content() + - 对于 video 类型,content_file 保持为空字符串 + + 结果: + - pipeline.py 第 206 行:`video_path = download_result.get("content_file", "")` 返回空 + - ASRProcessor 的 Whisper 需要 video_path 执行语音识别 + - 没有 video_path,Whisper 无法运行,只能依赖官方字幕 + - 如果视频没有官方字幕,最终笔记内容为空 + +fix: | + 在 DownloadProcessor.process() 中为 video 类型添加视频下载功能: + + 1. 在 BilibiliAdapter 中添加 download_video() 方法,使用 yt-dlp 下载音频 + 2. 在 DownloadProcessor.process() 中,对于 bilibili video 类型调用 adapter.download_video() + 3. 将下载的文件路径设置到 content_file,供 ASR Whisper 使用 + + 修改的文件: + - kb_pipeline/config.py: 添加 bilibili_cookie 配置项 + - kb_pipeline/platforms/bilibili.py: 添加 download_video() 方法 + - kb_pipeline/processors/download.py: 调用视频下载逻辑 + - kb_pipeline/processors/asr.py: 修复缩进错误 +verification: 导入成功,需要端到端测试验证 +files_changed: + - kb_pipeline/config.py + - kb_pipeline/platforms/bilibili.py + - kb_pipeline/processors/download.py + - kb_pipeline/processors/asr.py +commits: + - eae0817: fix(asr): use content_dir for subtitle output + - 729f465: fix(pipeline): populate results for skipped steps + - 60b0eae: feat(download): add video download capability