收藏夹里躺了上千个视频真正想看的时候才发现一半已经变成灰灰色的视频已失效。这个场景太熟悉了所以我一直强调B站视频下载这件事不是折腾而是刚需。今天这篇不讲什么高大上的架构就聊聊我用开源工具把B站视频完整保存下来的整套方案包括能直接抄的步骤、踩过的坑以及下载完之后怎么顺手做二次处理。适合谁看经常囤学习资料、想离线看纪录片、做剪辑需要原始素材、或者单纯不想让喜欢的UP主视频和弹幕一起消失的人。无论你是命令行小白还是写过几行脚本这套思路都能直接用而且看完你能明白它背后的原理不是瞎敲命令。1. 为什么我最终选了开源方案1.1 收藏夹的错觉你收藏一个视频只是给它的URL做了个书签内容本身还在B站的服务器上。UP主动态删稿、番剧版权到期、平台自查下架任何一个环节变动你的收藏夹就会多一个打不开的链接。我统计过自己2019年存的收藏夹存活率大概只有七成这个数字还在逐年往下掉。更现实的是看视频的场景也在迁移。通勤地铁上信号不好飞机高铁上根本没有网这时候本地文件比任何在线缓存都靠谱。B站客户端也提供缓存功能但缓存文件是加密的一旦客户端更新、换手机或者卸载重装缓存基本就废了根本导不出来。所以想要真正拥有一段视频内容只能把原始文件握在自己手里。1.2 在线解析站点为什么不建议碰一搜B站视频下载会跳出大量在线解析网页。我以前也图省事用过后来彻底放弃了原因很实在。第一是清晰度上限低大部分在线站能扒下来的也就480P或者720P码率压缩得没法看。第二是广告和跳转问题这些站点主要靠流量变现页面里各种诱导点击下载一个视频要等倒计时、关注公众号、反复验证体验极差。第三才是关键隐私问题你把视频链接贴进去相当于告诉服务商我在看什么这种第三方站点完全不可控指不定哪天就关了或者夹带私货。开源工具则完全绕开了这些。代码公开、行为透明、本地运行不依赖某个网站的存续也不受平台规则变化的影响。只要B站还在更新接口开源社区就会有人跟进适配这就是生态的力量。1.3 开源工具到底解决了什么问题真正好用的开源下载方案解决的不只是把视频拉下来这一个动作而是一套完整流程解析视频流地址、选择清晰度、处理多P视频、合并音视频轨、下载字幕弹幕、断点续传、批量处理。这些功能单看每一项都觉得不就是下载吗合在一起才发现工作量相当大。我最早手动写脚本只解决了单视频下载遇到多P合集和1080P音画分离就懵了。后来转向成熟的开源工具本质上是站在前人的肩膀上不用重复造轮子。2. 下载一个B站视频底层到底在发生什么2.1 你看到的视频不是网页上的一个文件在B站点击播放浏览器发出请求服务器返回的不是一个完整的.mp4文件而是一段JSON数据里面包含了视频流、音频流的真实URL地址以及各种清晰度对应的码率信息。播放器拿到这些地址之后边下边播。这个机制决定了下载工具的运作方式第一拿到网页页面第二从页面中提取视频IDBV号或AV号第三调用视频信息接口拿到视频的CID分P标识第四再用CID去请求playurl接口换取真正的音视频流地址最后把这些流下载到本地并按需合并成完整视频。2.2 从BV号到真实视频流的关键请求链用代码表达会更直观。假设你拿到了一个BV号第一步是用它换取视频的基本信息和分P列表import requests bvid BV1xxxxxx info_api fhttps://api.bilibili.com/x/web-interface/view?bvid{bvid} info requests.get(info_api).json() # 视频标题分P列表每个P都有一个独立的cid pages info[data][pages] cid pages[0][cid]拿到cid之后就能请求真正的播放地址play_api https://api.bilibili.com/x/player/playurl params { bvid: bvid, cid: cid, qn: 80, # 清晰度代号80对应1080P fnval: 16, # 请求DASH格式音视频分离 } resp requests.get(play_api, paramsparams).json()返回的JSON里dash.video是一个列表包含各种清晰度的视频流地址dash.audio是对应的音频流。开源工具做的就是把这套请求流程封装好让你不用手动构造这些参数。2.3 为什么音画要分开下载再合并B站的分发策略里高码率视频普遍采用DASH协议也就是视频轨和音频轨分开传输。这样做的优势是播放器可以根据网络情况分别调节码率画面清晰的同时不过多占用带宽。但这给下载带来一个麻烦你单独下一个视频流出来的文件没有声音单独下音频流只有声音没有画面。必须用FFmpeg这类工具把两路流合并成一个MP4。很多新手第一次下载高清视频发现文件播放不了或者没有声音十有八九就是漏了合并这一步。这个设计初衷也说明了一个问题音画合并不是可有可无的额外操作而是下载高画质内容的必经之路。3. 实操搭建一套可复现的下载工作流3.1 环境准备依赖就两个不管用现成的开源命令行工具还是自己写脚本调接口环境上只需要准备两样东西Python 3.8以上版本以及FFmpeg。FFmpeg是音视频处理的核心工具负责合并轨道、转码、截取、拼接。Windows用户下载安装包后需要把可执行文件路径加入PATH环境变量macOS可以直接装在系统里Linux发行版一般走包管理器。安装完验证一下ffmpeg -version能打印出版本信息就说明环境没问题。这一步卡住的人不少但真不是难事按官方文档走一遍就行。3.2 现成开源命令行工具的一键姿势如果不想自己写代码开源社区有几个非常成熟的B站下载器形态基本是命令行工具复制链接就能下载。例如在终端里输入yt-dlp https://www.bilibili.com/video/BV1xxxxxx它默认会帮你选择最高清晰度自动下载音视频并调用FFmpeg合并。如果要下载整个收藏夹或者某个UP主的投稿也只需要换参数。这类工具会持续跟进B站的反爬策略接口变动后很快更新老用户的体验是相当稳的。比在线解析站强的地方在于它不会因为网站挂了就失效而且支持断点续传下载到一半断了重新跑一遍已完成的块不会重复下载。3.3 用Python脚本控制API适合批量搬运的场景现成工具能覆盖九成需求但如果你想精细控制比如只下载某个分P、自动整理文件名、定时增量抓取新视频写一个几十行的Python脚本会更顺手。核心逻辑就是我前面展示的那样import os import requests def download_bilibili(bvid, save_pathdownloads, quality80): os.makedirs(save_path, exist_okTrue) # 1. 获取视频信息和分P列表 info_resp requests.get( https://api.bilibili.com/x/web-interface/view, params{bvid: bvid}, ).json() title info_resp[data][title] for page in info_resp[data][pages]: cid page[cid] page_title page[part] # 2. 获取音视频流地址 play_resp requests.get( https://api.bilibili.com/x/player/playurl, params{ bvid: bvid, cid: cid, qn: quality, fnval: 16, }, ).json() video_url play_resp[data][dash][video][0][baseUrl] audio_url play_resp[data][dash][audio][0][baseUrl] # 3. 先下载音视频到临时文件 video_file os.path.join(save_path, f{page_title}_v.m4s) audio_file os.path.join(save_path, f{page_title}_a.m4s) with open(video_file, wb) as f: f.write(requests.get(video_url).content) with open(audio_file, wb) as f: f.write(requests.get(audio_url).content) print(f已完成下载: {page_title})这段代码只做最基础的逻辑演示实际使用中还需要加请求头伪装、错误重试、断点续传和并发控制但骨架是完全跑得通的。3.4 清晰度参数与大会员画质的取舍清晰度对应的qn值常见的是16对应360P32对应480P64对应720P80对应1080P112对应1080P高码率116对应4K。但要注意部分高码率和4K画质需要登录甚至大会员权限匿名请求拿到不了这些流地址。所以需要用到登录态的Cookie。开源工具普遍支持读取浏览器已有的Cookie或者手动提供Cookie文件。使用的时候一定要理解这是为你账号的正常使用场景服务不代表可以绕过付费墙用于不正当用途。我自己的习惯是普通视频用1080P足够特别喜欢的纪录片才考虑高码率版本。毕竟码率越高文件越大一部90分钟的4K视频动辄几个GB存储压力还是要算一下的。4. 避坑实录那些年我翻过车的细节4.1 高清视频下载后没声音多半是漏了音视频合并第一次用脚本下载视频兴冲冲点开文件画面清晰但一丝声音都没有。查了半天才发现B站的DASH流就是音画分离的我下载的video.m4s文件本身就不含音频。解决办法是FFmpeg合并ffmpeg -i video.m4s -i audio.m4s -c copy output.mp4用-c copy直接复制流不重新编码速度飞快画质无损。如果时间戳对不上可以加参数微调但大多数情况下直接合成就行。4.2 打开报404或需要登录Cookie与防盗链刚开始用requests直接请求视频流地址返回了一堆乱码或者403后来才发现是请求头里没带Referer。B站的流地址做了防盗链校验请求时必须声明来源是bilibili.com否则服务器拒绝返回数据。解决方式是在请求头里加上headers { Referer: https://www.bilibili.com, User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64), }至于高画质画质报需要登录就是把浏览器里的Cookie塞进脚本。开源命令行工具通常有参数直接导入浏览器Cookie比自己手动复制粘贴省事得多。4.3 下载一半断了、续传续不上怎么处理网络波动、磁盘满、电脑休眠下载中断的理由五花八门。第一次遇到中断时我的第一反应是重新跑一遍结果发现从头开始下之前下好的部分全浪费了。后来改用支持断点续传的方式下载临时文件记录已完成的字节数再次下载时用Range请求头从断点继续。开源工具基本都内置了这个能力自己写脚本的话可以参考Content-Range响应头维护进度。还有一个已经被验证有效的土办法中断后不用删临时文件重新请求流的URL用Range: bytes已下载字节数-继续写文件。断点续传在下载长视频或多P合集时特别重要否则动辄几个GB的大文件光重试就够崩溃的。4.4 多P视频和字幕一起搞定B站视频分P是常态尤其是课程和纪录片合集。下载时如果只看BV号的第一P就会漏掉大量内容。所以要在拿到视频信息后遍历pages列表逐P获取cid并下载。开源工具通常有参数比如--playlist来控制下载整个合集。字幕方面B站的CC字幕、AI字幕不是嵌在画面里的需要额外调用字幕接口获取一般返回的是JSON格式可以转成SRT文件配合播放器加载。如果你只是拿视频素材做剪辑字幕反而多余不影响使用。5. 下载完之后的整理与二次处理5.1 命名标准化和去广告视频下载到本地只是第一步整理工作同样影响使用体验。我习惯用脚本把文件名规范成UP主 - 视频标题 - 分P序号的格式这样在NAS、网盘、本地目录里一眼就能找到。很多UP主视频开头有固定的片头、结尾有求关注内容做素材库的时候这些都不方便。用FFmpeg可以一键掐头去尾ffmpeg -i input.mp4 -ss 00:00:10 -to 00:30:00 -c copy output.mp4-ss是开始时间-to是结束时间-c copy保证不重新编码处理几十GB的素材也几乎是秒级完成。5.2 视频编辑工具里的常见接法下载下来的视频本质上就是普通的MP4或MKV文件完全可以导入剪映、Premiere、Final Cut Pro这类剪辑软件使用。B站视频普遍是1080P 30帧或60帧兼容性很好不像某些平台有奇怪的编码或者加密保护。如果你做混剪或者二创建议下载时选择60帧版本画面流畅度在慢放时差距非常明显。我一般还会把多个分P先拼接成一个长文件剪辑时方便导入ffmpeg -f concat -safe 0 -i filelist.txt -c copy combined.mp4filelist.txt里按顺序列出文件路径一行一个。这个方式不用重新编码拼接速度极快适合批量合并整集动画或连载教程。5.3 批量转码、截取与拼接的基本思路下载好的素材不全是播放时需要的内容。比如要在手机上看硬盘里存着的高码率文件太大可以压一版720P放手机里。或者只需要某堂课的PPT讲解片段不需要整段视频也可以精准截取。转码用FFmpeg的-crf参数控制质量数值越小质量越高、文件越大一般用23左右就很稳。批量操作可以写个循环for i in *.mp4; do ffmpeg -i $i -vf scale1280:-2 -crf 23 compressed_$i; done这套思路和下载本身是同一套工具链学会之后就打通了下载-整理-编辑的完整流程开源工具的价值也在这里体现得淋漓尽致。6. 常见问题速查表症状原因解决方法下载的视频只有画面没声音DASH音画分离没合并音频轨用FFmpeg合并且-c copy视频流地址403/404缺少Referer防盗链头请求头加Referer: https://www.bilibili.com1080P以上画质不可选需要登录态/大会员权限导入浏览器Cookie多P视频只下了第一P没有遍历pages列表使用播放列表模式或遍历cid下载中途断掉网络波动或程序退出启用断点续传文件名全是乱码/无意义ID没有用接口返回的标题信息按BV号cid标题统一命名合并后音频和画面不同步时间戳异常或编码参数差异加-t和-ss参数或重编码这些坑我基本都亲自踩过有些折腾了一整个下午才弄明白。其实下载工具本身原理不复杂真正费时间的往往是这些细节。好在开源社区更新迭代很快很多坑已经被前人填平了用成熟工具时遇到问题先看Issues和文档基本都能找到答案。最后再分享个小技巧保存视频的同时顺手把视频简介、发布时间一起放进一个文本文件归档信息完整性是本地资料库和在线视频最大的区别这套组合用熟了之后你才能真正体会到把内容攥在自己手里的踏实感。当然也提醒一句下载内容仅供个人学习、备份、二次创作参考公开发布前还是要尊重原作者版权这也是工具使用者最基本的自觉。