zoukankan      html  css  js  c++  java
  • Java网站视频资源加密

    ----------------------------------------------------------分享此文章,只为让版权能够得到更多的保护----------------------------------------------------------------------------

    目前公司是做线上视频教育的,教育视频资源一直被盗取,版权被侵犯。领导特别重视此事,于是就开始探索如何加密。

    果然,功夫不负有心人。。。。

    为了遵守技术开源无私奉献的原则,让版权能够得到更多的保护,决定果断分享此功能的实现方法!

    先带大家看一下主流视频网站的实现:

    等等吧,就不过多展示了,目测很多网站都用这种加密方式,其中的src链接都是blob:http://xxx格式的,且根据链接无法获取视频源。因为这并不是一个在线的视频存放地址,这样你通过爬虫脚本也无法下载该视频文件

    那么具体如何实现的呢?

    不急,咱们一步一步来:

    第一步:java 服务器接口,根据url 返回资源

    package com.wf.course.web.controller;
    
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.*;
    import java.net.MalformedURLException;
    import java.net.URL;
    import java.net.URLConnection;
    import java.net.URLEncoder;
    
    @Controller
    public class VideoController {
    
        @ResponseBody
        @RequestMapping("/getVideoSrc")
        public OutputStream getVideoSrc(HttpServletRequest httpServletRequest,
                                        HttpServletResponse httpServletResponse){
            //1.创建文件对象
            File f = new File("D:/test/x.mp4");
            //2.获取文件名称
            String fileName = f.getName();
            //3.导出文件
            String agent = httpServletRequest.getHeader("User-Agent").toUpperCase();
            InputStream fis = null;
            OutputStream os = null;
            try {
                //4.获取输入流
                fis = new BufferedInputStream(new FileInputStream(f.getPath()));
                byte[] buffer;
                buffer = new byte[fis.available()];
                fis.read(buffer);
                httpServletResponse.reset();
                //5.由于火狐和其他浏览器显示名称的方式不相同,需要进行不同的编码处理
                if(agent.indexOf("FIREFOX") != -1){//火狐浏览器
                    httpServletResponse.addHeader("Content-Disposition", "attachment;filename="+ new String(fileName.getBytes("GB2312"),"ISO-8859-1"));
                }else{//其他浏览器
                    httpServletResponse.addHeader("Content-Disposition", "attachment;filename="+ URLEncoder.encode(fileName, "UTF-8"));
                }
                //6.设置response编码
                httpServletResponse.setCharacterEncoding("UTF-8");
                httpServletResponse.addHeader("Content-Length", "" + f.length());
                //设置输出文件类型
                httpServletResponse.setContentType("video/mpeg4");
                //7.获取response输出流
                os = httpServletResponse.getOutputStream();
                os.flush();
                //8.输出文件
                os.write(buffer);
            }catch(Exception e){
                System.out.println(e.getMessage());
            } finally{
                //关闭流
                try {
                    if(fis != null){ fis.close(); }
    
                    if(os != null){ os.flush(); }
    
                    if(os != null){os.close(); }
    
                } catch (IOException e) {
                    System.out.println(e.getMessage());
                }
            }
    
            return os;
        }
    
    
        @RequestMapping("/getVideoBlob_V2")
        public OutputStream getVideoBlob_V2(HttpServletRequest httpServletRequest,
                                            HttpServletResponse httpServletResponse) {
    
            String httpUrl = "https://wangfang.oss-cn-qingdao.aliyuncs.com/wf_video/videoPath/863E1B126B81B7B60993CC0B9B1EC1EA.mp3";
            // 1.下载网络文件
            URL url = null;
            try {
                url = new URL(httpUrl);
            } catch (MalformedURLException e1) {
                e1.printStackTrace();
            }
    
            InputStream inStream = null;
            OutputStream outputStream = null;
            try {
    
                //2.获取链接
                URLConnection conn = url.openConnection();
                //3.输入流
                inStream = conn.getInputStream();
                httpServletResponse.reset();
                httpServletResponse.addHeader("Content-Disposition", "attachment;filename=" + httpUrl);
                //6.设置response编码
                httpServletResponse.setCharacterEncoding("UTF-8");//设置输出文件类型
                httpServletResponse.setContentType("video/mpeg4");
                //7.获取response输出流
                outputStream = httpServletResponse.getOutputStream();
                int byteRead;
                while ((byteRead = inStream.read()) != -1) {
                    outputStream.write(byteRead);
                }
    
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println(e);
            } finally {
    
                try {
                    inStream.close();
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
    
            return outputStream;
        }
    }

    第二步:页面添加<video>标签引用

    <video controls="controls"  preload="auto"  height="300" width="400" id="videoPath"    type="video/mp4">
                                             您的浏览器不支持html5!
                                          </video>

    第三步:页面js处理,调用接口,加载资源

    $(function () {
                var xhr = new XMLHttpRequest();//创建XMLHttpRequest对象
                xhr.open('GET', 'http://localhost:8080/getVideoBlob_V2', true);//配置请求方式、请求地址以及是否同步
                xhr.responseType = 'blob';//设置结果类型为blob;
                xhr.onload = function(e) {
                    alert(this.status);
                    if (this.status === 200) {
                        // 获取blob对象
                        var blob = this.response;
                        console.log(blob);
                        // 获取blob对象地址,并把值赋给容器
                        $("#videoPath").attr("src", URL.createObjectURL(blob));
                    }
                };
                xhr.send();
            });
    • 这里使用的最原生的XMLHttpRequest对象语法,这里最重要的一点是要设置responseType为blob,这样接收到response直接就是一个blob对象供我们使用。这个responseType属性不属于http头部信息,而是ajax请求中XHR对象的属性(默认为""也就是text类型,而在一些封装XHR的框架中,一般把默认值设为json)。这样就可以得到以blob:开头的临时url地址,而且在向服务端请求时页隐藏了真实的视频地址。
     
    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

    参考文章及感谢其作者:通过BLOB加密视频文件

  • 相关阅读:
    USACO 玛丽卡(最短路+枚举)
    POJ 1161 Walls(最短路+枚举)
    Windows 上配置Docker Desktop 的k8s
    菜鸡学算法--70. 爬楼梯
    CLR 异步函数
    【.NET Core开发实战学习笔记】依赖注入框架:管理服务的依赖与生命周期
    【.NET Core 开发实战学习笔记】StartUp:理解程序的启动过程
    .ef core 多对对关系的关联方法
    HttpGet请求传递数组(集合)
    使用wkhtmltopdf工具生成pdf
  • 原文地址:https://www.cnblogs.com/hero123/p/10856762.html
Copyright © 2011-2022 走看看