html
<input type="file" id="videoInput" accept="video/*" />
<button id="uploadButton">上传视频</button>
<div id="progress"></div>
js
// 切片大小(例如 5MB)
const CHUNK_SIZE = 5 * 1024 * 1024;
document.getElementById('uploadButton').addEventListener('click', async () => {
const file = document.getElementById('videoInput').files[0];
if (!file) {
alert('请选择视频文件');
return;
}
// 文件切片
const chunks = createFileChunks(file, CHUNK_SIZE);
// 上传所有切片
for (let i = 0; i < chunks.length; i++) {
const chunk = chunks[i];
const formData = new FormData();
formData.append('file', chunk);
formData.append('filename', file.name);
formData.append('chunkIndex', i);
formData.append('totalChunks', chunks.length);
try {
await uploadChunk(formData, i, chunks.length);
console.log(`切片 ${i + 1}/${chunks.length} 上传成功`);
} catch (error) {
console.error(`切片 ${i + 1}/${chunks.length} 上传失败:`, error);
break;
}
}
console.log('所有切片上传完成');
});
// 将文件切片
function createFileChunks(file, chunkSize) {
const chunks = [];
let start = 0;
while (start < file.size) {
const chunk = file.slice(start, start + chunkSize);
chunks.push(chunk);
start += chunkSize;
}
return chunks;
}
// 上传切片
function uploadChunk(formData, chunkIndex, totalChunks) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('POST', '/upload', true);
// 监听上传进度
xhr.upload.onprogress = (event) => {
if (event.lengthComputable) {
const percent = ((chunkIndex + event.loaded / event.total) / totalChunks * 100).toFixed(2);
document.getElementById('progress').innerText = `上传进度: ${percent}%`;
}
};
xhr.onload = () => {
if (xhr.status === 200) {
resolve(xhr.responseText);
} else {
reject(new Error('上传失败'));
}
};
xhr.onerror = () => {
reject(new Error('上传失败'));
};
xhr.send(formData);
});
}
拓展
视频预览
const video = document.createElement('video');
video.src = URL.createObjectURL(file);
video.controls = true;
document.body.appendChild(video);