前言
公司做的都是些企业官网,后台管理系统,忽然让做个视频播放功能,需求禁止用户下载视频,我有点方。作为一个前端,看一些视频的时候,会首先看video标签的地址是不是能打开并下载的,但是大部分的视频都是ts文件流传回来的,这样又可以防止下载,又可以随时切换清晰度,很高级,但是我们不用这种方法,因为太高级了,今天我们来用blob加密来处理,这种加密多见于图片加密,视频当然也同理
一、blob
通过URL.createObjectURL()创建一个blob:http://开头的地址,createObjectURL的参数是一个Object对象,可以是File对象,blob对象,还有就是我们今天的主角,mediaSource对象
二、mediaSource
想具体了解mediaSource的可以看这位大佬的文章@Starkwang
三、后台处理
作为一个纯前端,这里不多介绍后台是怎么具体处理的,我只说明一下和后台说的要求
- 读取文件,做成流
- 将二进制流传到前台
四、代码展示
不多解释了好吧,上整套代码,仅供参考
1、后台代码
偷的我们公司的后台阿姨代码,仅供参考啊。
FileInputStream in = null;
OutputStream outputStream = null;
response.setContentType("application/octet-stream;charset=UTF-8");
try {
// String path = AstResourceManagementController.class.getClassLoader().getResource(astResourceManagement.getResourceUrl()).getPath();
String path = Global.getConfig("file_path")+File.separator+astResourceManagement.getResourceUrl();
in=new FileInputStream(path);
int i=in.available();
byte[]data=new byte[i];
in.read(data);
in.close();
outputStream=new BufferedOutputStream(response.getOutputStream());
outputStream.write(data);
outputStream.flush();
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
2、前台代码
1.无插件,纯H5
html
<video src="" id="video" controlslist="nodownload" controls></video>
js
var video = document.querySelector('video');
var assetURL = "${ctx}/getvideo?id=${id}"; //jsp内部写法,不必在意
// 只需要改上边两个属性
var mimeCodec = 'video/mp4;codecs="avc1.42E01E,mp4a.40.2"';
if('MediaSource' in window && MediaSource.isTypeSupported(mimeCodec)) {
var mediaSource = new MediaSource();
video.src = URL.createObjectURL(mediaSource);
//video.src改变会触发监听事件
mediaSource.addEventListener('sourceopen', sourceOpen);
} else {
console.error('Unsupported MIME type or codec: ', mimeCodec);
}
function sourceOpen() {
var mediaSource = this;
var sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
fetchAB(assetURL, function(buf) {
sourceBuffer.addEventListener('updateend', function() {
mediaSource.endOfStream();
});
sourceBuffer.appendBuffer(buf);
});
};
function fetchAB(url, cb) {
var xhr = new XMLHttpRequest;
xhr.open('get', url);
xhr.responseType = 'arraybuffer';
xhr.onload = function() {
cb(xhr.response);
};
xhr.send();
};
2. 开源播放器插件
html
<div controls controlslist="nodownload" id="video-div"></div>
js
var assetURL = "${ctx}/getvideo?id=${id}";
// 只需要改上边两个属性
var player = new Player({
"id": "video-div",
"width":"100%",
"height":"100%",
});
var mimeCodec = 'video/mp4;codecs="avc1.42E01E,mp4a.40.2"';
if('MediaSource' in window && MediaSource.isTypeSupported(mimeCodec)) {
var mediaSource = new MediaSource();
player.start(URL.createObjectURL(mediaSource))
//video.src改变会触发监听事件
mediaSource.addEventListener('sourceopen', sourceOpen);
} else {
console.error('Unsupported MIME type or codec: ', mimeCodec);
}
function sourceOpen() {
var mediaSource = this;
var sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
fetchAB(assetURL, function(buf) {
sourceBuffer.addEventListener('updateend', function() {
mediaSource.endOfStream();
});
sourceBuffer.appendBuffer(buf);
});
};
function fetchAB(url, cb) {
var xhr = new XMLHttpRequest;
xhr.open('get', url);
xhr.responseType = 'arraybuffer';
xhr.onload = function() {
cb(xhr.response);
};
xhr.send();
};
相关报错
mediaSource.endOfStream()
// 这段代码报一些类型等错误的话,尝试修改视频文件类型。