前端使用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 二进制流
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | /* * 在这里可以进行权限验证等操作 */ //创建文件对象 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | //创建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(); |
1 | < video id="sound" width="200" controls="controls"></ video > |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?