在@ffmpeg/ffmpeg Worker中重构流式视频分片问题求助
问题解决:基于
@ffmpeg/ffmpeg重构网络流视频 问题1:后续分片报无效数据的原因及修复
原因
你当前从response.body读取的value是HTTP传输的分块数据,并非视频本身的独立分片。第一个"分片"恰好包含视频文件的完整文件头(如MP4的ftyp/moov段),所以FFmpeg能识别;但后续的HTTP分块仅为文件的部分数据,没有完整的文件结构,因此触发Invalid data found错误。
修复方案
先将所有HTTP分块合并为完整的二进制文件,再传入FFmpeg处理:
// 修改流式获取视频的代码 await useFetch(Capacitor.convertFileSrc(file.path), { responseType: "stream", onResponse: async ({ response }) => { if (response.body) { const reader = response.body.getReader(); const chunks = []; let totalLength = 0; while (true) { const { done, value } = await reader.read(); if (done) break; chunks.push(value); totalLength += value.length; } reader.releaseLock(); // 合并所有HTTP分块为完整二进制文件 const completeFile = new Uint8Array(totalLength); let offset = 0; for (const chunk of chunks) { completeFile.set(chunk, offset); offset += chunk.length; } file.completeFile = completeFile; // 用完整文件替代分块数组 } }, });
// 修改文件写入代码 const constructFile = async (completeFile: Uint8Array, queueId: number) => { const fullFileName = `video-${queueId}_complete`; await ffmpeg.writeFile(fullFileName, completeFile); // 验证文件有效性 await ffmpeg.exec(["-i", fullFileName]); };
问题2:真正视频分片的合并方法
如果你的场景是处理独立的视频分片文件(如HLS的.ts分片),而非HTTP传输分块,可使用FFmpeg的concat解复用器高效合并:
- 生成分片列表文件
// 生成包含所有分片路径的文本文件 const chunkListContent = chunks.map((_, index) => `file 'video-${queueId}_chunk-${index}'`).join('\n'); await ffmpeg.writeFile(`chunk-list-${queueId}.txt`, chunkListContent);
- 执行合并命令
// 合并分片并输出完整视频(直接复制流,无重新编码) await ffmpeg.exec([ "-f", "concat", "-safe", "0", "-i", `chunk-list-${queueId}.txt`, "-c", "copy", `output-${queueId}.mp4` ]);
注意:该方法要求所有分片的编码参数(分辨率、码率、格式)完全一致;若参数不一致,需移除
-c copy,让FFmpeg重新编码。
大视频处理替代方案:流式写入FFmpeg
若视频文件过大,合并成完整Uint8Array会占用过多内存,可直接将响应流传给FFmpeg,无需加载到内存:
await useFetch(Capacitor.convertFileSrc(file.path), { responseType: "stream", onResponse: async ({ response }) => { if (response.body) { const fullFileName = `video-${queueId}_complete`; // 直接将响应流写入FFmpeg await ffmpeg.writeFile(fullFileName, response.body); // 后续处理完整视频 await ffmpeg.exec(["-i", fullFileName, "-c", "copy", `output-${queueId}.mp4`]); } }, });
内容的提问来源于stack exchange,提问作者Oyedeji
相关产品推荐
相关产品推荐

