前端使用blob进行视频路径的加密
转子于:https://www.jianshu.com/p/04727924273d和https://blog.csdn.net/ffffffff8/article/details/87359640
前言:
现在许多视频在线观看网站,你如果打开chrome查看其video标签,会发现它的src是一个以blob:
开头的地址。比如下面这里是B站的截图,可以看到他这里引入的并不是一个在线的视频存放地址,这样你通过爬虫脚本也无法下载该视频文件,通过一个new tab打开也于事无补,会提示你地址错误。
createObjectURL与BLOB
- 我们再回到那个以
blob:
开头的神秘字符串,它其实是通过URL.createObjectURL
这个API生成的,该函数接收一个BLOB对象,返回该对象对应的DOMString
,这个字符串其实也可以看做是一个url地址,但它是与当前窗口的document
对象绑定的,也可以说是会话(session)级的,所以你在新的tab打开也就无效了 - 再来了解下BLOB,他的全称为big binary large object,二进制大对象。如果把一个视频文件转换成二进制对象,其大小肯定很大,这样理解就清楚多了。在浏览器端也提供了BLOB相关的API,通过
new Blog(...)
生成blog对象。 - 拿到blog对象后,再通过
URL.createObjectURL
生成临时地址,赋值给video标签的src属性,这样就可以了。但其实可以直接从服务端接收二进制对象,就是服务端把视频文件转换成二进制对象,通过接口给到前端,前端再生成dom string
。
Video 使用 blob 二进制流需要前后端同时支持。
Java 生成 Blob 二进制流
/* * 在这里可以进行权限验证等操作 */ //创建文件对象 File f = new File("E:\\test.mp4"); //获取文件名称 String fileName = f.getName(); //导出文件 String agent = getRequest().getHeader("User-Agent").toUpperCase(); InputStream fis = null; OutputStream os = null; try { fis = new BufferedInputStream(new FileInputStream(f.getPath())); byte[] buffer; buffer = new byte[fis.available()]; fis.read(buffer); getResponse().reset(); //由于火狐和其他浏览器显示名称的方式不相同,需要进行不同的编码处理 if(agent.indexOf("FIREFOX") != -1){//火狐浏览器 getResponse().addHeader("Content-Disposition", "attachment;filename="+ new String(fileName.getBytes("GB2312"),"ISO-8859-1")); }else{//其他浏览器 getResponse().addHeader("Content-Disposition", "attachment;filename="+ URLEncoder.encode(fileName, "UTF-8")); } //设置response编码 getResponse().setCharacterEncoding("UTF-8"); getResponse().addHeader("Content-Length", "" + f.length()); //设置输出文件类型 getResponse().setContentType("video/mpeg4"); //获取response输出流 os = getResponse().getOutputStream(); // 输出文件 os.write(buffer); }catch(Exception e){ System.out.println(e.getMessage()); } finally{ //关闭流 try { if(fis != null){ fis.close(); } } catch (IOException e) { System.out.println(e.getMessage()); } finally{ try { if(os != null){ os.flush(); } } catch (IOException e) { System.out.println(e.getMessage()); } finally{ try { if(os != null){ os.close(); } } catch (IOException e) { System.out.println(e.getMessage()); } } } }
HTML5 Video 使用 Blob
//创建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();
<video id="sound" width="200" controls="controls"></video>