最近在整理 B 站收藏夹时发现很多优质教程、技术分享和课程视频都存在一个共性痛点视频没法直接搜索、没法快速定位知识点、没法把多个视频的内容串联起来做横向对比。想引用其中的某个观点只能靠记忆硬翻弹幕和评论区。针对这个问题我梳理了一套完整的“B站视频转文字 多P批量处理 跨视频AI问答 角标溯源”的落地方案本文会结合谛听AI的能力从技术原理到工程实现逐步拆解帮助你把收藏夹变成可检索、可问答、可溯源的个人知识库。1. 视频转文字与AI问答知识库到底能解决什么问题1.1 收藏夹里的视频为什么难以直接利用B站聚集了大量优质学习资源尤其是编程教程、框架源码解析、系统设计公开课和行业分享。但视频这种载体有一个天然劣势它是线性播放的内容无法被搜索引擎直接索引。当你需要回顾某个知识点时只能凭记忆找到大概的分P位置然后拖进度条反复试看当你需要横向对比两个视频中关于同一问题的讲解时更是要来回切换窗口。这个痛点本质上是因为视频内容处于“不可检索的暗数据”状态。要让视频真正变成知识库第一步就是把它转换成结构化程度更高的文本形式。1.2 视频转文字、AI问答、角标溯源分别是什么视频转文字是指利用语音识别技术ASRAutomatic Speech Recognition将视频中的语音内容转成文字。常见的输出形式包括纯文本字幕、SRT字幕文件、带时间戳的分段文本等。AI问答是建立在文字内容之上的能力。将转写出来的文本按语义切分成片段通过向量化处理存入向量数据库再结合大语言模型LLM实现针对视频内容的自动问答。例如你可以直接问系统“这个视频里作者提到了哪三种优化方法”系统会从文字库中检索到相关片段并生成回答。角标溯源是知识库应用中很重要的一环。它要求AI在回答问题时不仅要给出结论还要标注这段结论来自哪个视频的哪一分P、在什么时间点出现。这样做有两个好处一是回答结果可以复核避免大模型编造内容二是用户可以快速跳转到原视频对应位置查看完整上下文。1.3 这套方案适用的典型场景学习笔记整理把课程视频转成文字稿建立个人笔记库支持关键字搜索。多视频横向对比同一主题下多个UP主的观点差异通过AI问答快速汇总。团队知识沉淀把培训录像、内部技术分享视频转成可检索的知识资产。论文/文献辅助对学术讲座视频进行内容抽取和重点标记。内容二次创作从视频中快速提取素材片段定位到具体时间点。2. 谛听AI的核心能力与技术架构2.1 谛听AI在整套流程中的位置谛听AI是一套面向视频内容处理与知识库构建的整合方案。它把“视频获取、批量转写、知识库构建、AI问答”这条原本需要人工串联多个工具才能完成的链路整合成了可视化、可配置的流水线。相比自己从零搭建谛听AI在视频批量处理、长视频分段、多P自动识别、答案溯源等方面做了大量工程化处理。从接口设计上看它的使用思路一般是先在网页端或客户端中配置视频来源可以是B站链接或本地文件系统自动拉取视频信息并拆分多P然后依次完成转写、文本清洗、向量入库等步骤。用户最终面对的是一个类似“聊天窗口”的交互界面可以在里面针对已入库的全部视频进行提问。2.2 底层技术栈拆解要实现“B站视频转文字 多P批量 跨视频AI问答 角标溯源”这套能力背后依赖以下技术模块功能模块核心技术输出产物视频获取bilibili API / yt-dlpMP4/M4A 视频文件音频抽取FFmpeg16kHz WAV/M4A 音频语音识别Whisper / FunASR / 商业ASRSRT、VTT、JSON 时间轴字幕文本切片语义分块算法带元数据文本片段向量化Embedding 模型向量索引向量存储Chroma / Milvus / FAISS向量数据库问答生成大语言模型 RAG答案 引用列表溯源展示时间轴映射视频链接 分P 时间戳2.3 为什么需要 RAG检索增强生成而不直接让大模型回答如果你把全部转写文本一次性丢给大模型可能会有几个问题第一是上下文窗口限制。一个1小时视频的转写文字大约有1.5万到2万字多个视频拼接后动辄数十万字远超常见大模型的单次处理长度。第二是召回精度问题。没有检索机制的大模型回答本质上是“凭训练记忆作答”无法保证内容确实来自你指定的视频集合。第三是溯源困难。直接生成回答无法自动给出“这句话出自哪一P的哪一分钟”。RAG检索增强生成的思路是把文本按照语义切块向量化存储提问时先对用户问题做向量化在库中检索最相关的若干片段再把这些片段作为上下文拼接到提示词中交给大模型生成回答。这样既规避了上下文窗口限制又能保证回答基于真实来源同时可以在返回片段中携带时间戳信息实现角标溯源。3. 环境准备与基础工具链3.1 运行环境建议由于语音识别模型对计算资源有一定要求建议按下面的组合准备环境操作系统Windows 10/11、Ubuntu 20.04、macOS 12 均可。Python 版本3.9 或 3.10 以上推荐使用 conda 创建独立环境避免依赖冲突。FFmpeg必须安装用于音频抽取和格式转换。硬件如果使用本地方案跑 Whisper建议 NVIDIA 显卡 8GB 显存以上没有显卡时也可以使用 CPU 跑但速度会慢很多。也可以直接使用在线ASR接口避免本地资源占用。版本需要根据你的项目实际情况调整文中示例以常见环境为例重点演示配置思路。3.2 安装 Python 依赖创建独立环境并安装核心依赖conda create -n bili-rag python3.10 -y conda activate bili-rag安装视频下载工具pip install yt-dlp安装FFmpegUbuntu示例sudo apt update sudo apt install ffmpeg -yWindows 用户可以从 FFmpeg 官网下载编译好的二进制包配置环境变量后即可使用。macOS 用户可以使用 Homebrewbrew install ffmpeg安装语音识别工具。如果选择 OpenAI Whisperpip install openai-whisper如果选择FunASR更适合中文长音频场景pip install funasr modelscope安装向量数据库和LLM相关依赖pip install chromadb openai langchain这里需要说明的是如果你使用谛听AI的产品化流程可以跳过本地环境搭建直接在平台上操作。但是了解底层工具链仍然很有价值因为在实际项目中你可能会遇到平台不能满足的定制化需求。4. 实战B站视频多P批量下载与转文字4.1 理解B站多P视频的下载逻辑B站的多P视频也就是一个视频页包含多个分P常见于长课程、系列教程和直播录播。下载多P视频时不能只拿第一P而需要遍历所有分P的信息逐个拉取视频流。使用 yt-dlp 下载B站视频时可以通过以下命令查看视频列表信息yt-dlp --flat-playlist --print %(playlist_index)s %(title)s %(id)s https://www.bilibili.com/video/BVxxxxxx这个命令会输出该视频下所有分P的序号、标题和视频ID。确认列表无误后执行批量下载yt-dlp -f bv*[height1080]ba/b --write-auto-subs --sub-langs zh-Hans -o ./videos/%(playlist_index)02d_%(title)s.%(ext)s https://www.bilibili.com/video/BVxxxxxx参数解释-f bv*[height1080]ba/b选择最高不超过1080P的视频流和音频流。--write-auto-subs --sub-langs zh-Hans自动下载中文CC字幕如果有的话。-o指定输出文件名格式%(playlist_index)02d会把分P序号补零成两位数便于排序。下载完成后检查文件列表ls -lh videos/预期看到以下格式的文件videos/ 01_第一章 认识大模型.mp4 02_第二章 提示词工程.mp4 03_第三章 RAG实战.mp44.2 批量抽取音频语音识别通常不直接处理视频文件而是先把音频抽取出来转换为模型更友好的采样率和声道格式。使用FFmpeg批量抽取音频的脚本如下#!/bin/bash # 文件路径extract_audio.sh for video in videos/*.mp4; do filename$(basename $video .mp4) ffmpeg -i $video -vn -ac 1 -ar 16000 audios/${filename}.wav -y done这段脚本遍历videos/目录下所有视频文件用FFmpeg抽取单声道、16kHz采样率的WAV音频。这里采样率选择16000Hz是语音识别任务的常见做法既保留了足够的语音信息又比44.1kHz节省空间和处理时间。抽取后的文件结构audios/ 01_第一章 认识大模型.wav 02_第二章 提示词工程.wav 03_第三章 RAG实战.wav4.3 使用 Whisper 批量转写进入Python环境编写一个批量转写脚本。Whisper支持多种模型规格中文场景下推荐使用medium或large-v3英文内容可以适当下调规格以提升速度。# 文件路径transcribe.py import whisper import os import json model whisper.load_model(medium) input_dir audios output_dir transcripts os.makedirs(output_dir, exist_okTrue) audio_files sorted(os.listdir(input_dir)) for audio_file in audio_files: if not audio_file.endswith(.wav): continue audio_path os.path.join(input_dir, audio_file) output_path os.path.join(output_dir, audio_file.replace(.wav, .json)) print(f正在转写{audio_file}) result model.transcribe(audio_path, languagezh, verboseFalse) with open(output_path, w, encodingutf-8) as f: json.dump(result, f, ensure_asciiFalse, indent2) print(f完成{audio_file}共 {len(result[segments])} 个片段)model.transcribe返回的结果中包含segments列表每个segment包含start、end、text等字段。这些时间戳信息最终会被用于角标溯源。4.4 将转写结果整理为带时间轴的结构化文本Whisper输出的JSON格式适合程序读取但不利于后续向量化和人工阅读。建议将每个视频的转写结果转换为一个统一的中间JSON结构# 文件路径build_corpus.py import json import os transcript_dir transcripts corpus [] for transcript_file in sorted(os.listdir(transcript_dir)): if not transcript_file.endswith(.json): continue with open(os.path.join(transcript_dir, transcript_file), r, encodingutf-8) as f: data json.load(f) video_title transcript_file.replace(.json, ) for segment in data.get(segments, []): corpus.append({ video: video_title, start: segment[start], end: segment[end], text: segment[text].strip() }) with open(corpus.json, w, encodingutf-8) as f: json.dump(corpus, f, ensure_asciiFalse, indent2) print(f共构建 {len(corpus)} 个文本片段)这个结构非常关键每个片段都保留了视频标题、开始时间、结束时间、文本内容这就是后面做跨视频AI问答和角标溯源的数据基础。5. 实战跨视频知识库构建与AI问答5.1 文本清洗与语义切片Whisper转写结果中经常包含语气词、重复词、句子中断等问题。在向量化之前需要做两步处理。第一步是清洗。对于中文文本可以过滤掉“嗯”“啊”“那个”“这个”等无意义词汇。这里使用简单规则处理# 文件路径clean_text.py import re def clean_text(text: str) - str: # 去除多余空格和换行 text re.sub(r\s, , text) # 去除常见语气词和填充词 text re.sub(r^(嗯|啊|哦|那|这个|那个|就是说|然后), , text) return text.strip()第二步是切片。Whisper的segment本身可能比较短直接做向量化会导致检索粒度太碎。建议将多个段落按语义聚合为长度适中的片段。常见做法是设置目标片段长度为500个字符左右并按段落边界滑动切分# 文件路径chunk_text.py def segment_corpus(corpus, max_chars500): chunks [] current_text current_video None current_start None current_end None for item in corpus: text item[text] if current_video is None: current_video item[video] current_start item[start] current_end item[end] elif item[video] ! current_video: # 视频切换先保存当前片段 if current_text.strip(): chunks.append({ video: current_video, start: current_start, end: current_end, text: current_text.strip() }) current_video item[video] current_text text current_start item[start] current_end item[end] else: current_end item[end] current_text text if len(current_text) max_chars: chunks.append({ video: current_video, start: current_start, end: current_end, text: current_text.strip() }) current_text current_video None if current_text.strip(): chunks.append({ video: current_video, start: current_start, end: current_end, text: current_text.strip() }) return chunks这个切片策略保证了同一个片段尽量来自同一个视频的连续区域同时在片段中保留了视频来源和时间轴信息。5.2 向量化并写入向量数据库向量化是把文本变成高维数值向量的过程。这里使用 OpenAI Embedding 接口作为示例实际项目中也可以替换为开源模型如bge-large-zh或text2vec-large-chinese避免依赖外部API。# 文件路径vectorize.py from openai import OpenAI import chromadb import json client OpenAI() # 读取切片后的语料 with open(chunks.json, r, encodingutf-8) as f: chunks json.load(f) # 初始化Chroma向量库 chroma_client chromadb.PersistentClient(path./vector_store) collection chroma_client.get_or_create_collection(bili_knowledge) # 为每个片段生成向量并入库 for i, chunk in enumerate(chunks): response client.embeddings.create( modeltext-embedding-3-small, inputchunk[text] ) embedding response.data[0].embedding collection.add( ids[str(i)], embeddings[embedding], documents[chunk[text]], metadatas[{ video: chunk[video], start: chunk[start], end: chunk[end] }] ) print(f已写入 {len(chunks)} 条向量数据)这里需要特别注意元数据metadata是溯源的关键。video、start、end三个字段在后续问答中会被提取出来生成带角标的回答。5.3 构建RAG问答链路RAG问答链路的逻辑可以拆成四步对用户问题做向量化。在向量数据库中检索最相近的 Top-K 片段K值通常取3到5。将片段文本拼接到提示词中连同问题一起发送给大模型。解析大模型回答并将命中的片段信息转换为可见的引用角标。下面是完整的问答函数# 文件路径qa_engine.py from openai import OpenAI import chromadb client OpenAI() chroma_client chromadb.PersistentClient(path./vector_store) collection chroma_client.get_collection(bili_knowledge) def ask_knowledge_base(question: str, top_k: int 5): # 1. 向量化用户问题 q_embedding client.embeddings.create( modeltext-embedding-3-small, inputquestion ).data[0].embedding # 2. 检索相似片段 results collection.query( query_embeddings[q_embedding], n_resultstop_k, include[documents, metadatas] ) documents results[documents][0] metadatas results[metadatas][0] # 3. 拼接上下文提示词 context_parts [] for idx, (doc, meta) in enumerate(zip(documents, metadatas)): video meta[video] start meta[start] context_parts.append(f[{idx}] 来源{video}时间点 {start:.1f}秒\n{doc}) context \n\n.join(context_parts) prompt f你是一个基于视频知识库的问答助手。请根据以下检索到的视频片段回答问题。 每个片段前有编号和来源信息回答时请用[编号]标注你引用的来源。 搜索到的片段 {context} 用户问题{question} 请给出简洁准确的回答并在句子末尾用[编号]标注引用来源。 # 4. 调用大模型生成回答 response client.chat.completions.create( modelgpt-4o-mini, messages[ {role: system, content: 你是一个严谨的知识库问答助手回答必须基于给定片段不许编造。}, {role: user, content: prompt} ], temperature0.3 ) answer response.choices[0].message.content # 生成溯源列表 sources [] for idx, (doc, meta) in enumerate(zip(documents, metadatas)): sources.append({ ref_id: idx, video: meta[video], start: meta[start], end: meta[end], snippet: doc[:80] }) return answer, sources这段代码的Prompt设计是关键。通过在上下文片段中加入编号和来源信息并明确要求模型在回答时标注引用来源就能实现“角标溯源”的输出效果。5.4 运行与验证现在来测试整个问答链路# 文件路径test_qa.py from qa_engine import ask_knowledge_base answer, sources ask_knowledge_base(这个课程里提到了哪几种提升RAG检索效果的方法) print(AI回答) print(answer) print(\n引用来源) for source in sources: print(f[{source[ref_id]}] {source[video]} {source[start]:.1f}s)预期输出大致如下AI回答 根据课程内容提升RAG检索效果的方法主要有三种优化文档切分策略、引入重排序模型Reranker、以及改进向量检索时的混合检索方式。[1][3] 引用来源 [1] 03_第三章 RAG实战 120.3s [3] 05_第五章 高级检索策略 45.8s注意这里模型编号引用与sources列表对齐。用户看到回答后可以直接点击引用来源跳到原视频对应时间点。5.5 将时间戳转换为B站跳转链接为了让角标溯源真正可用可以把时间戳转换为B站视频的跳转链接。B站URL支持带参数跳转到指定时间点格式为https://www.bilibili.com/video/{bvid}?p{part}t{seconds}。这里需要维护一个分P序号到视频链接的映射# 文件路径build_links.py mapping { 01_第一章 认识大模型: {bvid: BVxxxxxx, part: 1}, 02_第二章 提示词工程: {bvid: BVxxxxxx, part: 2}, 03_第三章 RAG实战: {bvid: BVxxxxxx, part: 3}, } def build_video_url(video_name: str, timestamp: float) - str: info mapping.get(video_name) if not info: return return fhttps://www.bilibili.com/video/{info[bvid]}?p{info[part]}t{int(timestamp)}把build_video_url集成到问答结果输出中用户点开链接就能直达对应分P的时间点这样就完成了从“提问”到“答案”再到“原视频验证”的闭环。6. 常见问题与排查思路6.1 高频问题速查表问题现象常见原因解决思路yt-dlp 下载B站视频失败B站接口变动、需要登录态或 Cookie升级 yt-dlp添加--cookies-from-browser chrome参数下载的视频没有声音音频流选择错误检查-f参数确保包含ba音频流Whisper 转写速度极慢使用CPU推理且视频较长改用GPU切换small模型使用FunASR在线推理接口中文转写错误率高模型规格过低或专有名词多使用large-v3在 Prompt 中补充术语表时间戳与视频内容对不上抽取音频前做了转码导致时间偏移尽量直接从原视频抽取音频不要先裁剪或变速向量检索命中不相关片段切片过长导致语义混杂调整 max_chars 到300-500尝试按段落边界切分大模型回答不是来自视频内容Prompt 未约束或检索片段未命中加强Prompt约束增大 top_k开启低 temperature 参数多个视频内容互相干扰知识库混合了不同主题的视频按主题建立不同Collection或给元数据添加“主题”字段6.2 定位“答案不对”的根本原因如果AI回答的内容明显错误不要急着调Prompt。先检查召回环节首先打印检索到的原始片段确认片段文本本身是否相关results collection.query( query_embeddings[q_embedding], n_results5, include[documents, metadatas] ) for doc in results[documents][0]: print(doc)如果检索结果中就没有出现正确答案说明问题出在切片或向量化环节而不是大模型。此时需要检查文本清洗是否过度剔除关键内容。检查切片长度是否合理是否把关键信息从上下文中切断。检查Embedding模型对中文长文本的支持情况。如果检索结果中明明有相关片段但大模型回答还是错了说明Prompt约束不够需要更明确地告诉模型“只能使用给定片段中的信息回答”。6.3 显存不足的应对策略本地跑Whisper时常见的报错是CUDA out of memory。解决办法有三种第一种降低模型规格把large换成medium或small。第二种开启分块转写长度超过一定阈值的音频先按时间切分再处理。第三种放弃本地推理使用云端ASR接口。这类接口通常按小时或按次计费对于一次性处理大量视频的场景反而更划算。7. 最佳实践与工程建议7.1 转写质量优先于技术炫技语音识别是整个知识库的地基。如果转写文本错误百出后面的向量化和问答质量都无从谈起。在生产项目中建议优先使用效果更好的大模型而不是追求速度。对专业领域内容维护一个自定义词汇表在调用ASR时传入。对关键视频做人工抽检发现系统性错误及时调整参数。保留原始音频和视频文件方便后续重新转写。7.2 知识库设计要“分而治之”不建议把几千个视频全部塞进同一个向量集合。更合理的方式是按主题、按课程、按时间分批构建子知识库每个知识库对应独立的Collection或命名空间。这样一方面可以控制单库规模提高检索精度另一方面可以针对不同子库使用不同的检索参数。例如一套Java教程和一套产品经理分享课程用户提问的方式和期望的答案粒度完全不同。另外在元数据设计上建议额外记录以下字段course_name课程名称便于按课程过滤。chapter_title章节标题便于展示时直接定位。upload_date视频发布时间便于排除过时内容。language语言区分中英文内容。7.3 RAG检索效果的三个优化方向很多人搭好RAG之后发现检索效果不理想通常会从三个方向下手。第一是混合检索。纯向量检索对语义理解好但对关键词精确匹配不够敏感。可以加入BM25关键词检索把两种结果做分数融合。这样用户搜索“P99延迟”时即使语义相近的向量检索没命中关键词检索也能兜底。第二是重排序Rerank。向量检索先粗筛出20个候选片段再用交叉编码器模型对候选片段和用户问题做精排最终只取前5个送入大模型。这一步通常能显著提升回答质量但会引入额外计算开销。第三是查询改写。用户提问往往是口语化、不完整的可以在检索前让LLM把问题改写为更规范的搜索词。例如用户问“那个第三个视频里说的优化方法具体是什么”可以改写为“第三个视频中提到的优化方法”。7.4 版权与合规提醒将B站视频转文字并建立知识库只能用于个人学习、研究、笔记整理等合理使用场景。如果需要二次发布、商用或大量复制内容必须先获得原作者授权。下载视频时也要遵守平台规则控制请求频率不要对平台造成压力。知识库本身如果涉及他人版权内容不要在公开渠道随意分享。7.5 生产环境部署建议如果要把这套能力做成团队内部服务建议关注以下几点使用异步任务队列如Celery或Arq来管理视频下载和转写任务避免阻塞主流程。将视频下载、音频抽取、语音识别、向量化拆分为独立步骤各自支持失败重试。记录每条任务的处理状态和日志方便追踪失败原因。为向量数据库和大模型接口设置调用配额防止资源被单个任务耗尽。如果使用云端API注意配置好密钥管理不要把API Key提交到代码仓库。8. 从视频到知识库下一步怎么走通过本文的完整拆解你已经掌握了从B站多P视频下载、批量语音转写、跨视频知识库构建到RAG问答与角标溯源的核心流程。整个过程可以概括为视频文件先转成带时间戳的文本文本再切成语义片段并向量化入库问答时通过检索增强生成返回带引用来源的答案。如果你使用的是谛听AI这类产品化工具可以直接在界面上完成上述流程无需本地搭建复杂环境如果你需要定制化功能也可以参考文中的代码和设计思路把流程集成到自己的系统中。建议先拿自己收藏夹里的一门课程做实验跑通之后再逐步扩展视频数量。下一步值得继续深入的方向包括接入更强的中文ASR模型以提升转写质量、引入重排序模型优化检索相关性、设计更合理的切片策略以适配不同视频类型、以及将知识库与Obsidian等笔记工具打通形成“视频学习-笔记整理-知识回顾”的完整闭环。如果这套方案对你有帮助可以收藏备用。后续遇到具体问题欢迎在评论区交流我会持续整理视频知识库相关的高频踩坑案例与优化方案。