关于⼤视频video播放的问题以及解决⽅案(m3u8的播放)
在HTML5⾥,提供了标签,可以直接播放视频,video的使⽤很简单:
<video width="320" height="240" controls>
<source src="movie.mp4" type="video/mp4">
</video>
这基本上能满⾜⼤部分⽤户的需求,但是还是有⼏个问题需要解决:
(1)⼤视频的问题。
(2)字幕的问题
(3)清晰度的问题
(4)视频保密问题。
本⽂将简单的探讨上⾯⼏个问题并给出简单的解决⽅案。
width的意思中文翻译1.⼤视频问题
当使⽤video播放视频时,对于⼤视频最好是分⽚存储,例如⼀个500M的视频,以10M为⼀个视频段,那么可以分为50个⽚段。播放时,按需加载所需要的视频⽚段(例如⽤户拖动滚动条直接到⼀个部分)。
这⾥⼜遇到2个问题:
1.1⼤⽂件的上传
⼤⽂件上传,这⾥使⽤的百度的,百度很好的⼀个上传组件,可惜已经不再维护,当然国外也有很多开源的⼤⽂件上传组件,所以,这个问题不⼤。
⼤⽂件上传的原理也⽐较简单:HTML5⾥提供了JS 的类,类,利⽤这个类可以在本地直接读取视频的⼤⼩,例如要上传500M的视频,以10M为⼀个分块,把视频分割为⼀个为50份,对于每⼀份利⽤JQuery的AJAX分别上传到服务器上,等50份上传完后,服务器再把这50分视频合并成⼀个⼤⽂件即可。
在上传时通常需要给每个视频⼀个编号,例如 file0, file49, 上传完毕后,利⽤.NET提供的System.IO.File.ReadAllBytes读取这些⽂件然后合并起来。
foreach (var part in files.OrderBy(x => x.Length).ThenBy(x => x))//排⼀下序,保证从0-N Write
{
var bytes = System.IO.File.ReadAllBytes(part);
fs.Write(bytes, 0, bytes.Length);
bytes = null;
System.IO.File.Delete(part);//删除分块
}
这样,就把本地的500M视频,原封不动的加速上传到服务器暂且命名为 video1.mp4。
1.2⼤⽂件分割
当视频播放时,利⽤的是m3u8进⾏列表播放(下述),在这⾥使⽤了组件,ffmpeg提供了如下命令:
< -i a.mp4 -hls_time 30 -hls_list_size 0 -f hls a.m3u8;
上⾯代码段⾥, -i 表⽰输⼊(input) a.mp4, -hls_time 30 表⽰每个分块断是30秒, hls_list_size 表⽰序号是从0开始。 a.m3u8 表⽰最终⽣成的⽂件名。
上⾯代表的是意思是:⽤ffmpeg把a.mp4进⾏分割,每个分段长为30秒,并把分割后的信息存放在a.m3u8⾥。
执⾏上述命令后,就可以得到⼀些列的 *.ts ⽂件和⼀个a.m3u8⽂件
利⽤.NET可以通过服务器执⾏合并操作。
1.3 m3u8
m3u8⽤来存储视频播放的列表,他的内容类似如下:
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:35232
#EXT-X-TARGETDURATION:10
#EXTINF:10.000,
cctv6hd-1549272376000.ts
#EXTINF:10.000,
cctv6hd-1549272386000.ts
#EXTINF:10.000,
cctv6hd-1549272396000.ts
#EXTINF:10.000,
cctv6hd-1549272406000.ts
#EXTINF:10.000,
cctv6hd-1549272416000.ts
#EXTINF:10.000,
cctv6hd-1549272426000.ts
简单的说,m3u8存放的是播放列表,视频以.ts格式存储, ts即"Transport Stream"的缩写。全称为MPEG2-TS,MPEG2-TS,格式的特点就是要求从视频流的任⼀⽚段开始都是可以独⽴解码的。
不⽤mp4是因为,如果⽤mp4,那么在2个分块直接播放时,会出现卡顿。⽽ts格式可以⽆缝对接。
你甚⾄可以设定客户端存储的数量,例如设置为3,当使⽤⼿机看到5.ts时,⼿机开始缓存6.ts ,7.ts, 8.ts, 只有这3个都下载完毕后,才播放,⽽不⽤等到整个下完才播放,这样增加了播放的流畅度。(有时候我们看视频时,卡顿时,⼿机会显⽰⼀直在缓冲中,来缓存⽚段。。。)
m3u8不是<video> 标签的⽀持的标准格式。换句话说,你使⽤如下代码是⽆法播放的
<video width="320" height="240" controls>
<source src="a.m3u8" type=application/x-mpegURL>
</video>
⽬前国内的有腾讯的和百度的可以播放m3u8,不过,他们其实都使⽤这个开源内容,外加⼀层⽪肤。
在我⾃⼰开发⾥,因为不想引⼊太多的JS,所以直接使⽤(HTTP Live Streaming )
当引⼊hls后,播放视频变的⾮常简单:
<video width="100%" id="video2"></video>
<script>
if (Hls.isSupported()) {
var video2 = ElementById('video2');
var hls =new Hls();
hls.loadSource('a.m3u8');
hls.attachMedia(video2);
<(Hls.Events.MANIFEST_PARSED, function () {
video2.play();
});
}
</script>
直接使⽤ hls.loadSource('a.m3u8'); 即可加载播放列表。
1.4 播放清晰度
m3u8指向的是播放列表,他本⾝不提供多清晰度的问题,通常,你需要利⽤ ⽣成不同的清晰度,例如
对于video1.mp3,你可以⽣成 video-360.mp4, video-720.mp4和 video-1080.mp4 并⽣产多个m3u8
video-360.m3u8
video-720.m3u8
video-1080.m3u8
当视频播放时,如果⽤户选择不同的清晰度,加载不同的m3u8.
你也可以根据⽤户的⽹速,加载不同的m3u8.
2.字幕问题
(以下内容主要来⾃)HTML5 Video视频⽀持⽀持外挂字幕,⽂件后缀名是.vtt,称为WebVTT格式,专门的web字幕格式。使⽤很简单,⽤⼀个<track>元素即可,例如:
<video id="video">
<source src="example.mp4" type="video/mp4">
<track src="example.vtt" default>
</video>
只要src属性地址OK,同时有default属性,字幕就会⽣效。
字幕格式是纯⽂本格式
WEBVTT
00:00:00.001 --> 00:00:01.000
请把你的锅
00:00:01.001 --> 00:00:03.500
带回你的虾
00:00:03.501 --> 00:00:07.000
请把你的微笑留下……
00:00:07.501 --> 00:00:10.000
请把你的锅
00:00:10.001 --> 00:00:12.000
带回你的虾
00:00:12.001 --> 00:00:15.000
请把你的微笑留下
<video>标签外挂<track>
<track src="example.vtt" kind="subtitles" label="中⽂字幕" srclang="zh" default>
⽽track⽀持多个字幕,例如:
<track src="example.vtt" kind="subtitles" label="中⽂字幕" srclang="zh" default>
<track src="example2.vtt" kind="subtitles" label="中⽂字幕(修正)" srclang="zh">
如果你的视频希望提供中⽂/英⽂/⽇⽂等多语⾔版本,利⽤这个⽅法,可以解决视频字幕多语⾔版本的问题。
在youtube上,我们有时候会看到⼀个视频会提供很多语⾔版本,如上所述,vtt是⼀个纯⽂本格式,利⽤机器翻译,例如百度翻译,把 vtt翻译上百个版本,挂在在track上,这样
瞬间,让你的视频⽀持⼏百个语⾔,⽴刻就会⾼⼤上。
最后,说⼀下视频加密,⽆论你⽤何种技术,视频最终是要在⽤户端显⽰的,所以,视频本⾝是⽆法加密的,⽽作为简单加密主要有2个⽅法:
(1)createObjectURL
当我们查看部分⽹站得出视频或者部分图⽚时,你会发现⽹址⽹址是⽤blob:src开头,这其实是搞的⿁
有兴趣的朋友可以看看其⽂档介绍,简单说,他就是把真实的地址隐藏了,当你看video的src看到的是⼀个虚拟地址。
(3)m3u8 加密
如上所述,m3u8⾥存放的是⼀个个 *.ts,对于普通⽤户来说,就算看到*.ts⽂件,让他⼀个个下载ts,估计想死的⼼都有。所以,我们保护m3u8最核⼼的是防⽌⼯具下载。
⼀个简单的解决⽅法是:m3u8加参数或者利⽤session,例如 a.m3u8?key=xxxxx-xxx-xxx
当使⽤⼯具下载视频时,⼯具因为⽆法获取key参数,那么就⽆法获取到a.m3u8。
当然,如果真正想下载m3u8也不是完全没办法,
< 这个⼯具既然提供了video分割为ts功能,⾃然也提供ts合并为⼀个完整的video功能。只是对普通⼈来说⽐较繁琐罢了。
当然,如果你不想搞这么复杂,使⽤下⾯代码就可以了, controlslist="nodownload" 让视频不出现下载,⽽contextmenu不允许使⽤右键播放,这应付⼀般的⼩⽩应该⾜够了。
<video
id="video2"
controlslist="nodownload"
>
</video>
<script>
$('#video').bind('contextmenu',function() { return false; });
</script>
最后说⼀下视频播放的问题,虽然HTML5⾥使⽤ autoplay 就可以制动播放,但是⾕歌的chrome在新版本⾥,已经禁⽌⾃动播放了,⾕歌给的解释:很多⽤户利⽤autoplay这个属性投放⼤量⼴告,让⽤户不堪其扰。因此,如果要autoplay必须配合muted(静⾳),也就是只有静⾳后⾃动播放才能⽣效,否则需要⽤户⼿动点击“播放”。
当然⾕歌也给出另外⼀个解决⽅案:就是不静⾳的⾃动播放,需要这个⽹址在安全性名单⾥,因此,我们看youtube是可以⾃动播放的,但是,很多⽹站是不能⾃动播放。
以上内容是我做遇到的,你可以查看当然还有很多细节要考虑,但是⼤部分问题都已经解决。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论