关于HLS直播流HTML页面播放解决

在最近的项目开发中,涉及了HLS直播音频流的播放,关于网上的资料较多,各种混杂,因此对此在问题解决尝试以及结果进行总结。

最终解决方案使用百度播放器,通过API,自己写想要的播放器组件。

什么是HLS

首先,什么是HLS?

HTTP Live Streaming(缩写是HLS)是一个由苹果公司提出的基于HTTP的流媒体网络传输协议。是苹果公司QuickTime X和iPhone软件系统的一部分。它的工作原理是把整个流分成一个个小的基于HTTP的文件来下载,每次只下载一些。当媒体流正在播放时,客户端可以选择从许多不同的备用源中以不同的速率下载同样的资源,允许流媒体会话适应不同的数据速率。在开始一个流媒体会话时,客户端会下载一个包含元数据的extended M3U (m3u8)playlist文件,用于寻找可用的媒体流。

HLS只请求基本的HTTP报文,与实时传输协议(RTP)不同,HLS可以穿过任何允许HTTP数据通过的防火墙或者代理服务器。它也很容易使用内容分发网络来传输媒体流。

—— 摘自维基百科

由于是HLS技术是苹果公司提出的,虽然在该协议的推广上也是作出了许多贡献,但是也是有很多浏览器依然不支持或者不完全支持该协议。

如何实现页面的直播流播放呢?

对于直播流方案,我做了几种解决尝试

方案一:使用video标签

首先,video标签是HTML 5中的新标签,用于嵌入视频元素。而目前,video标签只支持MP4、WebM、Ogg等格式。

或许,很疑惑,为什么要用视频元素标签来嵌入音频?对于我们这儿直播流的情况下,一般音频标签目前不能够解决。而使用视频元素标签来嵌入直播音频流。

既然这儿video标签不支持m3u8的HLS直播流格式,那是不是我这儿说错了?肯定不是。接下来需要借助一些其他开源项目来解决。

我们在这儿的解决都是基于video.js的一些衍生开源项目解决。

首先是第一种直接使用video.js测试。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<html>
<head>
<meta charset="utf-8" />
<title>Player</title>
<link href="https://unpkg.com/video.js/dist/video-js.css" rel="stylesheet">
</head>

<body>
<video id="video" class="video-js vjs-default-skin" controls preload="none" data-setup='{}'>
<source src="living.url" type="application/x-mpegURL">
</video>

<script src="js/video.js"></script>
<script type="text/javascript">
var player = videojs('video');
player.ready(function() {
var myPlayer = this;
myPlayer.src(url);
myPlayer.load(url);
myPlayer.play();
});
</script>
</body>
</html>

使用Safari浏览器测试如下

Safari支持使用video.js播放HLS直播流

然后,也可以使用videojs-contrib-hls项目解决,测试代码示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<html>
<head>
<meta charset="utf-8" />
<title>Player</title>
<link href="https://unpkg.com/video.js/dist/video-js.css" rel="stylesheet">
</head>

<body>
<video id="video" class="video-js vjs-default-skin" controls autoplay="autoplay" width="640" height="320" data-setup='{}'>
<source src="living.url" type="application/x-mpegURL" />
</video>

<script src="https://unpkg.com/video.js/dist/video.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/videojs-contrib-hls/5.12.1/videojs-contrib-hls.min.js"></script>

</body>
</html>

️注意:在这儿使用的js等资源皆是在线的一些支持。若需要在项目中使用,最好下载到本地使用。

这儿的测试结果,是对于mac上所有浏览器的一般m3u8视频流(即非直播)都支持,都能够播放。直播流仅持safari、edge、android,其他浏览器会出现错误。

Chrome测试HLS直播流

方案二:基于clappr

由于第一种方案,只能够部分解决HLS流播放的问题,且未解决直播流播放的浏览器兼容问题。因此需要继续寻找新的解决方案。

这个方案是基于github上clappr的开源项目解决。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<html>
<head>
<title>test</title>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/clappr@latest/dist/clappr.min.js"></script>
</head>

<body>
<div id="player-wrapper"></div>
<script>
var playerElement = document.getElementById("player-wrapper");
var player = new Clappr.Player({
source: 'm3u8.url',
mute: true,
height: 360,
width: 640
});
player.attachTo(playerElement);
</script>
</body>
</html>

通过测试,发现该方案对于m3u8的视频格式支持播放,但是对于直播流却不支持。

方案三:基于ChPlayer

在查询资料中发现,chplayer是网页视频播放器,支持mp4,flv,f4v以及m3u8格式,支持rtmp。支持点播和直播。因此决定使用这个尝试。

首先将项目下载到本地,然后使用页面测试。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<html>
<head>
<meta charset="UTF-8">
<title>test</title>
<script type="text/javascript" src="chplayer/chplayer.min.js"></script>
</head>

<body>
<dev id='video'></dev>
<script type="text/javascript">
var videoObject = {
container: '#video', //“#”代表容器的ID,“.”或“”代表容器的class
variable: 'player', //该属性必需设置,值等于下面的new chplayer()的对象
video: 'living.url' //视频地址
};
var player = new chplayer(videoObject);
</script>
</body>
</html>

通过这种方式测试,结果是能够解决直播流问题,并且主流浏览器都是兼容的。因此在我们的项目中决定使用这种方式解决问题。

方案四:使用hls.js

目前官方给出兼容情况如下:

方案五:使用cyberPlayer

该方式目前基本兼容常用浏览器,我测试的使用基本兼容。在该方式下,通过自己编写播放器按钮等组件可以基本解决该播放问题。但是在这个情况下,需要考虑当播放器出错时,如何屏蔽掉页面中展示的错误信息。

虽然使用chplayer已经能够解决这个问题,但是在后面的查询资料中发现FFmpeg,可以解决支持直播音频的播放以及所有解码等,虽然不仅限于该领域。后面可以借助其源码学习并解决音频领域的问题。