js实现视频下载
使用Blob对象下载视频
通过XMLHttpRequest或fetch获取视频数据流,转换为Blob对象后创建下载链接。

function downloadVideo(url, filename) {
fetch(url)
.then(response => response.blob())
.then(blob => {
const a = document.createElement('a');
a.href = URL.createObjectURL(blob);
a.download = filename || 'video.mp4';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
});
}
使用MediaSource扩展
处理分段视频流时,可通过MediaSource API实现渐进式下载。

const video = document.getElementById('video');
const mediaSource = new MediaSource();
video.src = URL.createObjectURL(mediaSource);
mediaSource.addEventListener('sourceopen', () => {
const sourceBuffer = mediaSource.addSourceBuffer('video/mp4; codecs="avc1.42E01E"');
fetchVideoSegments().then(segments => {
segments.forEach(segment => {
sourceBuffer.appendBuffer(segment);
});
});
});
处理跨域问题
当视频资源存在CORS限制时,需配置代理服务器或使用服务端中转。
// 服务端代理示例(Node.js)
const express = require('express');
const fetch = require('node-fetch');
const app = express();
app.get('/proxy', async (req, res) => {
const videoRes = await fetch(req.query.url);
videoRes.body.pipe(res);
});
分片下载大文件
对于大型视频文件可采用分块下载策略。
async function downloadInChunks(url, chunkSize = 1024 * 1024) {
const fileSize = await getFileSize(url);
const chunks = Math.ceil(fileSize / chunkSize);
for (let i = 0; i < chunks; i++) {
const start = i * chunkSize;
const end = Math.min(start + chunkSize, fileSize);
const chunk = await fetch(url, {
headers: { Range: `bytes=${start}-${end}` }
}).then(res => res.blob());
// 处理分片数据
}
}
注意事项
- 确保目标视频允许下载,避免侵犯版权
- 大文件下载建议显示进度条
- 移动端浏览器可能存在Blob限制
- 考虑使用第三方库如FileSaver.js简化操作
// 进度监控示例
fetch(url)
.then(response => {
const reader = response.body.getReader();
const contentLength = +response.headers.get('Content-Length');
let receivedLength = 0;
return new ReadableStream({
start(controller) {
function push() {
reader.read().then(({ done, value }) => {
if (done) {
controller.close();
return;
}
receivedLength += value.length;
updateProgress(receivedLength / contentLength);
controller.enqueue(value);
push();
});
}
push();
}
});
});






