vooidzero / B23Downloader

(已长久停更)
GNU General Public License v3.0
2.46k stars 339 forks source link

关于 HLS 直播和 DASH 视频的下载 #1

Open vooidzero opened 2 years ago

vooidzero commented 2 years ago

目前 B 站 Web 端有时会使用 HLS(切片长度为1秒,每个切片为 m4s 格式)。 LiveVideoStack - B站直播中HLS和去中心化P2P的实际应用


我在 10 月的时候研究了下 MP4 封装格式,参考的文档为 ISO IEC 14496-12(正版要钱,不好找啊)

直播下载的需求是边下边看,长时间连续下载时切片是接受的(这是 FLV 直播下载的行为,连续 5 小时后会切片)

当时得出的结论是:


再往后,有时间的话会添加 MP4 分段合并、M4S 音视频流合并(vomic 目前没找到单文件下载的接口)、HDR 下载(B 站 HDR 只能通过 dash 方式下载)。

vooidzero commented 2 years ago

B 站 web 端直播使用 HLS (fmp4) 的条件是:

  1. playurl_info.playurl.stream 包含 protocol_name == 'http_hls'format_name == 'fmp4' 的对象
  2. 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 来减缓服务端压力。

vooidzero commented 2 years ago

B 站 m3u8

#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|56301fef38db7|56301fef 占的是 title 字段。38db7289020803.m4s 的文件大小,56301fef 是 CRC 校验值。

vooidzero commented 2 years ago

目前的难题在于输出文件无法让播放器(Potplayer 和 VLC)达到理想中的“边下边看”效果。

先说下当前直播 FLV 下载的“边下边看”效果:

对于视频 FLV 下载,由于视频时长是确定的,Potplayer 和 VLC 都能满足“边下边看”。

而 fmp4 的情况是:

对于 Potplayer 以上不合意的行为,目前我设想了几种解决方法:

XiaoYangTech commented 2 years ago

我有点看不懂但是大受震撼

vooidzero commented 2 years ago

HTTP2 error after 1000 request

sihuan commented 2 years ago

https://github.com/THMonster/Revda 可以实现边播边录,还有弹幕,播放用的是 mpv