|
去年冬天我在准备一门嵌入式开发的课程认证考试,官方课程放在一个自建平台上,视频视频只能在线看,下载拖动进度条还要等缓冲。课程我那会儿住的视频地方网络不稳定,晚上八点以后基本卡成幻灯片。下载忍了三天,课程我决定把视频弄下来。视频 这件事听起来简单,下载做起来要看平台用什么技术。课程常见的视频课程视频托管方式无非几种:直接挂MP4文件、用HLS切片、下载或者套一层加密的课程DRM。前两种都好办,视频第三种基本劝退。下载 先搞清楚视频是怎么传过来的 打开浏览器开发者工具,切到Network面板,选Media过滤,然后刷新页面开始播放。如果看到一串.ts文件不断加载,那就是HLS流。如果只有一个.mp4或者.m3u8,情况更简单。 我遇到的那个平台用的是HLS,每10秒一个切片,一个四十分钟的课程大概产生240个.ts文件。手动一个个下载不现实,但.m3u8索引文件里列出了所有切片的地址,拿到它就能批量处理。 工具选择:别想太复杂 yt-dlp是目前最省心的选择。它支持上千个网站,HLS和DASH都能处理,还能自动合并音视频轨。安装方式取决于系统,Windows直接下exe,macOS用Homebrew,Linux各发行版仓库里基本都有。 用法就一行命令: yt-dlp -o "%(title)s.%(ext)s" "视频页面URL" 如果平台需要登录才能看视频,从浏览器里导出Cookie传给yt-dlp就行。Firefox和Chrome都有现成的扩展可以导出Netscape格式的Cookie文件,然后加--cookies cookies.txt参数。 有些平台会检测User-Agent或者Referer,加上--add-header参数伪装一下即可。我那次还碰到一个坑:平台把.ts切片的后缀改成了.jpg,yt-dlp照样能识别,因为它读的是.m3u8里的内容类型声明,不是靠扩展名判断。 手动下载的路子 如果yt-dlp搞不定,或者你不想装额外工具,手动方案也能用。拿到.m3u8的URL之后,用ffmpeg直接拉流: ffmpeg -i "https://example.com/course/video.m3u8" -c copy output.mp4 -c copy表示不重新编码,直接复制流,速度快,画质无损。ffmpeg会自动处理切片合并和音视频同步。缺点是如果网络中断,得从头再来。加个-reconnect 1 -reconnect_streamed 1能缓解,但不是万能的。 还有一种情况是视频被切成了独立的.ts文件,没有.m3u8索引。这时候可以用curl或者wget批量下载,然后用cat合并: cat *.ts > merged.ts 再用ffmpeg转成MP4容器。这个方法笨但有效,适合切片数量不多的情况。 加密流怎么办 AES-128加密的HLS流,.m3u8里会有一个#EXT-X-KEY标签,指向密钥文件。如果密钥是通过公开URL分发的,yt-dlp和ffmpeg都能自动获取并解密。如果密钥需要额外鉴权,那就得手动拿到密钥,用--hls-key参数传给ffmpeg。 DRM加密(Widevine、FairPlay这些)就别折腾了,解密需要从CDM里提取密钥,技术门槛高,法律风险也大。碰到这种,老老实实在线看吧。 几个实际会遇到的问题 下载速度慢。HLS切片是一个个下的,默认并发数不高。yt-dlp加--concurrent-fragments 8能明显提速,但别设太高,有些服务器会封IP。 音视频不同步。偶尔出现在切片时间戳不连续的情况下,ffmpeg合并时加-fflags +genpts可以修复。 字幕丢失。如果课程有独立字幕文件,yt-dlp的--write-subs参数能一并下载。内嵌字幕就没办法了,只能录屏。 我最后用yt-dlp搞定了那门课的全部视频,前后不到二十分钟。后来发现平台上其实有下载按钮,只是藏在一个需要滚动才能看到的角落里。白折腾一晚上。所以动手之前,先把页面翻到底。 |