在 Web 开发项目过程中,我遇到了视频切片以高效上传到服务器的挑战。最初,我开发了一项服务,通过从一个点提取字节到另一个点,成功地对 MP4 文件进行切片。但是,我在上传分段视频后的合并过程中遇到了问题。视频未能成功合并,我正在寻求见解和解决方案来克服这一障碍。
在尝试解决该问题时,我回顾了视频切片过程并实施了各种方法。尽管做出了这些努力,分段视频的合并仍然存在问题。我期望在上传分段部分后能够实现无缝合并过程,但不幸的是,情况并非如此。然而,我开始意识到视频切片涉及更多复杂性,正如这篇富有洞察力的Stack Overflow帖子中所述。
如果有人有视频切片的经验,特别是在 Web 开发的背景下,并成功解决了类似的合并挑战,我将非常感谢您的指导。此外,如果您对有效处理视频切片和合并的包或库有建议,请分享您的见解。
编辑:
简化的客户端代码
export class Chunks {
chunkSize: number
private file: File
constructor({chunkSize}) {
this.chunkSize = chunkSize * 1024
}
get totalChunks () {
return Math.ceil(this.file.size / this.chunkSize);
}
setFile(file: File) {
this.file = file
}
// Function to read a chunk of the file
readChunk(start: number, end: number) {
const file = this.file
return file.slice(start, end)
}
async getChunks(i: number) {
i--
if(i < this.totalChunks) {
const start = i * this.chunkSize;
const end = Math.min(start + this.chunkSize, this.file.size);
const chunk = await this.readChunk(start, end);
return chunk
}
}
}
const chunks = new Chunks({chunkSize: 1024})
chunks.setFile(File)
for (let index = 1; index <= chunks.totalChunks; index++) {
const blob = await chunks.getChunks(index)
const blobFile = new File([blob], "test.mp4", { type: blob.type });
const formData = new FormData();
formData.append("blobFile", blobFile);
formData.append("length", chunks.totalChunks);
formData.append("index", index);
return this.http.post(`${geturl}`, formData, options)
}
服务器端代码
错误出现在 concatMedia 函数内,并且在异常块中,没有捕获到任何内容。
测试
我进行了一些测试,我可以将第一个块作为视频播放。但其余部分无法识别为视频;它根本不认识它。
const blob = await chunks.getChunks(1)
const blobFile = new File([blob], "test.mp4", { type: blob.type });
// Create a URL for the blobFile
const blobUrl = URL.createObjectURL(blobFile);
// Get the video element from the DOM
const videoElement: any = document.getElementById("yourVideoElementId");
// Set the src attribute of the video element to the blob URL
videoElement.src = blobUrl;
// Optionally, you can also set other attributes or play the video
videoElement.controls = true; // Add controls for play, pause, etc.
videoElement.play(); // Auto-play the vid
报告
后端人员也进行了一些测试。他使用在线工具分割视频,然后上传第一个视频和第二个视频。他成功地将它们合并了。
我尝试不对视频进行切片,而是将完整视频分成一大块发送。上传后,concatMedia函数没有出现任何错误。
鉴于您保证它实际上正在工作,我现在将跳过实际的客户端代码。
我不希望工作的最可疑的问题,但会考虑能够播放第一个块,但之后不能播放任何内容,是尝试使用
ffmpeg
来连接本身不是有效 mp4 视频文件的二进制数据块或者,如果在视频流的错误位置进行分割,则会中断解码,ffmpeg
无法恢复。
在服务器上,我建议放弃使用
ffmpeg
来连接上传的块,而是:
创建一个以上传的 mp4 文件命名的空输出文件。
将上传的文件内容的块附加到输出文件,确保块数据在读/获取和写/附加操作中都被视为二进制数据。
在将最后一个块附加到输出文件后,关闭并刷新输出文件。输出文件应该是上传的视频文件。
如果输出文件按预期播放,则问题解决。如果不是,它可能会提供与上传文件相比的文件大小的线索,并且可能需要更详细地重新访问客户端上传代码。