在HTML5里,提供了<video>标签,可以直接播放视频,video的使用很简单:

<video width="320" height="240" controls>
<source src="movie.mp4" type="video/mp4">
</video>

这基本上能满足大部分用户的需求,但是还是有几个问题需要解决:

(1)大视频的问题。

(2)字幕的问题

(3)清晰度的问题

(4)视频保密问题。

本文将简单的探讨上面几个问题并给出简单的解决方案。

备注:这些问题也是我在制作启明星视频系统时遇到的(演示  http://demo.dotnetcms.org/video ),所以,如果你在开发视频播放,那么本文应该对你有用。

1.大视频问题

当使用video播放视频时,对于大视频最好是分片存储,例如一个500M的视频,以10M为一个视频段,那么可以分为50个片段。播放时,按需加载所需要的视频片段(例如用户拖动滚动条直接到一个部分)。

这里又遇到2个问题:

1.1大文件的上传

大文件上传,这里使用的百度的 WebUploader,百度很好的一个上传组件,可惜已经不再维护,当然国外也有很多开源的大文件上传组件,所以,这个问题不大。

大文件上传的原理也比较简单:HTML5里提供了JS 的 FileReader类,Blob类,利用这个类可以在本地直接读取视频的大小,例如要上传500M的视频,以10M为一个分块,把视频分割为一个为50份,对于每一份利用JQuery的AJAX分别上传到服务器上,等50份上传完后,服务器再把这50分视频合并成一个大文件即可。

在上传时通常需要给每个视频一个编号,例如 file0,file1,file2... 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.exe组件,ffmpeg提供了如下命令:

ffmpeg.exe -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>

目前国内的有 腾讯的 tcplayerlite和百度的cyberplayer 可以播放m3u8,不过,他们其实都使用videojs这个开源内容,外加一层皮肤。

在我自己开发里,因为不想引入太多的JS,所以直接使用 HLS.JS(HTTP Live Streaming )

当引入hls后,播放视频变的非常简单:

      <video          width="100%"      id="video2"     >     </video> 

                <script>
if (Hls.isSupported()) {
var video2 = document.getElementById('video2');
var hls = new Hls();
hls.loadSource('a.m3u8');
hls.attachMedia(video2);
hls.on(Hls.Events.MANIFEST_PARSED, function () {
video2.play();
});
}
</script>

直接使用       hls.loadSource('a.m3u8');  即可加载播放列表。

1.4 播放清晰度

m3u8指向的是播放列表,他本身不提供多清晰度的问题,通常,你需要利用 ffmpeg.exe 生成不同的清晰度,例如

对于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开头,这其实是 createObjectURL搞的鬼

有兴趣的朋友可以看看其文档介绍,简单说,他就是把真实的地址隐藏了,当你看video的src看到的是一个虚拟地址。

(3)m3u8 加密

如上所述,m3u8里存放的是一个个 *.ts,对于普通用户来说,就算看到*.ts文件,让他一个个下载ts,估计想死的心都有。所以,我们保护m3u8最核心的是防止工具下载。

一个简单的解决方法是:m3u8加参数或者利用session,例如  a.m3u8?key=xxxxx-xxx-xxx

当使用工具下载视频时,工具因为无法获取key参数,那么就无法获取到a.m3u8。

当然,如果真正想下载m3u8也不是完全没办法,

ffmpeg.exe 这个工具既然提供了video分割为ts功能,自然也提供ts合并为一个完整的video功能。只是对普通人来说比较繁琐罢了。

当然,如果你不想搞这么复杂,使用下面代码就可以了, controlslist="nodownload" 让视频不出现下载,而contextmenu不允许使用右键播放,这应付一般的小白应该足够了。

      <video
id="video2"
controlslist="nodownload"
>
</video> <script>
$('#video').bind('contextmenu',function() { return false; });
</script>

以上内容是我做启明星视频遇到的,你可以查看demo当然还有很多细节要考虑,但是大部分问题都已经解决。

关于大视频video播放的问题以及解决方案(m3u8的播放)的更多相关文章

  1. 手机浏览器自动播放视频video(设置autoplay无效)的解决方案

    1.问题的提出 某一天接了个需求,需要在手机的H5页面内加入视频,我开开心心做完,准备交付的时候,问题来了,PM想要用户一进入页面,视频就开始播放,不需要用户手动点击. 2.尝试解决 加autopla ...

  2. video视频在本地可以播放,在服务器上不可以播放

    今天遇到一个比较坑的问题,视频在本地可以播放,然后放到服务器上面就播放不了,原因是因为服务器上面不支持mp4的播放,下面看解决办法.1.首先进入IIS(Internet Information Ser ...

  3. html5--移动端视频video的android兼容,去除播放控件、全屏等

    html5 中的video 在手机浏览器中的总结所有页面播放时, 如果选择全屏播放, 播放画面将浮动到屏幕的最上层 IOS 手机   自动播放 播放界面浮动文字 播放时是否自动全屏 能否嵌入在页面中播 ...

  4. html5之音频、视频(video&audio)

    音频&视频 本篇为本人的学习笔记. 在Html5之前,浏览器对于视频和音频的处理并没有一个标准.因此在网页中看到的视频,都是通过第三插件的方式嵌入的,如:QuickTime.RealPlaye ...

  5. HTML5视频Video 音频Audio

    视频协议 视频格式 Flash HTML5 HTTP flv HTTP f4v HTTP mp4 HTTP m3u8 HTTP webm HTTP ogg RTMP flv RTMP f4v RTMP ...

  6. 如何使用油猴脚本不要vip就能观看各大视频网站如腾讯,爱奇艺等的vip视频

    如何使用油猴脚本不要vip就能观看各大视频网站如腾讯,爱奇艺等的vip视频 首先打开谷歌商店(这里需要fq,如不能fq的小伙伴请看上面写的Chrome怎么访问外网) 搜索Tampermonkey,点击 ...

  7. html5视频video积累

    又是好几个月没有写东西,还是太懒散了~必须要教育下自己罗~ 这次做了个播放视频的移动H5,之前没有仔细玩过,好好记录下基本知识,还有遇到的一些坑,方便之后再次遇见后进行解决 一.基本 video标签在 ...

  8. popcorn-js视频Video框架简单用法

    <div> <video class="video" id="ourvideobig" preload="auto" co ...

  9. IOS(苹果手机)使用video播放HLS流,实现在内部播放及全屏播放(即非全屏和全屏播放)。

    需求: 实现PC及移动端播放HLS流,并且可以自动播放,在页面内部播放及全屏播放功能. 初步:PC及安卓机使用hls.js实现hls流自动播放及全屏非全屏播放 首先使用了hls.js插件,可以实现在P ...

随机推荐

  1. SQL Server数据库Union和Union All查询出数据的区别?

    好久没有更新博客了,可能是最近比较忙,总是忽略了一些事情,今天查了做了一些数据分析的数据,突然感觉对Union和Union all有些不太理解了,可能是自己老了吧,就翻了一些资料,进行回忆和学习,趁着 ...

  2. Netty源码解析 -- 内存对齐类SizeClasses

    在学习Netty内存池之前,我们先了解一下Netty的内存对齐类SizeClasses,它为Netty内存池中的内存块提供大小对齐,索引计算等服务方法. 源码分析基于Netty 4.1.52 Nett ...

  3. java大厂面经-阿里腾讯、网易美团、京东、华为、快手、字节全在这里了

    前言 在这篇文章详细说了该如何去复习,之前也答应各位把面经整理一下,但是因为入职的事情耽搁了,现在整理出来回馈给大家! 美团 一面 0.自我介绍1.问项目(项目详细介绍.用到什么技术.有什么优化)2. ...

  4. 深度分析:面试阿里,字节99%会被问到Java类加载机制和类加载器

    1. 类加载机制 所谓类加载机制就是JVM虚拟机把Class文件加载到内存,并对数据进行校验,转换解析和初始化,形成虚拟机可以直接使用的Jav类型,即Java.lang.Class. 2. 类加载的过 ...

  5. The Life out of coding_Employment_01

    1.工作与个人价值 软技能读书笔记第一篇:--From 安晓辉 内生涯与外生涯 内生涯包括知识.技能.工作经验.心理素质.内心情感.行为习惯.视野.观念.职业心态.职业成熟度.心灵成长. 外生涯包括职 ...

  6. FL studio系列教程(十六):FL Studio查看菜单讲解

    FL Studio中每个窗口的显示.隐藏和布局命令都在查看菜单中.其中它被分为窗口.布局和浏览器3个部分,各项名称都有其单独的作用.窗口部分主要是软件的显示的一些菜单这里就不详细讲解了,接下来我们重点 ...

  7. 慢SQL优化:where id in (select max(id)...) 改为join后性能提升400倍

    背景 有两张表,都是主键递增,类似于主表和明细表: statistics_apply:统计申请表,主键applyId,7万多条记录 statistics_apply_progress:统计申请进度表( ...

  8. 唯一key的生成规则,可自己视情况改动

    <?php function getMillisecond() { $time = explode ( " ", microtime ()); $time = $time[1 ...

  9. leetcode117. 填充每个节点的下一个右侧节点指针 II

    给定一个二叉树struct Node {  int val;  Node *left;  Node *right;  Node *next;}填充它的每个 next 指针,让这个指针指向其下一个右侧节 ...

  10. Vue Springboot (包括后端解决跨域)实现登录验证码功能详细完整版

    利用Hutool 基于Vue.ElementUI.Springboot (跨域)实现登录验证码功能 前言 一.Hutool是什么? 二.下面开始步入正题:使用步骤 1.先引入Hutool依赖 2.控制 ...