V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
yodhcn
V2EX  ›  程序员

音视频点播为什么要用 HLS? HTTP 不是也有 Range 请求头?

  •  
  •   yodhcn ·
    yodhcn · 362 天前 · 3002 次点击
    这是一个创建于 362 天前的主题,其中的信息可能已经有所发展或是发生改变。
    用 Nginx 作为静态资源服务器,访问音频/视频资源时,Nginx 会处理 Range 请求头,不是也能实现拖拽进度条的功能吗?而且读取文件的第 xxx 字节的数据造成的延迟也不高。

    那么,HLS 又为什么要提前切片?是因为磁盘上的大文件随机读取慢吗?
    29 条回复    2023-11-29 14:41:07 +08:00
    hahasong
        1
    hahasong  
       362 天前
    CDN 了解下
    bestsanmao
        2
    bestsanmao  
       362 天前
    因为有些片是新生成的吧
    比如直播
    wy315700
        3
    wy315700  
       362 天前   ❤️ 2
    因为你拖拽进度条的时候,播放器并不知道要请求第几个字节。他只知道请求第几秒的视频。


    @bestsanmao
    OP 说的是点播
    GeekGao
        4
    GeekGao  
       362 天前
    最大优势:HLS 自带多码率自适应啊…
    mscststs
        5
    mscststs  
       362 天前
    DASH 了解一下
    flyqie
        6
    flyqie  
       362 天前 via Android
    好做 cache ?
    nothingistrue
        7
    nothingistrue  
       362 天前
    第一,提高下载门槛。不要小看这一点门槛,防盗版本来就是防小白不防高人,只要把小白阻挡了就已经成功了。

    第二,越简单粗暴,可用性越差,大文件是真不行。就别说网络视频了,本地一个单文件视频,你拖进度条试试。视频定位,快进、快退是跳固定帧,很快,但是点击进度条定位,就要先算基准帧,慢的一匹。HLS 可能原本不是给定位用的,但它顺便就给进度条定位加了一个缓存。
    yodhcn
        8
    yodhcn  
    OP
       362 天前
    @nothingistrue #7
    "视频定位,快进、快退是跳固定帧,很快,但是点击进度条定位,就要先算基准帧,慢的一匹。"

    是指拖拽进度条吗?实测拖拽进度条几乎没有延迟
    yodhcn
        9
    yodhcn  
    OP
       362 天前
    @yodhcn #8

    后端:SpringBoot 实现的 /stream 接口,返回 ResponseEntity<Resource> responseEntity = ResponseEntity.ok().headers(headers).body(new FileSystemResource(filePath))

    前端:html5 <audio>

    测试音频文件:wav 封装格式,大小 1.5G ,时长 1 小时 40 分钟

    实测拖拽进度条几乎没有延迟
    flyqie
        10
    flyqie  
       362 天前 via Android
    @yodhcn #9

    h264 试过吗?

    IPB 帧确实得定位。。定位到最近的 I 帧然后再解码后面的 PB 帧
    jsboy
        11
    jsboy  
       362 天前   ❤️ 1
    貌似和视频格式有关吧?之前处理过类似的功能,mp4 是可以通过视频进度计算对应的字节偏移量,但是有些视频格式是无法通过视频进度计算对应的字节偏移量。所以我的觉得转成 hls 是一种统一的做法。如果原视频需要支持很多格式,那么我会选择统一转成 hls 。
    chaxus
        12
    chaxus  
       362 天前
    hls 协议自带标准加密,码率自适应,分片加载等等,功能比较完备。用其他方式确实也能实现,但是,何必呢?
    ttvast
        13
    ttvast  
       362 天前
    HLS=HTTP Live Streaming

    本来就是针对直播设计的。你们都过度解读了。

    对于点播来说。hls 相比 mp4 没有什么优势和区别
    wy315700
        14
    wy315700  
       362 天前
    @yodhcn
    wav 是固定码率的,进度条和文件位置是等价的。
    你找个 FLV 看看
    nevermoreluo
        15
    nevermoreluo  
       362 天前
    1. 多数音视频格式是无法通过头上一段字节推断流内容的,mp4 除外
    2. hls 有现有库支持浏览器播放,video 标签支持 mp4
    3. H265 解码问题,浏览器多数还不支持硬解,软解实现操蛋,流媒体在服务器上就解决了
    4. 即使 range 也要再经过一系列的解复用才可以拖进度条,不过有现成的库,例如字节的 https://github.com/bytedance/xgplayer
    nothingistrue
        16
    nothingistrue  
       362 天前
    @yodhcn #8 换个 h264 视频再试试,你还可以试试去掉硬解用软解。还没看出来,就再弄个 h265 的。如果你买的是品牌机,有些会内置优化硬解,这东西你要在自己组装机器上会体验的很明显。
    Goat121
        17
    Goat121  
       362 天前   ❤️ 1
    我还真用 range 做过,你自己测试是没用的,我们当时测试也没问题
    但是上线问题就来了,因为视频点播必须上 CDN 的,CDN 不支持 range 获取视频
    即使真有 CDN 支持,每次回源必须拉取整个视频资源,不管是用户响应时间还是流量成本,都比 hls 高太多了。
    特别是对于长视频,用户往往不会看完,越长的视频越浪费。当时我们调研过市面上主要 app 的视频格式,只有抖音用的 mp4 ,没考虑到抖音是最长 15 秒的,灰度测试紧急改成 hls 了
    laqow
        19
    laqow  
       362 天前
    video 控件的 range 每次都是从节点直接到结尾的,意味着会重新下载很多次原始视频
    leaflxh
        20
    leaflxh  
       362 天前
    搞个视频放在服务器上,本地用<video src="视频地址" /> 试一下就知道了

    你看看能不能流畅的拖动进度条,甚至能不能加载显示出来

    以及可供的测试项:

    视频为 h265 格式
    视频为 h264 格式,但关键帧间隔不固定
    视频为 mkv 格式
    leaflxh
        21
    leaflxh  
       362 天前
    以及不要在本地测试。非要测试你可以选择把视频放在 U 盘上
    fgodt
        22
    fgodt  
       362 天前
    hls 切片对点播来说还有个优点是可以秒开,mp4 大文件 Meta 头都要读很久

    你 wav 是未编码的 pcm 格式没有代表性,你试一试 aac+264 组合 seek 就麻烦了
    yodhcn
        23
    yodhcn  
    OP
       361 天前
    @nevermoreluo #15
    音视频封装了解的少,请教一下老哥:

    1. 本地播放器在播放本地视频,拖拽进度条时,是怎么根据播放进度,定位应该从文件的哪个字节开始播放的?
    理论上,网页端播放器与本地播放器,二者的差别应该只有网络传输上的延迟,是 <audio> <video> 的实现逻辑太简单的吗?

    2. 您提到的“解复用”具体是指什么? <audio> <video> 在播放某些特殊格式的媒体时,不能直接根据播放进度计算出 range ,字节的 bytedance/xgplayer 是怎么解决这个问题的?

    3. 测试了常用的音频编码:wav ,mp3 都可以无延迟拖进度条,flac 就不行。
    是编码层面上的什么差异,导致了这样的结果? 同样是压缩编码,mp3 可以,而 flac 不行?
    nevermoreluo
        24
    nevermoreluo  
       361 天前
    叠甲,以下是曾经断续看过两周各种奇怪资料的个人理解,如有不对还请大佬指正:

    1. 差别是网络延迟、缓存、编解码(甚至转码,有的时候软解还要组回去喂给 canvas 或者 mse)。因为这些问题会导致视频甚至无法在 video 标签里面播放,例如 avi 。定位文件从那个字节播放有点想当然了,视频编码不是平铺直叙的,文件指针 seek 到相应位置并不一定等于视频播放 seek 到对应位置。举个例子,音频流和视频流是两组信息,就算你强行 seek 过去大概率会在视频上。夫人,你也不想播放光渲染画面,没有声音吧。。。

    2. 解复用是把封装在容器文件中的音视频流分离出来,就像上面说的特例,假设就只有一个视频流和一个音频流,实际可能有很多。字节的 range 也是依赖 mp4 特定格式的 meta 信息,解析出索引和时间戳找到对应的数据组回 mse 播放的。也就是说限定 mp4 支持了 range

    3. 这个我也不太了解,就不强答了。
    edotac
        25
    edotac  
       361 天前
    1.HLS 有成熟的加密安全解决方案,mp4 不好做或者我还没了解到,这块在付费业务有用。
    2.HLS 的多码率适应在海外复杂网络环境好用?
    3.HLS 的整体卡顿率、失败率比 MP4 低?这个我没测过,但是听说是这样。
    hesetiema
        26
    hesetiema  
       361 天前
    我也觉得是不同格式的音视频问题,之前遇到过:有的音频能拖拽到指定位置快速正常播放,有的却不能,即浏览器进度条是定位到指定位置的,但实际播放的音频确是文件流的开端不是指定位置的音频片段。可能提前切片能减少音视频内容的缓冲和加载时间。当用户请求播放某一段音视频时,服务器可以立即提供已经切片好的片段,而不需要等待整个音视频文件加载完成吧,这样应该是最好的。
    yodhcn
        27
    yodhcn  
    OP
       361 天前
    @hesetiema #26

    看我这篇帖子,我在 flac 音频播放时就遇到过这个问题,flac 的元数据中可以放一个 SEEKTABLE 用来加速 seek 。

    https://www.v2ex.com/t/996058
    hesetiema
        28
    hesetiema  
       361 天前
    @yodhcn 破案了,原来是这样
    lovelylain
        29
    lovelylain  
       361 天前
    > 音视频点播为什么要用 HLS ?
    因为源视频文件不一定是单个文件,可能包含多个文件,所以需要一项能支持分片文件连续播放的技术;从技术的角度,MSE 比 HLS 要好,但是 iPhone 只支持 HLS ,为了能在 iPhone 上播放所以要用 HLS ;为什么 iPhone 不肯支持 MSE 你去问 Apple 。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2761 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 38ms · UTC 10:14 · PVG 18:14 · LAX 02:14 · JFK 05:14
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.