如何上传 10GB 左右的视频文件?
如果通过以前的二进制上传方式,将它一次性上传将会产生一系列问题。
Request Body
过大,在上传 9GB 左右失败时,需要重新全部上传,浪费时间Request Body
过大,导致时间过长
既然上传整个视频文件过大,那将它分割成 N 个小块上传,服务器端再将其进行拼接,岂不是可以解决问题?
上传效果可在 Apifox 查看:
客户端分割
资源分为二进制资源与文本资源,文本资源很容易被分割与拼接,那二进制资源呢?
我们在浏览器端上传二进制资源时,通过 Blob
进行上传,可使用 Blob.prototype.slice 进行切片。
const blob = instanceOfBlob.slice([start [, end [, contentType]]]}
复制代码
通过 createChunks
函数可创建分片,并通过 uploadChunks
上传分片,在所有分片上传完成之后发送请求通知服务端进行切片合并。
function createChunks(blob, chunkSize) {
const chunks = []
let id = 0
while (start < blob.size) {
chunks.push({
blob: blob.slice(id * chunkSize, (id + 1) * chunkSize),
id: id
})
id++
}
return chunks
}
async function uploadChunks(chunks) {
for (const chunk of chunks) {
const form = new FormData()
form.append('blob', chunk.blob)
form.append('id', chunk.id)
// 分片上传大文件
await fetch('/upload-bigfile', {
body: form
})
}
// 全部分片上传完成之后,可以通知服务器端合并所有分片
await fetch('/upload-bigfile/merge')
}
复制代码
在上传切片的过程中,为了保证上传速度,可通过 p-map 控制并发上传。
上传效果可在 Apifox 查看:
服务器拼接
作业
- 如何实现大文件上传