oc-youtube-summarizer:专为Agent设计的视频摘要工具,支持YouTube与B站
1. 项目概述一个为Agent而生的视频摘要工具如果你和我一样每天需要从海量的YouTube、B站视频中快速获取信息或者正在构建一个需要“看懂”视频内容的智能体Agent那你一定遇到过这些麻烦手动看视频太耗时自动字幕提取工具要么被平台限流要么不支持B站生成的摘要也往往干巴巴的缺乏上下文和关键画面。今天分享的这个项目oc-youtube-summarizer就是我在实践中找到并深度改造的一个解决方案。它本质上是一个专为OpenClaw等Agent框架设计的技能Skill但其核心功能完全独立可以作为一个强大的命令行工具来使用。这个工具的核心价值在于它打通了从视频信息获取、字幕/语音转录、关键帧提取到AI智能摘要的完整链路并且对YouTube和B站两大平台提供了原生支持。最让我欣赏的是它的设计思路不是简单调用某个单一API而是组合了多种策略来保证稳定性和效果。比如它用innertube客户端绕过YouTube的API限流用faster-whisper在本地处理B站音频转录完全无需OpenAI的API密钥既保护隐私又节省成本。对于需要图文并茂摘要的场景它提供了三种不同策略的“图文模式”从追求速度的纯文本到平衡的自动插帧再到效果最佳的AI审阅配图你可以根据需求灵活选择。接下来我会带你深入这个工具的每一个模块拆解其工作原理分享我在部署和使用中踩过的坑以及优化技巧。无论你是想把它集成到自己的自动化工作流里还是单纯想找一个高效的视频学习工具相信这篇内容都能给你提供直接的参考。2. 核心架构与设计哲学2.1 模块化与可扩展性设计这个项目的代码结构清晰地体现了“单一职责”和“开闭原则”。它不是一个大而全的 monolithic 脚本而是被拆分为几个核心模块这使得理解和扩展变得非常容易。平台提取器这是架构的核心。目前有youtube_extractor.py和bilibili_extractor.py。每个提取器负责处理特定平台的所有逻辑获取视频元数据、下载、提取字幕或转录音频。如果你想支持抖音、推特视频等新平台理论上只需要仿照现有结构实现一个新的extractor类即可。这种设计避免了代码的臃肿也使得维护和测试更加聚焦。摘要生成器这是一个相对独立的服务。它接收提取器处理好的文本字幕/转录稿和可选的图像帧列表调用配置好的大语言模型LLM生成结构化的摘要。目前它支持通过环境变量配置不同的LLM API后端具备了良好的灵活性。核心协调器主脚本video-summarizer扮演了指挥者的角色。它解析命令行参数根据视频URL判断该调用哪个平台提取器协调摘要生成并最终整理输出JSON格式的结果。整个流程清晰可控。这种架构带来的最大好处是稳定性。例如当YouTube的官方API或某个字幕库接口发生变化时你只需要修改youtube_extractor模块而不会影响到B站的处理流程或摘要生成的逻辑。2.2 多策略字幕获取对抗平台限制的实战经验直接使用youtube-transcript-api这类公共库在频繁请求时非常容易触发YouTube的反爬机制导致IP被临时限制。项目作者在这里采用了一个非常聪明的“组合拳”策略这也是我从中学到最多的地方。主攻策略innertube客户端。innertube是一个非官方的库它模拟了YouTube安卓客户端的内部API。通过它来获取字幕请求特征更接近真实用户极大地降低了被识别为机器流量的风险。这是目前最稳定、最推荐的首选方法。备用策略传统API库。当innertube因某些未知原因失败时比如视频格式特殊工具会自动回退到使用youtube-transcript-api作为备选方案。多一层保障成功率就高一分。终极保障语音转录。对于极少数连备用方案都失效或者本身就没有字幕的视频工具会启动“B站模式”的流程下载音频然后用faster-whisper进行本地语音识别。虽然这需要额外计算资源且精度取决于模型大小但它确保了“有音必有文”的底线。实操心得在实际部署中我建议在服务器或长期运行的机器上为innertube配置一个Cloudflare代理通过环境变量设置HTTP_PROXY/HTTPS_PROXY。这不仅能进一步分散请求来源在某些网络环境下还能提高连接速度。项目文档中提到的REQUEST_DELAY_SECONDS环境变量也务必设置建议在3-5秒这是对平台最基本的尊重也是保证长期可用性的关键。2.3 B站处理的本地化方案隐私、成本与效果的平衡B站的处理方案是整个工具的亮点它完美诠释了如何在资源有限的情况下达成目标。无需API Key整个流程从视频下载yt-dlp到语音转文字faster-whisper全部在本地完成。这意味着没有数据上传到第三方服务的风险也没有调用次数或费用的限制对于处理大量视频或敏感内容非常友好。关键帧提取除了文字视频的“画面”信息同样重要。工具使用ffmpeg按固定间隔默认30秒抽取视频帧。这些帧文件路径会保存在输出结果中供后续的AI进行“视觉分析”或简单地作为摘要配图。这个功能对于理解教程类、演示类视频至关重要。模型选择权衡faster-whisper提供了多种规模的模型如tiny,base,small,medium,large-v3。模型越大转录精度越高但所需的内存和计算时间也呈指数增长。工具默认使用small模型在绝大多数情况下其准确度和速度已经取得了很好的平衡。只有在处理口音很重、背景嘈杂或专业术语密集的视频时才需要考虑升级到medium或large-v3。3. 图文摘要的三种模式深度解析这是该工具区别于简单“字幕总结器”的高级功能。它认识到一篇好的摘要不仅是文字的提炼更是关键视觉信息的捕捉。三种模式对应了三种不同的资源消耗和效果层级。3.1 text-only纯文字模式工作流程提取文字字幕/转录→ 发送给LLM生成纯文本摘要。资源消耗最低。仅处理文本不涉及图像下载、抽取或分析。输出结果JSON中的summary字段为Markdown格式的纯文本。适用场景对摘要速度要求极高需要批量处理大量视频。视频内容以口播、访谈为主视觉信息辅助性不强如播客视频。后续处理流程只需要文本信息。我的使用建议在搭建自动化信息流如每日频道扫描时我通常会先使用此模式进行初筛快速判断视频是否值得深入观看。对于确定有价值的内容再单独用更高级的模式重新处理一次。3.2 auto-insert自动插帧模式工作流程按固定间隔如30秒抽取多帧通常会多抽一些作为余量。将所有帧的时间戳统一向后偏移一个固定值默认5秒。这是一个非常实用的技巧因为镜头切换转场后的那一帧往往信息量更大、画面更稳定避开切换瞬间的模糊帧。生成纯文本摘要并划分章节。将帧根据其时间戳机械地插入到对应的章节附近。资源消耗中等。增加了抽帧和简单的匹配逻辑但无需AI分析图像。输出结果摘要文本中会以Markdown图片语法插入本地帧图片的路径或Base64编码取决于配置。适用场景希望摘要有配图但对图文契合度要求不是极致。视频内容节奏均匀每段时间都有代表性画面如产品评测、旅行Vlog。追求比ai-review更快的处理速度。3.3 ai-reviewAI审阅模式- 默认推荐工作流程多帧预选工具首先会抽取比最终需要多约50%的帧例如一个10分钟的视频按30秒间隔应抽20帧但它可能会抽30帧建立一个丰富的“素材库”。先生文后配图这是核心逻辑。LLM先基于字幕生成一个结构清晰、分好章节的纯文本摘要。反向匹配与决策AI开始逐章节审阅这个摘要。对于每一章它会思考“这一部分需要配图吗如果需要预选的帧库里有合适的吗如果没有是否需要命令工具在特定时间点附近补抽一帧如果都不合适这章可以不配图。”输出优化结果最终输出的是精选后的帧每帧都附带一句AI生成的画面描述并精确对应到摘要的某个章节。资源消耗最高。除了抽帧还需要额外的LLM Token来执行“审阅”和“描述生成”的任务。文档中提到会多消耗5-8K Token这基本符合我的实测。输出结果图文契合度最高。图片不再是简单的时间戳附属品而是服务于内容表达的有机组成部分。适用场景制作高质量的读书笔记、学习报告或内容简报。视频内容复杂关键信息点与时间点并非均匀分布如技术教程关键操作可能只出现在某几秒。追求最终摘要的阅读体验和传播效果。避坑指南选择ai-review模式时务必关注你的LLM API成本。如果使用GPT-4这类模型处理一个长视频的额外Token消耗可能不容忽视。一个折中的方案是用auto-insert模式生成初稿人工快速浏览只为真正重要的章节手动补图或替换图片这比完全依赖AI审阅更省成本且效果可控。4. 从零开始的完整部署与配置实操4.1 环境准备与依赖安装假设我们在一个全新的Ubuntu 22.04系统上部署。首先克隆项目代码是第一步。# 1. 克隆项目仓库 git clone https://github.com/mcdowell8023/oc-youtube-summarizer.git cd oc-youtube-summarizer # 2. 安装系统级依赖 (ffmpeg) sudo apt update sudo apt install -y ffmpeg python3-pip python3-venv # 3. 创建并激活Python虚拟环境强烈推荐避免污染系统环境 python3 -m venv venv source venv/bin/activate接下来安装Python依赖。项目提供了setup.sh但理解其内容有助于排查问题。我们也可以手动安装核心依赖。# 手动安装核心Python包 pip install yt-dlp youtube-transcript-api innertube faster-whisper # 验证关键工具 yt-dlp --version python -c import faster_whisper; print(faster_whisper.__version__)跨平台注意事项macOS使用brew install ffmpeg安装ffmpeg其他步骤相同。Windows建议通过choco install ffmpeg(Chocolatey) 或scoop install ffmpeg(Scoop) 安装ffmpeg。faster-whisper在Windows上如果没有CUDA环境会自动使用CPU速度会慢很多处理长视频需有耐心。4.2 首次运行与图文模式配置直接运行工具它会引导你进行初始配置。# 进入项目技能目录假设你在OpenClaw框架内 cd ~/.openclaw/skills/video-summarizer # 运行安装脚本 ./setup.sh # 或者直接运行工具它会提示你进行初始设置 python video_summarizer.py --setup你会看到图文模式的选择提示。这里的选择会被保存到config/settings.json。 选择默认图文模式: 1) text-only - 纯文字不抽帧最快 2) auto-insert - 自动选帧插入文档推荐平衡 3) ai-review - AI 智能选图默认最佳效果多消耗 ~5-8k token 请选择 [1/2/3] (默认 3):配置解析我个人的习惯是将默认模式设为auto-insert因为它平衡了速度和效果。当需要处理特别重要的视频时再通过命令行参数--mode ai-review临时启用最佳模式。text-only则留给全自动的频道扫描任务。4.3 核心功能实战命令详解4.3.1 处理单个YouTube视频这是最基本的功能。你只需要一个视频链接。video-summarizer --url https://www.youtube.com/watch?vdQw4w9WgXcQ工具会自动识别平台提取信息获取字幕并根据你的默认模式生成摘要。结果会以JSON格式打印在终端同时也会在项目目录下生成一个带有时间戳的JSON文件。常用参数组合# 指定使用纯文字模式最快获得摘要 video-summarizer --url YOUR_URL --mode text-only # 指定AI审阅模式并要求使用更大的whisper模型处理音频如果字幕获取失败 video-summarizer --url YOUR_URL --mode ai-review --whisper-model medium # 跳过所有图像处理等同于 text-only video-summarizer --url YOUR_URL --no-frames4.3.2 处理B站视频对B站的支持是无缝的。工具会自动调用不同的提取器。video-summarizer --url https://www.bilibili.com/video/BV1GJ411x7h7对于B站视频流程是下载音频 - 用faster-whisper转录 - 抽帧 - 生成摘要。所以第一次处理时下载和转录可能会花费一些时间。B站专属参数# 调整关键帧抽取间隔为60秒适用于长视频减少帧数 video-summarizer --url BILIBILI_URL --frame-interval 60 # 调整帧时间偏移为8秒进一步避免转场模糊帧 video-summarizer --url BILIBILI_URL --frame-time-offset 84.3.3 频道扫描与每日摘要这是自动化信息收集的核心。你需要准备一个channels.json配置文件。{ channels: [ { name: 科技播客, id: UCXUp6L5-5JhyKkq2vqyfT3A, url: https://www.youtube.com/SomeTechChannel }, { name: 知识区UP主, id: UCxxxxxx, // B站频道ID可在UP主主页地址中找到 url: https://space.bilibili.com/xxxxxx } ], hours_lookback: 24, min_duration_seconds: 300, max_videos_per_channel: 3 }hours_lookback: 回顾多少小时内的视频。设为24就是“每日更新”。min_duration_seconds: 最短视频时长秒。设为3005分钟可以自动过滤掉Shorts等短视频。max_videos_per_channel: 每个频道最多处理几个视频防止某个频道日更过多导致任务过载。运行扫描video-summarizer --config /path/to/your/channels.json运行每日批量处理适合放在Cron定时任务中video-summarizer --config /path/to/your/channels.json --daily --output /tmp/daily_digest_$(date %Y%m%d).json--daily参数会自动将hours_lookback设置为24并忽略配置文件中该字段的值确保每天获取的就是过去24小时的内容。5. 高级配置、集成与故障排查5.1 配置LLM API后端默认情况下工具可能使用内置的或项目预设的LLM服务。要集成你自己的模型如本地部署的Ollama、OpenAI API、Claude等需要通过环境变量配置。# 示例使用OpenAI API export LLM_API_URLhttps://api.openai.com/v1 export LLM_API_KEYsk-your-openai-api-key export LLM_MODELgpt-4-turbo-preview # 示例使用本地Ollama export LLM_API_URLhttp://localhost:11434/v1 export LLM_API_KEYollama # Ollama通常不需要key但有些封装需要 export LLM_MODELllama3:8b # 你本地部署的模型名 # 然后运行工具生成的摘要就会使用你配置的模型 video-summarizer --url YOUR_URL重要提示工具调用LLM的Prompt模板是固定的旨在生成结构化的Markdown摘要。如果你使用的模型对Prompt格式特别敏感或效果不佳可能需要修改项目源码中的summary_generator.py文件来调整Prompt。5.2 输出结果的处理与集成工具的输出是结构化的JSON这为后续自动化处理提供了极大便利。{ generated_at: ..., items: [ { title: ..., url: ..., summary: # Markdown格式的完整摘要\n\n包含文字和图片链接..., platform: youtube, has_transcript: true, // B站视频独有的字段 transcript_path: /tmp/...txt, frame_files: [/tmp/...jpg, ...] } ], stats: {...} }你可以直接阅读将summary字段的内容复制到Markdown编辑器或支持Markdown的笔记软件如Obsidian、Notion中查看。集成到工作流写一个简单的Python脚本或Shell脚本定期运行video-summarizer --daily解析输出的JSON文件将摘要通过邮件、钉钉/飞书机器人、或直接保存到数据库。供Agent使用这也是项目的初衷。你的Agent可以读取这个JSON提取summary结合其他上下文进行二次创作或直接发送给用户。5.3 常见问题与解决方案实录在实际使用中我遇到了以下典型问题并总结了排查思路问题现象可能原因解决方案YouTube字幕获取失败1. 视频本身无字幕。2.innertube和备用API均被临时限流。3. 网络连接问题。1. 检查输出JSON中has_transcript是否为false。如果是工具会尝试用音频转录B站路径或仅基于标题生成简短摘要。2. 增加REQUEST_DELAY_SECONDS环境变量值如设为10并等待一段时间再试。3. 检查网络可尝试配置代理。B站视频处理极慢1. 视频较长faster-whisper使用CPU模式。2. 网络下载速度慢。1. 考虑使用更小的Whisper模型--whisper-model tiny或确保在支持CUDA的机器上运行。2. 使用yt-dlp的参数--limit-rate限制下载速率有时反而能提高稳定性或者检查本地网络。faster-whisper报错缺少CUDA运行时库或版本不匹配。1. 确认已安装正确版本的CUDA Toolkit和cuDNN。2. 或者直接强制使用CPU在代码中或环境变量里指定devicecpu。生成的摘要质量不佳1. 字幕/转录文本质量差。2. 使用的LLM能力不足或Prompt不匹配。1. 对于口音重或嘈杂的视频尝试使用--whisper-model large-v3获取更准确的转录稿。2. 更换更强大的LLM后端如GPT-4或根据你的需求修改项目中的摘要生成Prompt模板。磁盘空间不足处理大量视频或长视频时下载的音频和抽取的帧会占用临时空间。工具使用系统临时目录/tmp。定期清理或通过设置环境变量TMPDIR指向一个更大容量的分区。频道扫描漏掉视频1. 频道ID或URL配置错误。2.hours_lookback设置太短。3. 视频被过滤如时长不足。1. 手动用--url测试该频道的最新视频链接确认可访问。2. 查看JSON输出中的stats了解扫描和过滤的数量。3. 调整min_duration_seconds参数。一个具体的排错案例我曾遇到处理某个YouTube频道所有视频都失败的情况。单独处理单个视频却成功。通过增加--verbose日志可能需要你手动在代码中添加日志输出发现在频道扫描模式下yt-dlp获取的视频列表格式与单个视频不同导致后续拼接URL时出错。解决方案是检查并修复了youtube_extractor.py中解析频道视频列表的那部分代码确保它能兼容不同风格的列表输出。