翼度科技»论坛 编程开发 JavaScript 查看内容

前端使用 fetch() 流式下载.mp4视频文件,跟踪进度

2

主题

2

帖子

6

积分

新手上路

Rank: 1

积分
6
参考:https://www.cnblogs.com/lxlx1798/articles/16969244.html
要么使用流读取器,要么使用 Reponse 的方法来获取结果,不能同时使用两种方法来读取相同的响应。
直接获取:
Response.blob() 方法返回一个 resolve 返回值为 Blob 对象的 Promise
  1. fetch(videoUrl).then(res => {
  2.                 const p = res.blob()
  3.                 return res.blob()
  4.             }).then(blob => {
  5.                 const a = document.createElement("a");
  6.                 a.style.display = 'none'
  7.                 document.body.append(a)
  8.                 const url = window.URL.createObjectURL(blob)
  9.                 a.href = url
  10.                 a.download = item.name
  11.                 a.click()
  12.                 document.body.removeChild(a)
  13.                 window.URL.revokeObjectURL(url)
  14.             })
复制代码
流读取:
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 就可以完成下载了
  1. const videoUrl = 'video url'<br>const response = await fetch(videoUrl)
  2. const reader = response.body.getReader()
  3. const contentLength = +response.headers.get('Content-Length')
  4. let receivedLength = 0
  5. let chunks = []
  6. while (true) {
  7.     const { done, value } = await reader.read();
  8.     if (done) {
  9.         break
  10.     }
  11.     chunks.push(value)
  12.     receivedLength += value.length
  13.     // 下载进度
  14.     console.log(`Reveived ${receivedLength} of ${contentLength}`)
  15. }
  16. const a = document.createElement("a");
  17. a.style.display = 'none'
  18. document.body.append(a)
  19. const url = window.URL.createObjectURL(new Blob(chunks, { type: 'video/mp4'} ))
  20. a.href = url
  21. a.download = item.name
  22. a.click()
  23. document.body.removeChild(a)
  24. 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.
 

来源:https://www.cnblogs.com/xiyouchen/p/17070200.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具