前端使用 fetch() 流式下載.mp4視頻文件,跟蹤進度

来源:https://www.cnblogs.com/xiyouchen/archive/2023/01/28/17070200.html
-Advertisement-
Play Games

參考:https://www.cnblogs.com/lxlx1798/articles/16969244.html 要麼使用流讀取器,要麼使用 Reponse 的方法來獲取結果,不能同時使用兩種方法來讀取相同的響應。 直接獲取: Response.blob() 方法返回一個 resolve 返回值 ...


參考:https://www.cnblogs.com/lxlx1798/articles/16969244.html

要麼使用流讀取器,要麼使用 Reponse 的方法來獲取結果,不能同時使用兩種方法來讀取相同的響應。

直接獲取:

Response.blob() 方法返回一個 resolve 返回值為 Blob 對象的 Promise

fetch(videoUrl).then(res => {
                const p = res.blob()
                return res.blob()
            }).then(blob => {
                const a = document.createElement("a");
                a.style.display = 'none'
                document.body.append(a)
                const url = window.URL.createObjectURL(blob)
                a.href = url
                a.download = item.name
                a.click()
                document.body.removeChild(a)
                window.URL.revokeObjectURL(url)
            })

流讀取:

Response.body 是一個 ReadableStream 對象

ReadableStream.getReader() 創建流讀取器,並且會把流鎖定,預設返回的是 ReadableStreamDefaultReader 類型

The getReader() method of the ReadableStream interface creates a reader and locks the stream to it. While the stream is locked, no other reader can be acquired until this one is released.

response.headers.get('Content-Length') 得到響應的總長度

ReadableStreamDefaultReader.read() 方法得到一個 Promise 對象,可以獲取到流內部序列中的下一個分塊,迴圈調用直到完成,同時收集數據得到一個 Uint8Array 數組

最後轉換成 Blob 就可以完成下載了

const videoUrl = 'video url'
const response = await fetch(videoUrl) const reader = response.body.getReader() const contentLength = +response.headers.get('Content-Length') let receivedLength = 0 let chunks = [] while (true) { const { done, value } = await reader.read(); if (done) { break } chunks.push(value) receivedLength += value.length // 下載進度 console.log(`Reveived ${receivedLength} of ${contentLength}`) } const a = document.createElement("a"); a.style.display = 'none' document.body.append(a) const url = window.URL.createObjectURL(new Blob(chunks, { type: 'video/mp4'} )) a.href = url a.download = item.name a.click() document.body.removeChild(a) window.URL.revokeObjectURL(url)

用到的一些方法:

fetch()

The global fetch() method starts the process of fetching a resource from the network, returning a promise which is fulfilled once the response is available.

The promise resolves to the Response object representing the response to your request.

fetch() promise only rejects when a network error is encountered (which is usually when there's a permissions issue or similar). A fetch() promise does not reject on HTTP errors (404, etc.). Instead, a then() handler must check the Response.ok and/or Response.status properties.

WindowOrWorkerGlobalScope is implemented by both Window and WorkerGlobalScope, which means that the fetch() method is available in pretty much any context in which you might want to fetch resources.

The fetch() method is controlled by the connect-src directive of Content Security Policy rather than the directive of the resources it's retrieving.

 

ReadableStream.getReader()

The getReader() method of the ReadableStream interface creates a reader and locks the stream to it. While the stream is locked, no other reader can be acquired until this one is released.

ReadableStreamDefaultReader.read()

The read() method of the ReadableStreamDefaultReader interface returns a Promise providing access to the next chunk in the stream's internal queue.

URL.createObjectURL()

The URL.createObjectURL() static method creates a string containing a URL representing the object given in the parameter.

The URL lifetime is tied to the document in the window on which it was created. The new object URL represents the specified File object or Blob object.

To release an object URL, call revokeObjectURL().

URL.revokeObjectURL()

The URL.revokeObjectURL() static method releases an existing object URL which was previously created by calling URL.createObjectURL().

Call this method when you've finished using an object URL to let the browser know not to keep the reference to the file any longer.

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Win11安裝VMware Workstation Pro,Centos,Xshell,Xftp(Linux學習需要) 註意:1.win11不能安裝太低版本的VMware Workstation Pro,否則啟動linux會出現藍屏 ​ 2.win11是預設沒有開虛擬機平臺支持的,所以同時也要開啟, ...
  • 前言 本篇我將介紹 Keil C51 和 MDK-ARM 兩大集成開發環境的安裝包下載方法,幫助大家安全快速的從官網下載安裝包。 博主編寫了軟體安裝教程,可以在安裝包下載完成後,跳轉觀看圖文教程進行軟體的安裝與註冊。 待更新 Keil 官網 Keil 官網 >> 點擊跳轉 Keil C51 官網下載 ...
  • 痞子衡單片機排行榜(2022Q4) 繼2020年開辦的《痞子衡嵌入式半月刊》之後,從2023年1月份開始痞子衡將為大家帶來新項目《痞子衡單片機排行榜》(一年分四季,每個季度發佈一期),以MCU主頻和Coremark跑分為基礎(後期會加入更多指標),搜羅國內外8051/ARM/RISC-V等不同賽道的 ...
  • 固件更新 需將小米AX9000路由支持安裝Docker,但正式版並沒有該功能需更新為開發板Rom,直接在小米路由官網下載固件更新即可,當前正式版最新固件為1.0.165,開發板固件為:1.0.140; 固件更新為140開發版本後即可在小米路由管理頁面的高級設置項中看到DOCKER的選項; 安裝Doc ...
  • 一:背景 1. 講故事 大家都知道資料庫應用程式 它天生需要圍繞著數據文件打轉,諸如包含數據的 .mdf,事務日誌的 .ldf,很多時候深入瞭解這兩類文件的合成原理,差不多對資料庫就能理解一半了,關於 .mdf 的合成前面的文章已經有所介紹,這篇我們來聊一下 .ldf 的一些內部知識,比如 LSN。 ...
  • 本文基於此: Flutter中文網 一、安裝和運行Flutter的系統環境要求 想要安裝並運行 Flutter,你的開發環境需要最低滿足以下要求: 操作系統:macOS 磁碟空間:2.8 GB(不包括IDE/tools的磁碟空間)。 工具:Flutter使用git進行安裝和升級。我們建議安裝Xcod ...
  • 主題說明 打開博客園的隨筆詳細頁、標簽頁等,都是整頁重新載入,比較影響體驗。SPA 應用可以減少整頁載入,實現局部刷新,本皮膚通過 Vue3 + TS + Vite 開發的。有些細節待日後逐步完善,隨筆的閱讀和使用基本上沒有問題,文章、日記、部分側邊欄內容還沒有實現。 倉庫地址:GitHub,請點個 ...
  • 值和類型 八種數據類型 undefined、null、boolean、number、string、symbol、bigint、object 原始值和引用值 原始值:按值訪問。值存儲在棧中。變數賦值傳遞時會創建該值的副本,兩個變數(複製與被覆制)完全獨立。 常見原始值類型:undefined、null ...
一周排行
    -Advertisement-
    Play Games
  • GoF之工廠模式 @目錄GoF之工廠模式每博一文案1. 簡單說明“23種設計模式”1.2 介紹工廠模式的三種形態1.3 簡單工廠模式(靜態工廠模式)1.3.1 簡單工廠模式的優缺點:1.4 工廠方法模式1.4.1 工廠方法模式的優缺點:1.5 抽象工廠模式1.6 抽象工廠模式的優缺點:2. 總結:3 ...
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 本章將和大家分享ES的數據同步方案和ES集群相關知識。廢話不多說,下麵我們直接進入主題。 一、ES數據同步 1、數據同步問題 Elasticsearch中的酒店數據來自於mysql資料庫,因此mysql數據發生改變時,Elasticsearch也必須跟著改變,這個就是Elasticsearch與my ...
  • 引言 在我們之前的文章中介紹過使用Bogus生成模擬測試數據,今天來講解一下功能更加強大自動生成測試數據的工具的庫"AutoFixture"。 什麼是AutoFixture? AutoFixture 是一個針對 .NET 的開源庫,旨在最大程度地減少單元測試中的“安排(Arrange)”階段,以提高 ...
  • 經過前面幾個部分學習,相信學過的同學已經能夠掌握 .NET Emit 這種中間語言,並能使得它來編寫一些應用,以提高程式的性能。隨著 IL 指令篇的結束,本系列也已經接近尾聲,在這接近結束的最後,會提供幾個可供直接使用的示例,以供大伙分析或使用在項目中。 ...
  • 當從不同來源導入Excel數據時,可能存在重覆的記錄。為了確保數據的準確性,通常需要刪除這些重覆的行。手動查找並刪除可能會非常耗費時間,而通過編程腳本則可以實現在短時間內處理大量數據。本文將提供一個使用C# 快速查找並刪除Excel重覆項的免費解決方案。 以下是實現步驟: 1. 首先安裝免費.NET ...
  • C++ 異常處理 C++ 異常處理機制允許程式在運行時處理錯誤或意外情況。它提供了捕獲和處理錯誤的一種結構化方式,使程式更加健壯和可靠。 異常處理的基本概念: 異常: 程式在運行時發生的錯誤或意外情況。 拋出異常: 使用 throw 關鍵字將異常傳遞給調用堆棧。 捕獲異常: 使用 try-catch ...
  • 優秀且經驗豐富的Java開發人員的特征之一是對API的廣泛瞭解,包括JDK和第三方庫。 我花了很多時間來學習API,尤其是在閱讀了Effective Java 3rd Edition之後 ,Joshua Bloch建議在Java 3rd Edition中使用現有的API進行開發,而不是為常見的東西編 ...
  • 框架 · 使用laravel框架,原因:tp的框架路由和orm沒有laravel好用 · 使用強制路由,方便介面多時,分多版本,分文件夾等操作 介面 · 介面開發註意欄位類型,欄位是int,查詢成功失敗都要返回int(對接java等強類型語言方便) · 查詢介面用GET、其他用POST 代碼 · 所 ...
  • 正文 下午找企業的人去鎮上做貸後。 車上聽同事跟那個司機對罵,火星子都快出來了。司機跟那同事更熟一些,連我在內一共就三個人,同事那一手指桑罵槐給我都聽愣了。司機也是老社會人了,馬上聽出來了,為那個無辜的企業經辦人辯護,實際上是為自己辯護。 “這個事情你不能怪企業。”“但他們總不能讓銀行的人全權負責, ...