通過BLOB加密視頻文件

前言
  • 現在許多視頻在線觀看網站,你如果打開chrome查看其video標簽,會發現它的src是一個以blob:開頭的地址。比如下面這里是B站的截圖,可以看到他這里引入的并不是一個在線的視頻存放地址,這樣你通過爬蟲腳本也無法下載該視頻文件,通過一個new tab打開也于事無補,會提示你地址錯誤。
    image.png
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。
代碼實現
  • 服務端使用的nodejs,koa框架,這里的操作很簡單,就是用fs.readFileSync直接打開視頻文件,得到的data結果是二進制的數據,直接作為結果返回。
const Koa = require('koa')
const Router = require('koa-router')
const buffer = require('buffer');
const app = new Koa()
const router = new Router()
const fs = require('fs')
const video = async (ctx, next) => {
  try {
    // open 一個放在服務器的視頻
    let data = fs.readFileSync('XXX.XXX.XXX/simple.mp4')
    ctx.response.body = data
  } catch (e) {
    return Promise.reject({
      status: 500,
      message: '視頻傳輸錯誤'
    })
  }
  next()
}

router.get('/video', video)

app.use(router.routes()).use(router.allowedMethods())
app.listen(3001)
  • 接下來看前端代碼,這里使用的最原生的XMLHttpRequest對象語法,這里最重要的一點是要設置responseType為blob,這樣接收到response直接就是一個blob對象供我們使用。這個responseType屬性不屬于http頭部信息,而是ajax請求中XHR對象的屬性(默認為""也就是text類型,而在一些封裝XHR的框架中,一般把默認值設為json)。
    let xhr = new XMLHttpRequest()
    xhr.open('GET', 'http://localhost:3001/video', true)
    xhr.responseType = 'blob'
    xhr.onload = function(e) {
      if (this.status === 200) {
        // 獲取blob對象
        let blob = this.response
        console.log(blob)
        // 獲取blob對象地址,并把值賦給容器
        $("#sound").attr("src", URL.createObjectURL(blob));
      }
    }
    xhr.send()
  • 這樣就可以得到以blob:開頭的臨時url地址,而且在向服務端請求時頁隱藏了真實的視頻地址。
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容