H5播放HLS之hls.min.js库

视频推流

为了产生HLS视频,我们可以借助srs来实现rtmp推流并生成HLS流,具体详细使用可以参考我之前的文章,这里不再赘述。

我们要实现web端播放传统的音视频,最重要的实现就是rtmp实时视频推送至srs集群,为了演示我这里只启动一个srs简单应用,重点放在web端播放相关技术的讲解,关于srs实时视频推送一块,我在《SRS直播集群方案》一文已经做了很详细的介绍,这里不再赘述。

首先,我们可以使用ffmpeg或者obs采集本地视频并推送到srs协转服务中,这里我使用obs进行采集与推送(ffmpeg每次都需要敲命令),打开obs=>来源一栏添加“视频捕获设备”=>右下角“设置”,具体如图下所示。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
为了生成HLS流,我们需要配置srs开启HLS直播,该配置如下:

listen              1935;
max_connections     1000;
srs_log_tank        file;
srs_log_file        ./objs/srs.log;
http_api {
    enabled         on;
    listen          1985;
}
http_server {
    enabled         on;
    listen          8080;
    dir             ./objs/nginx/html;
}
stats {
    network         0;
    disk            sda sdb xvda xvdb;
}
vhost __defaultVhost__ {
    gop_cache       off;
    queue_length    10;
    min_latency     on;
    mr {
        enabled     off;
    }
    mw_latency      100;
    tcp_nodelay     on;
    hls {
        enabled         on;
        hls_fragment    1;
        hls_window      6;
        hls_path        ./objs/nginx/html;
        hls_m3u8_file   [app]/[stream].m3u8;
        hls_ts_file     [app]/[stream]-[seq].ts;
        hls_cleanup     on;#是否清理过期ts文件片
        hls_dispose     5;#清理过期文件时间
    }
}

这里的几个重要参数我觉得还是要稍微说明一下的:

  • hls_fragment:秒,指定 ts 切片的最小长度。实际上 ts 文件的长度由以下公式决定:
ts文件时长 = max(hls_fragment, gop_size)
hls_fragment:配置文件中的长度。譬如:5秒。
gop_size:编码器配置的 gop 的长度,譬如 ffmpeg 指定fps为20帧/秒,gop为200帧,则gop_size=gop/fps=10秒。
那么,最终ts的时长为max(5, 10) = 10秒。这也是为什么有些流配置了hls_fragment,
但是ts时长仍然比这个大的原因。
  • hls_td_ratio:倍数。控制 m3u8 的 EXT-X-TARGETDURATION,参考 Rewrite HLS写入ts部分
  • hls_aof_ratio:倍数。纯音频时,当 ts 时长超过配置的 hls_fragment 乘以这个系数时就切割文件。例如,但hls_fragment 是 10 秒,hls_aof_ratio 是 2.0 时,对于纯音频,10s*2.0=20秒时就切割 ts 文件。
  • hls_window:秒,指定 HLS 窗口大小,即 m3u8 中 ts 文件的时长之和,超过总时长后,丢弃第一个 m3u8 中的第一个切片,直到 ts 的总时长在这个配置项范围之内。即 SRS 保证下面的公式
hls_window >= sum(m3u8中每个ts的时长)
  • hls_cleanup:是否删除过期的 ts 切片,不在 hls_window 中就是过期。可以关闭清除 ts 切片,实现时移和存储,使用自己的切片管理系统。
  • hls_dispose:HLS 清理的过期时间(秒),系统重启或者超过这个时间时,清理 HLS 的所有文件,包括 m3u8 和 ts。默认为 0,即不清理。
  • hls_wait_keyframe:是否按 gop 切片,即等待到关键帧后开始切片。测试发现 OS X 和 android 上可以不用按 gop 切片。

启动srs

./objs/srs -c srs/conf
tailf ./objs/srs.log

obs开始推送流
obs开始推送流
使用vlc测试rtmp

rtmp://192.168.12.187:1935/live/1

在这里插入图片描述
在这里插入图片描述
使用vlc测试HLS
在这里插入图片描述
在这里插入图片描述
可以看到rtmp和hls都可以点播,那么接下来的时间我们就基于这两条流开发web前端的页面来点播视频。

H播放HLS

关于HLS点播的第一种方式,我们web前端H5页面我们可以使用hls.min.js库来实现web端的点播。

该库按照我以上的配置延迟大概在7s左右,为降低延时可以适当调整如下参数:

  • hls_fragment和hls_window为较小的值

hls_fragment为ts片段大小,每一个ts文件大小,尽量设置小点以便一个ts文件不需等待太长时间就生成且快速下载;ts文件大小与hls_fragment和gop有关,ts文件时长取两者最大值,所以gop的i帧间隔在采集端也尽量小点。

  • gop大小调小

正如上面分析到,ts文件大小与gop有关,采集端可以降低改值,如果GOP过大服务器端的缓存也会变大

  • h264 编码使用 H.264 baseline profile,减少编码时消耗的时间。
  • 音频尽量使用AAC-LC Codec,这样会减少编码时消耗的时间。

hls.min.js库的使用如下所示:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="Access-Control-Allow-Origin" content="*">
    <title>H5播放m3u8文件</title>
</head>

<body>
    <script src="js/hls.min.js"></script>
    <video id="video" style="width:500px;height: 300px; border: 1px solid red;">
        测试
    </video>
    <script>
        if (Hls.isSupported()) {
            // 获取 video 标签
            var video = document.getElementById('video');
            // 实例化 Hls 对象
            var hls = new Hls();
            // 传入路径
            hls.loadSource('http://192.168.12.187:8080/live/1.m3u8');
            hls.attachMedia(video);
            hls.on(Hls.Events.MANIFEST_PARSED, function () {
                video.play(); // 调用播放 API
            });
        } else {
            alert("不支持HLS");
        }
    </script>
</body>

</html>

经过测试该库的播放非常流畅,延迟经过调整依然保持在7s左右。 在这里插入图片描述
源码获取、合作、技术交流请获取如下联系方式:
QQ交流群:961179337
在这里插入图片描述

微信账号:lixiang6153
公众号:IT技术快餐
电子邮箱:lixx2048@163.com

毕业于中国石油大学软件工程系,先后就职于北京方正集团、北京用友财务软件股份有限公司、广东安居宝数...

47 声望
4 粉丝
0 条评论
推荐阅读
SpringBoot后台代码生成系统
作为技术人员的你,你可能遇到频繁的小项目不断的在创建(包括生产或技术语言),基础功能代码相似度达到90%,系统的基础接口、流程、参数等几近相似。每次新建项目就算你在熟悉,你也得花很大部分的时间(从数据...

贝壳里的沙阅读 1.5k

CSS transition 小技巧!如何保留 hover 的状态?
欢迎关注我的公众号:前端侦探通常情况下,hover 是无法保存状态的。鼠标移入触发额外样式,一旦移出就还原了 {代码...} 这就意味着,如果需要保留hover的状态,可能就不得不借助JS了,比如下面是某某书院的首页...

XboxYan30阅读 3.9k评论 2

封面图
由小见大!不规则造型按钮解决方案
今天,有个群友在群里提问,使用 CSS 能否实现下述这个图形:emmm,中间这个酷似三次贝塞尔曲线的造型,使用 CSS 不太好实现。我的建议是切图实现,然而群友要求一定要用 CSS 实现。虽然麻烦,但是这个图形勉强也...

chokcoco17阅读 1.3k

封面图
CSS 如何让auto height完美支持过渡动画?
欢迎关注我的公众号:前端侦探众所周知,高度在设置成auto关键词时是不会触发transition过渡动画的,下面是伪代码 {代码...} 效果如下如果希望展开时有过渡动画,例如这样通常是借助 JS 动态去获取元素的高度(还...

XboxYan17阅读 1.3k评论 2

封面图
vh 存在问题?试试动态视口单位之 dvh、svh、lvh
大部分同学都知道,在 CSS 世界中,有 vw、vh、vmax、vmin 这几个与视口 Viewport 相关的单位。正常而言:1vw 等于1/100的视口宽度 (Viewport Width)1vh 等于1/100的视口高度 (Viewport Height)vmin — vmin ...

chokcoco13阅读 1.4k评论 2

CSS 奇思妙想之酷炫倒影
在 CSS 中,倒影是一种比较常见的效果。今天,我们就将尝试,使用 CSS 完成各类不同的倒影效果,话不多说,直接进入主题。实现倒影的两种方式首先,快速过一下在 CSS 中,实现倒影的 2 种方式。使用 -webkit-box-...

chokcoco14阅读 1.9k评论 1

那些不用js也能实现的效果
本文首发于公众号:GitWeb,欢迎关注,接收首发推文本文列举几个不需要使用js也能实现的效果一、页面回到顶部回到顶部是页面开发中很常见的一个功能,一般的做法是对回到顶部组件做一个监听,当用户点击的时候,...

阿山9阅读 514评论 4

封面图

毕业于中国石油大学软件工程系,先后就职于北京方正集团、北京用友财务软件股份有限公司、广东安居宝数...

47 声望
4 粉丝
宣传栏