FFmpeg捕获直播串流m3u8数据并保存为mp4

是的,FFmpeg还能干这件事。

背景

周四,浙江大学在b站上开了一场“演化生物学青年学者论坛”的直播,其中有几位报告人的题目令我感兴趣。可惜周四全天都抽不开身,只能寄希望于对直播进行录制之后看回放。

放在以前,我可能会直接开一个格式工厂的录屏,之后换台电脑接着干活。但是毕竟之前录的都是腾讯会议,今天第一次录这种b站直播,于是突发奇想,搜了一下有哪些录制b站直播的方法,得知了捕获m3u8串流数据这种奇淫巧计。

m3u8串流格式介绍

这一段内容整合了文心一言等多个AI的回答。

M3U8是一种基于HTTP Live Streaming(HLS)协议的流媒体播放列 表文件,它在现代在线视频服务中扮演着重要角色。

起源:

M3U8格式的起源可以追溯到苹果公司,它是为了适应HLS协议而被提出的。HLS是一种实时流传输协议,主要应用于在线视频直播和点播。在此之前,流媒体传输面临诸多挑战,如网络带宽波动、不同设备的兼容性等。M3U8作为HLS协议的核心之一,通过其独特的索引文件和多码率适配特性,为流媒体传输提供了更灵活和高效的解决方案。

M3U8格式的前身是M3U格式,这是一种较早的播放列表文件格式,主要用于存储音频文件的URL 列表。M3U8基本上可以认为是M3U格式的扩展,主要区别在于M3U8文件使用UTF-8字符编码,并 且支持更多的标签和特性,以适应HLS协议的需求。

格式:

M3U8文件是一种基于文本的播放列表格式,使用UTF-8编码,以.m3u8作为文件扩展名(同时也是网络资源URL的网址后缀)。M3U8文件作为索引文件,它包含了多个音频或视频文件的URL链接,以及一些播放参数和标签。这些标签定义了播放列表的特性,如媒体文件的持续时间、码率、加密信息等。播放器通过解析M3U8文件,可以按需加载相应的视频分段,并根据网络状况动态调整播放码率,从而实现流畅的观看体验。

HLS协议通过M3U8文件实现了流媒体的分段传输和自适应码率功能。视频文件被切分成多个小段(通常为TS格式),并通过HTTP协议实时传输。TS(Transport Stream)是一种基于MPEG-2标准的视频封装格式,支持多路复用、错误恢复、内置时间戳、任意位置独立解码等特性,相比于MP4等格式,TS格式更适合于需要高可靠性和多路复用能力的场景。

应用场景:

M3U8文件在在线视频播放领域得到了广泛应用,尤其是对于希望提供高质量流媒体服务的平台 来说,这一格式提供了必要的技术支持。其主要用途包括在线视频直播、视频点播、跨平台视频服务、流式文件传输等。由于M3U8文件支持视频分段,视频可以在不下载完整个文件的情况下开始播放,这大大减少了启动延迟和数据使用量。

FFmpeg的介绍与使用

FFmpeg这个工具就不多介绍了吧。对于这么一款瑞士军刀般的软件,之前的博客里面写过很多了。

具体到使用FFmpeg捕获直播串流这件事上,我们需要用到的指令如下:

1
ffmpeg -i "http://example.com/path/to/video.m3u8" -c copy -bsf:a aac_adtstoasc output.mp4

这条命令的作用是从指定的URL下载m3u8串流,并将音视频流复制(不重新编码)到输出的MP4文件中。-bsf:a aac_adtstoasc 参数是为了确保AAC音频流能正确地封装进MP4容器中。

实操:如何找到一个直播的m3u8串流地址,并实现内容捕获

然而,仅仅知道捕获直播串流的命令行指令,依然无济于事,因为m3u8串流地址才是核心。对于b站这样的视频网站来说,我们在浏览器地址栏里看到的那一串URL仅仅是直播页面的网址,而m3u8串流地址则另有其它。因此,下面将介绍一下我们如何使用网页开发者工具找到这个m3u8的地址。

以Firefox浏览器为例。首先,我们打开b站直播页面,并按下键盘上的”F12”按钮,此时将会打开如下图所示的开发者工具(或者也可以在菜单栏→“更多工具”里找到网页开发者工具的入口)。

image.png

接下来,我们在网页开发者工具的栏目中切换到Network标签页(这个标签页记录了当前网页所有的流量和数据包),选择所有类型为Media的数据包,并在筛选器中输入m3u8以过滤出所有m3u8格式的串流链接,如下图所示。注意,下图红框框里标出来的就是这个直播的串流URL。

1727585059955.png

现在我们选中其中任意一条数据记录,按下鼠标右键,在菜单栏里选择copy valuecopy URL ,就能获得这个URL的链接。

image.png

Edge浏览器的资源嗅探方法有点区别,它似乎把b站的m3u8直播串流数据包归类为了Fetch类型而不是media类型(如下图),需要注意一下区分。

image.png

总之,不管使用哪一种浏览器,最后我们复制到的URL大概都长下面这个样子:

1
https://d1--cn-gotcha204-2.bilivideo.com/live-bvc/584477/live_1732959538_49081492/index.m3u8?expires=1727588571&len=0&oi=975321898&pt=web&qn=10000&trid=100732efe5d8f47c8c565c3461656366f8da&sigparams=cdn,expires,len,oi,pt,qn,trid&cdn=cn-gotcha204&sign=5d9c2ac82f198dc33df86d4d02804299&site=302fd3c3e6cf4084876d1f3aea392009&free_type=0&mid=398122142&sche=ban&bvchls=1&trace=16&isp=ct&rg=East&pv=Shanghai&pp=rtmp&source=puv3_onetier&deploy_env=prod&score=5&suffix=origin&p2p_type=1&origin_bitrate=396276&sl=1&hot_cdn=0&sk=bc9191c9d2d0ca7362288c156d0a1a39&qp=de_0&flvsk=9f91530c840c4772d1b03c74821d7442&vd=bc&src=puv3&order=2

有点儿长,不过没关系。现在让我们打开一个命令行窗口,并输入下面的指令进行串流数据捕获:

1
2
3
URL="https://d1--cn-gotcha204-2.bilivideo.com/live-bvc/584477/live_1732959538_49081492/index.m3u8?expires=1727588571&len=0&oi=975321898&pt=web&qn=10000&trid=100732efe5d8f47c8c565c3461656366f8da&sigparams=cdn,expires,len,oi,pt,qn,trid&cdn=cn-gotcha204&sign=5d9c2ac82f198dc33df86d4d02804299&site=302fd3c3e6cf4084876d1f3aea392009&free_type=0&mid=398122142&sche=ban&bvchls=1&trace=16&isp=ct&rg=East&pv=Shanghai&pp=rtmp&source=puv3_onetier&deploy_env=prod&score=5&suffix=origin&p2p_type=1&origin_bitrate=396276&sl=1&hot_cdn=0&sk=bc9191c9d2d0ca7362288c156d0a1a39&qp=de_0&flvsk=9f91530c840c4772d1b03c74821d7442&vd=bc&src=puv3&order=2"

ffmpeg -i $URL -c copy -bsf:a aac_adtstoasc output.mp4

命令行会滚过如下的输出内容。这些内容会随着直播的进行而持续输出,同时output.mp4文件也会不断变大,实时记录下直播的内容。

image.png

要停止对直播内容的捕获,一种方法是按下Ctrl+C键终止当前任务,另一种方法就是等主播下播,直播结束,这样ffmpeg会自动停止捕获。

最后,我们看一下捕获到的output.mp4的效果:

image.png

拓展:基于app的b站直播录屏

有一款APP叫做KB视频工厂 ,将上面这些功能全部包在了APP里,用户只需要输入b站直播的页面地址,就能实现自动m3u8资源嗅探+串流捕获。

不过这个APP是会员制的,免费版用户只能捕获10分钟的视频,对于较长时间的直播需要分好几段进行捕获,稍微有点儿不方便。