Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 国产剧情麻豆三级在线观看,韩国色三级伦不卡高清在线观看,二区三区在线

          整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          為什么視頻網(wǎng)站的視頻鏈接地址是blob

          從HTML5提供了video標(biāo)簽,在網(wǎng)頁中播放視頻已經(jīng)變成一個(gè)非常簡單的事,只要一個(gè)video標(biāo)簽,src屬性設(shè)置為視頻的地址就完事了。由于src指向真實(shí)的視頻網(wǎng)絡(luò)地址,在早期一般網(wǎng)站資源文件不怎么通過referer設(shè)置防盜鏈,當(dāng)我們拿到視頻的地址后可以隨意的下載或使用(每次放假回家,就會(huì)有親戚找我?guī)兔囊恍┮曨l網(wǎng)站上下東西)。

          目前的云存儲(chǔ)服務(wù)商大部分都支持referer防盜鏈。其原理就是在訪問資源時(shí),請(qǐng)求頭會(huì)帶上發(fā)起請(qǐng)求的頁面地址,判斷其不存在(表示直接訪問圖片地址)或不在白名單內(nèi),即為盜鏈。

          可是從某個(gè)時(shí)間開始我們打開調(diào)試工具去看各大視頻網(wǎng)站的視頻src會(huì)發(fā)現(xiàn),它們統(tǒng)統(tǒng)變成了這樣的形式。

          拿b站的一個(gè)視頻來看,紅框中的視頻地址,這個(gè)blob是個(gè)什么東西?。

          其實(shí)這個(gè)Blob URL也不是什么新技術(shù),國內(nèi)外出來都有一陣子了,但是網(wǎng)上的相關(guān)的文章不多也不是很詳細(xì),今天就和大家一起分享學(xué)習(xí)一下。

          Blob和ArrayBuffer

          最早是數(shù)據(jù)庫直接用Blob來存儲(chǔ)二進(jìn)制數(shù)據(jù)對(duì)象,這樣就不用關(guān)注存儲(chǔ)數(shù)據(jù)的格式了。在web領(lǐng)域,Blob對(duì)象表示一個(gè)只讀原始數(shù)據(jù)的類文件對(duì)象,雖然是二進(jìn)制原始數(shù)據(jù)但是類似文件的對(duì)象,因此可以像操作文件對(duì)象一樣操作Blob對(duì)象。

          ArrayBuffer對(duì)象用來表示通用的、固定長度的原始二進(jìn)制數(shù)據(jù)緩沖區(qū)。我們可以通過new ArrayBuffer(length)來獲得一片連續(xù)的內(nèi)存空間,它不能直接讀寫,但可根據(jù)需要將其傳遞到TypedArray視圖或 DataView 對(duì)象來解釋原始緩沖區(qū)。實(shí)際上視圖只是給你提供了一個(gè)某種類型的讀寫接口,讓你可以操作ArrayBuffer里的數(shù)據(jù)。TypedArray需指定一個(gè)數(shù)組類型來保證數(shù)組成員都是同一個(gè)數(shù)據(jù)類型,而DataView數(shù)組成員可以是不同的數(shù)據(jù)類型。

          TypedArray視圖的類型數(shù)組對(duì)象有以下幾個(gè):

          • Int8Array:8位有符號(hào)整數(shù),長度1個(gè)字節(jié)。
          • Uint8Array:8位無符號(hào)整數(shù),長度1個(gè)字節(jié)。
          • Uint8ClampedArray:8位無符號(hào)整數(shù),長度1個(gè)字節(jié),溢出處理不同。
          • Int16Array:16位有符號(hào)整數(shù),長度2個(gè)字節(jié)。
          • Uint16Array:16位無符號(hào)整數(shù),長度2個(gè)字節(jié)。
          • Int32Array:32位有符號(hào)整數(shù),長度4個(gè)字節(jié)。
          • Uint32Array:32位無符號(hào)整數(shù),長度4個(gè)字節(jié)。
          • Float32Array:32位浮點(diǎn)數(shù),長度4個(gè)字節(jié)。
          • Float64Array:64位浮點(diǎn)數(shù),長度8個(gè)字節(jié)。

          Blob與ArrayBuffer的區(qū)別是,除了原始字節(jié)以外它還提供了mime type作為元數(shù)據(jù),Blob和ArrayBuffer之間可以進(jìn)行轉(zhuǎn)換。

          File對(duì)象其實(shí)繼承自Blob對(duì)象,并提供了提供了name , lastModifiedDate, size ,type 等基礎(chǔ)元數(shù)據(jù)。

          創(chuàng)建Blob對(duì)象并轉(zhuǎn)換成ArrayBuffer:

          //創(chuàng)建一個(gè)以二進(jìn)制數(shù)據(jù)存儲(chǔ)的html文件
          const text = "<div>hello world</div>";
          const blob = new Blob([text], { type: "text/html" }); // Blob {size: 22, type: "text/html"}
          //以文本讀取
          const textReader = new FileReader();
          textReader.readAsText(blob);
          textReader.onload = function() {
           console.log(textReader.result); // <div>hello world</div>
          };
          //以ArrayBuffer形式讀取
          const bufReader = new FileReader();
          bufReader.readAsArrayBuffer(blob);
          bufReader.onload = function() {
           console.log(new Uint8Array(bufReader.result)); // Uint8Array(22) [60, 100, 105, 118, 62, 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 60, 47, 100, 105, 118, 62]
          };
          

          創(chuàng)建一個(gè)相同數(shù)據(jù)的ArrayBuffer,并轉(zhuǎn)換成Blob:

          //我們直接創(chuàng)建一個(gè)Uint8Array并填入上面的數(shù)據(jù)
          const u8Buf = new Uint8Array([60, 100, 105, 118, 62, 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 60, 47, 100, 105, 118, 62]);
          const u8Blob = new Blob([u8Buf], { type: "text/html" }); // Blob {size: 22, type: "text/html"}
          const textReader = new FileReader();
          textReader.readAsText(u8Blob);
          textReader.onload = function() {
           console.log(textReader.result); // 同樣得到div>hello world</div>
          };
          

          更多Blob和ArrayBuffer的相關(guān)內(nèi)容可以參看下面的資料:

          • MDN Blob
          • MDN ArrayBuffer
          • 阮一峰js標(biāo)準(zhǔn)參考教程二進(jìn)制數(shù)組

          URL.createObjectURL

          video標(biāo)簽,audio標(biāo)簽還是img標(biāo)簽的src屬性,不管是相對(duì)路徑,絕對(duì)路徑,或者一個(gè)網(wǎng)絡(luò)地址,歸根結(jié)底都是指向一個(gè)文件資源的地址。既然我們知道了Blob其實(shí)是一個(gè)可以當(dāng)作文件用的二進(jìn)制數(shù)據(jù),那么只要我們可以生成一個(gè)指向Blob的地址,是不是就可以用在這些標(biāo)簽的src屬性上,答案肯定是可以的,這里我們要用到的就是URL.createObjectURL()。

          const objectURL = URL.createObjectURL(object); //blob:http://localhost:1234/abcedfgh-1234-1234-1234-abcdefghijkl
          復(fù)制代碼
          

          這里的object參數(shù)是用于創(chuàng)建URL的File對(duì)象、Blob 對(duì)象或者 MediaSource 對(duì)象,生成的鏈接就是以blob:開頭的一段地址,表示指向的是一個(gè)二進(jìn)制數(shù)據(jù)。

          其中l(wèi)ocalhost:1234是當(dāng)前網(wǎng)頁的主機(jī)名稱和端口號(hào),也就是location.host,而且這個(gè)Blob URL是可以直接訪問的。需要注意的是,即使是同樣的二進(jìn)制數(shù)據(jù),每調(diào)用一次URL.createObjectURL方法,就會(huì)得到一個(gè)不一樣的Blob URL。這個(gè)URL的存在時(shí)間,等同于網(wǎng)頁的存在時(shí)間,一旦網(wǎng)頁刷新或卸載,這個(gè)Blob URL就失效。

          通過URL.revokeObjectURL(objectURL) 釋放一個(gè)之前已經(jīng)存在的、通過調(diào)用 URL.createObjectURL() 創(chuàng)建的 URL 對(duì)象。當(dāng)你結(jié)束使用某個(gè) URL 對(duì)象之后,應(yīng)該通過調(diào)用這個(gè)方法來讓瀏覽器知道不用在內(nèi)存中繼續(xù)保留對(duì)這個(gè)文件的引用了,允許平臺(tái)在合適的時(shí)機(jī)進(jìn)行垃圾收集。

          如果是以文件協(xié)議打開的html文件(即url為file://開頭),則地址中http://localhost:1234會(huì)變成null,而且此時(shí)這個(gè)Blob URL是無法直接訪問的。

          實(shí)戰(zhàn)一:上傳圖片預(yù)覽

          有時(shí)我們通過input上傳圖片文件之前,會(huì)希望可以預(yù)覽一下圖片,這個(gè)時(shí)候就可以通過前面所學(xué)到的東西實(shí)現(xiàn),而且非常簡單。

          html

          <input id="upload" type="file" />
          <img id="preview" src="" alt="預(yù)覽"/>
          

          javascript

          const upload = document.querySelector("#upload");
          const preview = document.querySelector("#preview");
          upload.onchange = function() {
           const file = upload.files[0]; //File對(duì)象
           const src = URL.createObjectURL(file); 
           preview.src = src;
          };
          

          這樣一個(gè)圖片上傳預(yù)覽就實(shí)現(xiàn)了,同樣這個(gè)方法也適用于上傳視頻的預(yù)覽。

          實(shí)戰(zhàn)二:以Blob URL加載網(wǎng)絡(luò)視頻

          現(xiàn)在我們有一個(gè)網(wǎng)絡(luò)視頻的地址,怎么能將這個(gè)視頻地址變成Blob URL是形式呢,思路肯定是先要拿到存儲(chǔ)這個(gè)視頻原始數(shù)據(jù)的Blob對(duì)象,但是不同于input上傳可以直接拿到File對(duì)象,我們只有一個(gè)網(wǎng)絡(luò)地址。

          我們知道平時(shí)請(qǐng)求接口我們可以使用xhr(jquery里的ajax和axios就是封裝的這個(gè))或fetch,請(qǐng)求一個(gè)服務(wù)端地址可以返回我們相應(yīng)的數(shù)據(jù),那如果我們用xhr或者fetch去請(qǐng)求一個(gè)圖片或視頻地址會(huì)返回什么呢?當(dāng)然是返回圖片和視頻的數(shù)據(jù),只不過要設(shè)置正確responseType才能拿到我們想要的格式數(shù)據(jù)。

          function ajax(url, cb) {
           const xhr = new XMLHttpRequest();
           xhr.open("get", url);
           xhr.responseType = "blob"; // ""|"text"-字符串 "blob"-Blob對(duì)象 "arraybuffer"-ArrayBuffer對(duì)象
           xhr.onload = function() {
           cb(xhr.response);
           };
           xhr.send();
          }
          

          注意XMLHttpRequest和Fetch API請(qǐng)求會(huì)有跨域問題,可以通過跨域資源共享(CORS)解決。

          看到responseType可以設(shè)置blob和arraybuffer我們應(yīng)該就有譜了,請(qǐng)求返回一個(gè)Blob對(duì)象,或者返回ArrayBuffer對(duì)象轉(zhuǎn)換成Blob對(duì)象,然后通過createObjectURL生成地址賦值給視頻的src屬性就可以了,這里我們直接請(qǐng)求一個(gè)Blob對(duì)象。

          ajax('video.mp4', function(res){
           const src = URL.createObjectURL(res); 
           video.src = src;
          })
          

          用調(diào)試工具查看視頻標(biāo)簽的src屬性已經(jīng)變成一個(gè)Blob URL,表面上看起來是不是和各大視頻網(wǎng)站形式一致了,但是考慮一個(gè)問題,這種形式要等到請(qǐng)求完全部視頻數(shù)據(jù)才能播放,小視頻還好說,要是視頻資源大一點(diǎn)豈不爆炸,顯然各大視頻網(wǎng)站不可能這么干。

          解決這個(gè)問題的方法就是流媒體,其帶給我們最直觀體驗(yàn)就是使媒體文件可以邊下邊播(像我這樣的90后男性最早體會(huì)到流媒體好處的應(yīng)該是源于那款快子頭的播放器),web端如果要使用流媒體,有多個(gè)流媒體協(xié)議可以供我們選擇。

          HLS和MPEG DASH

          HLS (HTTP Live Streaming), 是由 Apple 公司實(shí)現(xiàn)的基于 HTTP 的媒體流傳輸協(xié)議。HLS以ts為傳輸格式,m3u8為索引文件(文件中包含了所要用到的ts文件名稱,時(shí)長等信息,可以用播放器播放,也可以用vscode之類的編輯器打開查看),在移動(dòng)端大部分瀏覽器都支持,也就是說你可以用video標(biāo)簽直接加載一個(gè)m3u8文件播放視頻或者直播,但是在pc端,除了蘋果的Safari,需要引入庫來支持。

          用到此方案的視頻網(wǎng)站比如優(yōu)酷,可以在視頻播放時(shí)通過調(diào)試查看Network里的xhr請(qǐng)求,會(huì)發(fā)現(xiàn)一個(gè)m3u8文件,和每隔一段時(shí)間請(qǐng)求幾個(gè)ts文件。

          但是除了HLS,還有Adobe的HDS,微軟的MSS,方案一多就要有個(gè)標(biāo)準(zhǔn)點(diǎn)的東西,于是就有了MPEG DASH。

          DASH(Dynamic Adaptive Streaming over HTTP) ,是一種在互聯(lián)網(wǎng)上傳送動(dòng)態(tài)碼率的Video Streaming技術(shù),類似于蘋果的HLS,DASH會(huì)通過media presentation description (MPD)將視頻內(nèi)容切片成一個(gè)很短的文件片段,每個(gè)切片都有多個(gè)不同的碼率,DASH Client可以根據(jù)網(wǎng)絡(luò)的情況選擇一個(gè)碼率進(jìn)行播放,支持在不同碼率之間無縫切換。

          Youtube,B站都是用的這個(gè)方案。這個(gè)方案索引文件通常是mpd文件(類似HLS的m3u8文件功能),傳輸格式推薦的是fmp4(Fragmented MP4),文件擴(kuò)展名通常為.m4s或直接用.mp4。所以用調(diào)試查看b站視頻播放時(shí)的網(wǎng)絡(luò)請(qǐng)求,會(huì)發(fā)現(xiàn)每隔一段時(shí)間有幾個(gè)m4s文件請(qǐng)求。

          不管是HLS還是DASH們,都有對(duì)應(yīng)的庫甚至是高級(jí)的播放器方便我們使用,但我們其實(shí)是想要學(xué)習(xí)一點(diǎn)實(shí)現(xiàn)。其實(shí)拋開掉索引文件的解析拿到實(shí)際媒體文件的傳輸?shù)刂罚瑪[在我們面前的只有一個(gè)如何將多個(gè)視頻數(shù)據(jù)合并讓video標(biāo)簽可以無縫播放。

          與之相關(guān)的一篇B站文章推薦給感興趣的朋友:我們?yōu)槭裁词褂肈ASH

          MediaSource

          video標(biāo)簽src指向一個(gè)視頻地址,視頻播完了再將src修改為下一段的視頻地址然后播放,這顯然不符合我們無縫播放的要求。其實(shí)有了我們前面Blob URL的學(xué)習(xí),我們可能就會(huì)想到一個(gè)思路,用Blob URL指向一個(gè)視頻二進(jìn)制數(shù)據(jù),然后不斷將下一段視頻的二進(jìn)制數(shù)據(jù)添加拼接進(jìn)去。這樣就可以在不影響播放的情況下,不斷的更新視頻內(nèi)容并播放下去,想想是不是有點(diǎn)流的意思出來了。

          要實(shí)現(xiàn)這個(gè)功能我們要通過MediaSource來實(shí)現(xiàn),MediaSource接口功能也很純粹,作為一個(gè)媒體數(shù)據(jù)容器可以和HTMLMediaElement進(jìn)行綁定。基本流程就是通過URL.createObjectURL創(chuàng)建容器的BLob URL,設(shè)置到video標(biāo)簽的src上,在播放過程中,我們?nèi)匀豢梢酝ㄟ^MediaSource.appendBuffer方法往容器里添加數(shù)據(jù),達(dá)到更新視頻內(nèi)容的目的。

          實(shí)現(xiàn)代碼如下:

          const video = document.querySelector('video');
          //視頻資源存放路徑,假設(shè)下面有5個(gè)分段視頻 video1.mp4 ~ video5.mp4,第一個(gè)段為初始化視頻init.mp4
          const assetURL = "http://www.demo.com";
          //視頻格式和編碼信息,主要為判斷瀏覽器是否支持視頻格式,但如果信息和視頻不符可能會(huì)報(bào)錯(cuò)
          const mimeCodec = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"'; 
          if ('MediaSource' in window && MediaSource.isTypeSupported(mimeCodec)) {
           const mediaSource = new MediaSource();
           video.src = URL.createObjectURL(mediaSource); //將video與MediaSource綁定,此處生成一個(gè)Blob URL
           mediaSource.addEventListener('sourceopen', sourceOpen); //可以理解為容器打開
          } else {
           //瀏覽器不支持該視頻格式
           console.error('Unsupported MIME type or codec: ', mimeCodec);
          }
          function sourceOpen () {
           const mediaSource = this;
           const sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
           let i = 1;
           function getNextVideo(url) {
           //ajax代碼實(shí)現(xiàn)翻看上文,數(shù)據(jù)請(qǐng)求類型為arraybuffer
           ajax(url, function(buf) {
           //往容器中添加請(qǐng)求到的數(shù)據(jù),不會(huì)影響當(dāng)下的視頻播放。
           sourceBuffer.appendBuffer(buf);
           });
           }
           //每次appendBuffer數(shù)據(jù)更新完之后就會(huì)觸發(fā)
           sourceBuffer.addEventListener("updateend", function() {
           if (i === 1) {
           //第一個(gè)初始化視頻加載完就開始播放
           video.play();
           }
           if (i < 6) {
           //一段視頻加載完成后,請(qǐng)求下一段視頻
           getNextVideo(`${assetURL}/video${i}.mp4`);
           }
           if (i === 6) {
           //全部視頻片段加載完關(guān)閉容器
           mediaSource.endOfStream();
           URL.revokeObjectURL(video.src); //Blob URL已經(jīng)使用并加載,不需要再次使用的話可以釋放掉。
           }
           i++;
           });
           //加載初始視頻
           getNextVideo(`${assetURL}/init.mp4`);
          };
          

          這段代碼修改自MDN的MediaSource詞條中的示例代碼,原例子中只有加載一段視頻,我修改為了多段視頻,代碼里面很多地方還可以優(yōu)化精簡,這里沒做就當(dāng)是為了方便我們看邏輯。

          此時(shí)我們已經(jīng)基本實(shí)現(xiàn)了一個(gè)簡易的流媒體播放功能,如果愿意可以再加入m3u8或mpd文件的解析,設(shè)計(jì)一下UI界面,就可以實(shí)現(xiàn)一個(gè)流媒體播放器了。

          最后提一下一個(gè)坑,很多人跑了MDN的MediaSource示例代碼,可能會(huì)發(fā)現(xiàn)使用官方提供的視頻是沒問題的,但是用了自己的mp4視頻就會(huì)報(bào)錯(cuò),這是因?yàn)閒mp4文件擴(kuò)展名通常為.m4s或直接用.mp4,但卻是特殊的mp4文件。

          Fragmented MP4

          通常我們使用的mp4文件是嵌套結(jié)構(gòu)的,客戶端必須要從頭加載一個(gè) MP4 文件,才能夠完整播放,不能從中間一段開始播放。而Fragmented MP4(簡稱fmp4),就如它的名字碎片mp4,是由一系列的片段組成,如果服務(wù)器支持 byte-range 請(qǐng)求,那么,這些片段可以獨(dú)立的進(jìn)行請(qǐng)求到客戶端進(jìn)行播放,而不需要加載整個(gè)文件。

          我們可以通過這個(gè)網(wǎng)站判斷一個(gè)mp4文件是否為Fragmented MP4,網(wǎng)站地址。

          我們通過FFmpeg或Bento4的mp4fragment來將普通mp4轉(zhuǎn)換為Fragmented MP4,兩個(gè)工具都是命令行工具,按照各自系統(tǒng)下載下來對(duì)應(yīng)的壓縮包,解壓后設(shè)置環(huán)境變量指向文件夾中的bin目錄,就可以使用相關(guān)命令了。

          Bento4的mp4fragment,沒有太多參數(shù),命令如下:

          mp4fragment video.mp4 video-fragmented.mp4
          

          FFmpeg會(huì)需要設(shè)置一些參數(shù),命令如下:

          ffmpeg -i video.mp4 -movflags empty_moov+default_base_moof+frag_keyframe video-fragmented.mp4
          

          Tips:網(wǎng)上大部分的資料中轉(zhuǎn)換時(shí)是不帶default_base_moof這個(gè)參數(shù)的,雖然可以轉(zhuǎn)換成功,但是經(jīng)測試如果不添加此參數(shù)網(wǎng)頁中MediaSource處理視頻時(shí)會(huì)報(bào)錯(cuò)。

          視頻的切割分段可以使用Bento4的mp4slipt,命令如下:

          mp4split video.mp4 --media-segment video-%llu.mp4 --pattern-parameters N
          

          最后

          之所以寫這篇文章其實(shí)是之前公司有個(gè)需求要了解一下Blob URL,稍微看了一下,后來不了了之。這次忙里偷閑重拾起來把它搞清楚,一邊學(xué)習(xí)一邊記錄,這篇文章中的很多點(diǎn)展開了其實(shí)有很多內(nèi)容,希望大家看了這篇文章能夠有所啟發(fā)或引起興趣,我的目的也就達(dá)到了,另外視頻這方面的東西真的是有點(diǎn)深的,文章中如果有錯(cuò)誤和疏漏也歡迎大家指出,我將及時(shí)修正。

          作者:wangzy2019

          鏈接:https://juejin.im/post/5d1ea7a8e51d454fd8057bea

          來源:掘金

          、首先看下大廠的(愛奇藝)視頻的播放地址加密

          紫霞仙子

          2、Node.js實(shí)現(xiàn)(服務(wù)器端)

          let http = require('http');
          let fs = require('fs');
          let express = require('express');
          let app = express();
          /**
           * 前端訪問頁面
           */
          app.get('/', function(req, res) {
            res.sendfile('./index.html')  // 查看標(biāo)題3前端頁面的index.html
          })
          
          /*
           * 實(shí)現(xiàn)流傳送
           */
          app.post('/', function(req, res) {
            fs.createReadStream('./video.mp4')   // 讀取當(dāng)前目錄下的video.mp4視頻
              .on("open",chunk=>{
                console.log("chunk", chunk)  // 準(zhǔn)備好發(fā)送數(shù)據(jù)
              })
              .on("data",chunk=>{
                console.log(chunk)
                res.write(chunk);  //發(fā)送數(shù)據(jù)
              })
              .on("end",()=>{
                console.log('end')
                res.end();   //發(fā)送結(jié)束
              })
          })
          let port = 8008;
          var server = http.createServer(app);
          server.listen(port);
          console.log('listening on port:' + port)

          3、前端頁面(index.html)

          <html>
            <head>
              <meta charset="utf-8" />
              <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
              <style type="text/css">
                html, body {
                  margin: 0;
                  padding: 0;
                  width: 100%;
                  height: 100%;
                  text-align: center;
                }
                .video{
                  width: 384px;
                  height: 683px;
                  margin: 0 auto;
                  display: inline-block;
                }
              </style>
            </head>
            <body>
              <video class="video" id="video" controls="controls"></video>
              <script type="text/javascript">
                var xhr = new XMLHttpRequest();
                xhr.open('POST', './', true);
                xhr.responseType = 'blob';   // 注意是blob
                xhr.onload = function(e) {
                  if (this.status == 200) {//請(qǐng)求成功
                    //獲取blob對(duì)象
                    var blob = this.response;
                    console.log(this.response)
                    //獲取blob對(duì)象地址,并把值賦給容器
                    $("#video").attr("src", URL.createObjectURL(blob));
                  }
                };
                xhr.send();
              </script>
          	</body>
          </html>

          4、實(shí)現(xiàn)效果

          瀏覽器中輸入地址:http://localhost:8008/index.html 即可看到效果。

          Node.js實(shí)現(xiàn)視頻地址Blob加密

          火狐瀏覽器為例

          在此操作之前我們需要在火狐瀏覽器里安裝“User Agent Switcher”插件。

          • 打開火狐瀏覽器,點(diǎn)擊右上角“三橫線”,“附加組件”

          • “查看更多附加組件”

          • 在附加組件搜索框里搜索“User Agent Switcher”,下載一個(gè)自己喜歡的,我這里以第一個(gè)為例。

          • 安裝好了以后再火狐瀏覽器右上角會(huì)看到相應(yīng)的圖標(biāo)。

          【重點(diǎn)】將插件安裝好了以后我們將瀏覽器設(shè)置為移動(dòng)端,然后才開始下面的操作。

          1、打開視頻所在的網(wǎng)頁

          圖1

          圖2

          2、在網(wǎng)頁空白地方單擊鼠標(biāo)【右鍵】—>【檢查】

          3、此時(shí)我們按照下圖進(jìn)行操作,第一步點(diǎn)擊左下角帶箭頭的按鈕,第二步再點(diǎn)擊視頻中的播放按鈕(注意:當(dāng)前一定不要打開播放視頻),第三步我們將看到播放按鈕所對(duì)應(yīng)的網(wǎng)頁源代碼。

          4、此時(shí),結(jié)合上一部操作找到源代碼以后,我們這個(gè)時(shí)候才打開視頻,讓視頻播放,我們將會(huì)看到視頻的地址

          5、雙擊視頻地址,復(fù)制。

          6、粘貼復(fù)制好的視頻在瀏覽器地址框內(nèi),回車(Enter)。

          此時(shí)我們可以看到視頻已經(jīng)被我們提取了出來。

          7、鼠標(biāo)放在視頻界面上,右鍵,點(diǎn)擊【另存視頻為】

          搞定!

          如果你覺得有用,歡迎分享給身邊的人。關(guān)注我,我還有很多你意想不到的“黑科技”。


          主站蜘蛛池模板: 亚洲一区二区三区在线观看精品中文 | 一区二区三区杨幂在线观看| 一本大道东京热无码一区| 一区二区中文字幕| 国产A∨国片精品一区二区| 免费播放一区二区三区| 四虎永久在线精品免费一区二区| 亚洲视频一区在线| 国产精品无码一区二区三级| 日本精品一区二区在线播放| 亚洲熟妇av一区| 亚洲电影国产一区| 国产亚洲福利精品一区| 中文字幕一区二区三区精华液| 国产成人一区二区三区高清| 一本久久精品一区二区| 精品女同一区二区三区免费站 | 69福利视频一区二区| 亚洲色精品vr一区二区三区| 国产色精品vr一区区三区| 波多野结衣中文一区| 国产亚洲综合一区二区三区| 日本香蕉一区二区三区| 日本无卡码免费一区二区三区| 亚洲高清毛片一区二区| 无码一区18禁3D| 欧洲精品码一区二区三区| 免费看AV毛片一区二区三区| 精品国产日韩亚洲一区91| 日韩精品一区二区三区国语自制| 亚洲国产欧美国产综合一区| 国产SUV精品一区二区四| 韩国一区二区三区视频| 精品免费AV一区二区三区| 国产精品一区不卡| 亚洲av高清在线观看一区二区| 肥臀熟女一区二区三区| 国产另类TS人妖一区二区 | 末成年女AV片一区二区| 一区二区在线观看视频| 在线观看视频一区二区|