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加密視頻文件

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM