在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. rgw的rgw_thread_pool_size配置调整

    前言 在比对rgw的不同前端的区别的时候,官方说civetweb是通过线程池来控制连接的,beast是后面加入了流控相关的,这块一直也没有调整过相关的参数,然后通过ab压测了一下,还是有很明显的区别的 ...

  2. CVE-2020-3452 CISCO ASA远程任意文件读取漏洞

    0x01 漏洞描述     Cisco官方 发布了 Cisco ASA 软件和 FTD 软件的 Web 接口存在目录遍历导致任意文件读取 的风险通告,该漏洞编号为 CVE-2020-3452.     ...

  3. python-网络安全编程第四天(数据库编程&网络编程)

    前言 好几天没更因为寒假放假回家放松了几天 嘿嘿 今天继续开始启动学习模式. python数据库编程 Python DB API访问数据库流程 Python DB API包含的内容 什么是 PyMyS ...

  4. Navicat总是提示主键不存在问题

    Windows 和 Linux:打开navicat > 找到工具 > 点击选项- > 外观 > 点击数据 & 网格 > 取消勾选显示主键警告 > 确定. M ...

  5. 常见web漏洞修复方法

    方法如下: 漏洞修复.(输入过滤,输出转义) 1.在连接数据库时,在接收参数后进行转义,$id = mysql_real_escape_string($id); 2.在网页源码中在接收参数后可用htm ...

  6. 新鲜出炉!花了三天整理的JVM复习知识点,面试突击必备!

    此次JVM知识点包含以下几个部分 1.类加载机制 2.jvm运行时数据区 3.java对象内存布局 4.jvm内存模型 5.垃圾回收机制 6.垃圾收集器 7.问题排查 一 类加载机制 主要说的部分是这 ...

  7. ABBYY FineReader 15 对比文档功能

    想必大家在办公的时候都有着要处理各种各样文档的烦恼,一个文档经过一个人或不同人的多次修订都是常有的事,拥有文档对比功能的软件也就应势而生.ABBYY FineReader 15 有许多能够帮助我们办公 ...

  8. python截取视频制作动态表情包+文字

    1:安装moviepy库 2:安装IPython库 代码如下: from moviepy.editor import * from IPython.display import Image def B ...

  9. Java基础教程——变量

    变量 变量(variable)可以理解为一个"有名称的容器",用于装各种不同类型的数据.编程人员通过对变量的访问和修改,操作内存中的数据. 对变量的理解:https://www.c ...

  10. Asp.NetCore之AutoMapper基础篇

    应用场景 现在由于前后端技术的分离,后端程序员在使用ORM框架开发后台API接口的时候,往往会将数据库的"数据模型"直接提供给前端.而大多数时候,可能这些数据并不能够满足前端展示的 ...