短视频目前在互联网上非常火爆,因为视频比文字更能清晰的表达创作的内容,大家每天都可能在刷抖音、B站的视频。作为开发人员,不管是否从事音视频开发,都应该了解一下相关的技术。
基础概念
首先给大家介绍视频的三个基础概念:
1.帧数
在一秒内播放的帧数就是每秒帧数率。
视频标准帧率:24帧
2.分辨率
视频图像在一个单位尺寸内的精密度。
常见分辨率:1280*720
3.码率
数据传输时单位时间传送的数据位数,单位:kbps。
码率和质量成正比,但是文件体积也和码率成正比。
视频格式
视频格式实质是视频编码方式,可以大致分为两种大类:
一、适合本地播放的本地影像视频(从网上下载的视频如:MP4)
如上图,这是一个常见的MP4格式视频,有很多视频的基础信息。MP4、AVI、MKV 等都是本地视频文件的后缀,是一种包含视频各种信息的封装格式,可以理解为一种打包,把所有的视频数据和音轨封装在一起。
二、适合在网络中播放的网络流媒体影像视频(如B站上的视频)
『视频协议』是针对网络流媒体而言的,也就是只有在有网络时通过浏览器或者移动端APP才能看到的视频,目前常见的协议有RTSP、RTMP、HLS、HTTP等。
一般来讲,视频流从加载到准备播放是需要经过解协议、解封装、解编码这样的过程,其中协议指的就是流媒体协议;封装指的是视频的封装格式;而编码又分为视频编码和音频编码。
如果平台上的视频出于对版权的考虑,要进行加密,一般是怎么处理的呢?
视频BLOB加密
这种加密是在前端比较常见的一种加密方式,我们以B站上的一个视频为例:
打开浏览器按下F12,可以看到视频的资源地址是一串以 blob 开头的地址,这跟我们常见的地址有些不一样,而且如果你直接打开这个地址是无效的。
BLOB,它的全称为big binary large object,译为二进制大对象。
一般来说,首先由后端,比如 JAVA 将视频转换为blog对象传给前端,前端在拿到blog对象后,再通过URL.createObjectURL生成临时地址,赋值给video标签的src属性,就可以实现这个效果了。前端的大致代码如下:
// 创建XMLHttpRequest对象
var xhr = new XMLHttpRequest();
// 配置请求方式、请求地址以及是否同步
xhr.open('POST', './play', true);
// 设置请求结果类型为blob
xhr.responseType = 'blob';
// 请求成功回调函数
xhr.onload = function(e) {
if (this.status == 200) {//请求成功
// 获取blob对象
var blob = this.response;
// 获取blob对象地址,并把值赋给容器
$("#sound").attr("src", URL.createObjectURL(blob));
}
};
xhr.send();
视频切片加密
我们知道看视频的话是需要很大的流量的,对于绝大多数用户来说,他们不一定会把视频看完,如果是加载一个小视频,那还没有什么大问题,但如果是加载一个大视频的话,这就会浪费大量的流量,并且加载过程会持续占用带宽。
这个时候我们会用到视频分片处理。
试想一下,如果我们把视频切成一段一段的,每次只加载一段,看完了再加载一段,这样能有效的节省资源。
还是以B站的一个视频为例,在F12中的Network里可以看到,网站一直在一段一段的请求视频流的数据。(PS:这个m4s是HTML的一种格式)
切片加密原理:将视频从MP4文件切片成多个ts文件,并使用AES-128对每一片视频进行加密,最后生成m3u8文件。这里我们需要用到ffmpeg。
1.生成公有key
openssl rand 16 > encrypt.key
2.生成私有key(16进制)
openssl rand -hex 16
3.按照下面格式新建一个encrypt.keyinfo的文件
Key URI # enc.key的路径,使用http形式
Path to key file # enc.key文件
Private key # 上面生成的16进制的私有key
例如:
http://192.168.1.111:8090/encrypt.key
/home/Admin/encrypt.key
8b4c39c498949536f8d2af1f6fec7d39
4.用 ffmpeg 开始分片并加密
ffmpeg -y \
-i test.mp4 \
-hls_time 12 \ # 将test.mp4分割成每个小段多少秒
-hls_key_info_file enc.keyinfo \
-hls_playlist_type vod \ # 设置为点播,切片不会变
-hls_segment_filename "file%d.ts" \ # 每个小段的文件名
playlist.m3u8 # 生成的m3u8文件
防盗链Referer
通过对视频资源设置防盗链Referer,可以屏蔽非白名单内的视频资源下载。例如思博网的视频我们都设置了防盗链:
HTTP referer 是 header 上的一个属性。当浏览器向服务器发起请求时,一般会带上Referer,告诉服务器我是从哪个页面链接过来的。打个比方,我们在后台上传一个视频到七牛云,七牛云高级配置里有一个域名防盗链选项,我们可以在这里设置白名单和黑名单。
另外,七牛云还提供了私有空间,私有空间内的文件对象都要获得拥有者的授权才能进行访问,并且可以设置链接的有效时间,超过时长后自动失效(视频会有缓存,清空缓存之前视频仍然有效)。私有空间的特点是安全性更高,需要加token访问,资源链接有时效性。
除了以上几种策略外,还有视频播放器加密、跑马灯防盗录等等。但是即使做了加密处理,也阻止不了录屏。完全杜绝视频泄露是很难的,或者我们可以采取其他方式加大盗用的成本。
目前市面上大致的视频加密就是这几种,当然我们可以多个方案一起使用,使视频加密的安全性更高。