Open vooidzero opened 2 years ago
B 站 web 端直播使用 HLS (fmp4) 的条件是:
playurl_info.playurl.stream
包含 protocol_name == 'http_hls'
且 format_name == 'fmp4'
的对象playurl_info.playurl.p2p_data.p2p_type in [P2PType.HLS_BILI, P2PType.NONE, P2PType.HLS_NOT_P2P]
下面的例子默认使用 http_stream.flv
,因为 p2p_type
不满足条件
{ "playurl_info": { "playurl": {
"stream": [
{
"protocol_name": "http_stream",
"format": [
{ "format_name": "flv", ... }
]
},
{
"protocol_name": "http_hls",
"format": [
{ "format_name": "ts", ... },
{ "format_name": "fmp4", ... }
]
}
],
"p2p_data": {
"p2p": true,
"p2p_type": -2,
...
},
...
}}}
观察到的现象是 HLS 会在流量较大的时候启用。B 站用 HLS 的主要目的应该是通过 P2P 来减缓服务端压力。
#EXTM3U
#EXT-X-VERSION:7
#EXT-X-START:TIME-OFFSET=0
#EXT-X-MEDIA-SEQUENCE:289020803
#EXT-X-TARGETDURATION:1
#EXT-X-MAP:URI="h288595070.m4s"
#EXTINF:1.00,38db7|56301fef
289020803.m4s
...
#EXT-X-BILI-PREFETCH:URL="[0-9]+.m4s?prefetch=1"
...
#EXT-X-MAP:URI="h288595070.m4s"
指出初始化片段 (ftyp + moov) 为 h288595070.m4s
#EXT-X-MEDIA-SEQUENCE:289020803
指出列表中第一个片段的序号为 289020803.m4s
,该片段以关键帧开始。(B站直播关键帧间隔的一个典型值是 3s,而切片长度为 1s,所以并不是每个片段都有关键帧)
#EXTINF:1.00,38db7|56301fef
中 38db7|56301fef
占的是 title 字段。38db7
是 289020803.m4s
的文件大小,56301fef
是 CRC 校验值。
目前的难题在于输出文件无法让播放器(Potplayer 和 VLC)达到理想中的“边下边看”效果。
先说下当前直播 FLV 下载的“边下边看”效果:
对于视频 FLV 下载,由于视频时长是确定的,Potplayer 和 VLC 都能满足“边下边看”。
而 fmp4 的情况是:
对于 Potplayer 以上不合意的行为,目前我设想了几种解决方法:
2022.02.06 简单测试了下,逐个请求视频(音频就不管了)moof,HTTP请求并发度为4(再往上调收益不大),测试的视频时长为2小时,请求完所有moof耗时为20秒到40秒不等。moof的总体积小(这里的话有2MB)所以mdat的下载耗时可以认为是下载整个m4s文件的耗时,前面的20秒到40秒就是建立索引的时间开销。看起来也不是那么坏,理论上还是可以的,实现的话呢,有生之年吧。
我有点看不懂但是大受震撼
https://github.com/THMonster/Revda 可以实现边播边录,还有弹幕,播放用的是 mpv
目前 B 站 Web 端有时会使用 HLS(切片长度为1秒,每个切片为 m4s 格式)。 LiveVideoStack - B站直播中HLS和去中心化P2P的实际应用
我在 10 月的时候研究了下 MP4 封装格式,参考的文档为 ISO IEC 14496-12(正版要钱,不好找啊)
直播下载的需求是边下边看,长时间连续下载时切片是接受的(这是 FLV 直播下载的行为,连续 5 小时后会切片)
当时得出的结论是:
再往后,有时间的话会添加 MP4 分段合并、M4S 音视频流合并(vomic 目前没找到单文件下载的接口)、HDR 下载(B 站 HDR 只能通过 dash 方式下载)。