前言
随着现在数据处理能力越来越强大,对视频及文件的存储和安全需求越来越多,很多项目中都涉及视频的存储和安全,据lz观察就像两年前FastDFS(阿里巴巴的非关系型数据库,可以用来存储图片、视频、压缩包等几乎任意文件)的使用还没有那么多查找资料也比较困难,现在FastDFS相关的资料以及越来越多了,从侧面也映射出用户对视频等文件的开发需求增加。视频的存储随之而来的就是视频的安全问题,这是一个成本比较高的事,普通公司没办法去实现自己的视频加密逻辑,同样这个问题也困扰着我,大概有两年的时间了一直也没有找到很好的解决方案,今天总算是解决了。这个方法不能保证视频的绝对安全,但是一般的浏览器视频下载插件无法在下载后直接查看视频,对于开发人员我觉得一般超过2年的开发经验才有能力去处理这些视频,但是也需要花大量的时间去解密视频并且合成,工作量之大,接下来看一下相关的技术实现吧。另外这篇帖子介绍的比较多的是windows的实现及实现思路,这篇(视频加密并上传至oss实现高并发访问)可以实现在Linux上的视频加密功能,由于项目安全无法直接贡献类文件只能通过分享方法的方式共享,感兴趣的可以留言我会尽快回复,希望大家勿喷,认为有参考价值的可以点个赞,确实也是花了很多的时间整理资料。
技术栈
名称 | 服务名称、版本及作用 |
---|---|
后端语言 | Java |
播放方式 | web前端 |
代理服务器 | nginx 1.9.7 |
视频切分工具 | ffmpeg 5.0 |
视频播放工具 | video.js |
概述
实现视频加密的大概思路说一下,先通过ffmpeg将mp4格式的视频文件转成h264格式的ts文件,转完后的视频文件主要文件形式为两种,一种为.m3u8的文件,这个文件也可以说是摘要文件,主要记录了当前视频所有的片段文件以及如果使用了加密文件那么加密文件的路径地址,另一种文件为.ts文件,这种类型文件为数据文件,即视频文件。转换的方式实际就是一条ffmpeg开头的指令,ffmpeg的功能是在太强了除此之外还可以做你能想到的跟视频相关的操作(另外多说一句,如果想做直播推流的可以在整合一个rtmp服务,网上资料很多)。如果视频需要加密,切分的时候需要携带你生成的enc.key参数,这样的话你的ts文件就是加密的文件,如果你不带加密enc.key文件那么你的.ts文件是可以在各种播放器中直接播放的。生成好之后我们将m3u8、ts、enc.key文件上传到nginx的html路径下(如果不想key文件与ts文件相同路径,可以编写接口传输另外修改m3u8文件中的uri参数改成能够只能访问到key的get接口地址即可)。然后通过前端的videojs视频播放插件,就可以实现视频的加密播放,默认的加密算法为AES-128,话不多说直接开始
Linux环境相关代码实现分享:视频加密并上传至oss实现高并发访问
实现MP4视频文件加密切分
下面介绍的是在本地完成m3u8视频加密,如果想通过代码实现可以参考lz这篇文章,里面包含ffmpeg的核心视频切分代码,不过不包含生成加密视频文件:Java实现上传的视频转m3u8上传到OSS后播放
视频切分成m3u8文件
参考链接:使用ffmpeg视频切片并加密
- 生成加密用的 key,需要安装openssl服务
windows安装openssl
centos7安装openssl:sudo yum install pcre-devel openssl openssl-devel -y
- 生成一个enc.key文件,license与windows指令相同,生成的路径需要在nginx的html目录下,lz是在html的enc目录下
openssl rand 16 > enc.key
生成加密串,记下来
openssl rand -hex 16
新建一个文件 enc.keyinfo 内容格式如下:
Key URI # enc.key的路径,使用http形式
Path to key file # enc.key文件
IV # 上面生成的iv
例如lz的:
视频切分,传一个test.mp4到enc.key路径下,通过黑窗口执行下面的指令
ffmpeg -y -i test.mp4 -hls_time 12 -hls_key_info_file enc.keyinfo -hls_playlist_type vod -hls_segment_filename "file%d.ts" playlist.m3u8
ffmpeg -y \
-i test.mp4 \
-hls_time 12 \ # 将test.mp4分割成每个小段多少秒
-hls_key_info_file enc.keyinfo \
-hls_playlist_type vod \ # vod 是点播,表示PlayList不会变
-hls_segment_filename "file%d.ts" \ # 每个小段的文件名
playlist.m3u8 # 生成的m3u8文件
切分完成如图:
尝试使用播放器播放ts文件,加密后的ts文件是无法播放的
配置nginx
nginx服务器默认无法播放m3u8格式的文件需要添加配置,修改nginx的nginx.conf文件,新增如下配置,配置完后需要重启nginx服务
location /video {
types{
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
alias /usr/local/nginx/html/m3u8;
add_header Cache-Control no-cache;
add_header Access-Control-Allow-Origin *;
}
截图如下
注意:lz配置方法需要将所有m3u8文件放在nginx的m3u8目录下,并且访问的时候路径是/video(避免路径上出现敏感字符)
使用xftp传到m3u8的test路径下
web前端使用videojs查看
- 创建m3u8.html文件,需要注意的是需要下载video-js.css、video.js、videojs-contrib-hls.js在m3u8的同级目录下
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>videojs-contrib-hls embed</title>
<!--
Uses the latest versions of video.js and videojs-contrib-hls.
To use specific versions, please change the URLs to the form:
<link href="https://unpkg.com/video.js@5.16.0/dist/video-js.css" rel="stylesheet">
<script src="https://unpkg.com/video.js@5.16.0/dist/video.js"></script>
<script src="https://unpkg.com/videojs-contrib-hls@4.1.1/dist/videojs-contrib-hls.js"></script>
-->
<link href="./video-js.css" rel="stylesheet">
</head>
<body>
<h1>Video.js Example Embed</h1>
<video id="my_video_1" class="video-js vjs-default-skin" controls preload="auto" width="640" height="268"
data-setup='{}'>
<source src="http://124.71.187.225/video/encry/a65105d4ae064e829d7e1fea98b3f9e1.player.m3u8" type="application/x-mpegURL">
</video>
<script src="./video.js"></script>
<script src="./videojs-contrib-hls.js"></script>
</body>
</html>
- 层级关系如下
- 修改source标签中的地址为加密后的文件地址
- 修改m3u8文件的URI地址为enc.key
修改前
修改后
打开m3u8.html文件访问视频,并且F12打开调试窗口,可以看到视频播放的过程中伴随着enc.key文件的下载,后期enc.key文件可以通过接口传输并且增加expir参数,感兴趣的可以关注一下,后期会出
资源整理花费了大量时间,对大家有帮助的话希望点个赞支持一下,感谢。
余生还长,切勿惆怅