Edit: I'm rewriting this entire question
Goal: To reconstruct a video from its pieces/chunks from a network stream inside of an @ffmpeg/ffmpeg
worker
Problems:
- Video chunks/pieces which come after the first piece/chunk are reported by
@ffmpeg/ffmpeg
to have invalid data, as seen in the log below:
{
"type": "stderr",
"message": "video-0_chunk-1.part: Invalid data found when processing input"
}
- How would I merge these chunks/pieces to reconstruct the full video using
@ffmpeg/ffmpeg
(after solving the first issue above)
My current code situation:
- For merging the video pieces
const constructFile = async (chunks: Uint8Array[], queueId: number) => {
await Promise.all(
chunks.map(async (chunk, index) => {
const chunkFile = `video-${queueId}_chunk-${index}`;
await ffmpeg.writeFile(chunkFile, chunk);
// Return information about newly created file
ffmpeg.exec(["-i", chunkFile]);
})
);
};
I'm reading the logs/output for
ffmpeg.exec(['-i', chunkFile])
using
ffmpeg.on('log', (log) => console.log(log))
- For fetching the videos using streams
await useFetch(Capacitor.convertFileSrc(file.path), {
responseType: "stream",
onResponse: async ({ response }) => {
if (response.body) {
const reader = response.body.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) break;
file.chunks.push(value);
}
reader.releaseLock();
}
},
});
Note: file.chunks is linked to a reactive value which is passed to constructFile()
when initialized
These are the logs I get from the code currently above:
chunk-4OF65L5M.js:2710 <Suspense> is an experimental feature and its API will likely change.
(index):298 native App.addListener (#25407936)
(index):298 native FilePicker.pickVideos (#25407937)
(index):272 result FilePicker.pickVideos (#25407937)
(index):298 native VideoEditor.thumbnail (#25407938)
(index):272 result VideoEditor.thumbnail (#25407938)
Processing.vue:135 {type: 'stderr', message: 'ffmpeg version 5.1.3 Copyright (c) 2000-2022 the FFmpeg developers'}
Processing.vue:135 {type: 'stderr', message: ' built with emcc (Emscripten gcc/clang-like repla…3.1.40 (5c27e79dd0a9c4e27ef2326841698cdd4f6b5784)'}
Processing.vue:135 {type: 'stderr', message: ' configuration: --target-os=none --arch=x86_32 --…e-libfreetype --enable-libfribidi --enable-libass'}
Processing.vue:135 {type: 'stderr', message: ' libavutil 57. 28.100 / 57. 28.100'}
Processing.vue:135 {type: 'stderr', message: ' libavcodec 59. 37.100 / 59. 37.100'}
Processing.vue:135 {type: 'stderr', message: ' libavformat 59. 27.100 / 59. 27.100'}
Processing.vue:135 {type: 'stderr', message: ' libavdevice 59. 7.100 / 59. 7.100'}
Processing.vue:135 {type: 'stderr', message: ' libavfilter 8. 44.100 / 8. 44.100'}
Processing.vue:135 {type: 'stderr', message: ' libswscale 6. 7.100 / 6. 7.100'}
Processing.vue:135 {type: 'stderr', message: ' libswresample 4. 7.100 / 4. 7.100'}
Processing.vue:135 {type: 'stderr', message: ' libpostproc 56. 6.100 / 56. 6.100'}
Processing.vue:135 {type: 'stderr', message: "Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'video-0_chunk-0':"}
Processing.vue:135 {type: 'stderr', message: ' Metadata:'}
Processing.vue:135 {type: 'stderr', message: ' major_brand : mp42'}
Processing.vue:135 {type: 'stderr', message: ' minor_version : 0'}
Processing.vue:135 {type: 'stderr', message: ' compatible_brands: isommp42'}
Processing.vue:135 {type: 'stderr', message: ' creation_time : 2022-11-29T14:46:32.000000Z'}
Processing.vue:135 {type: 'stderr', message: ' Duration: 00:00:51.50, start: 0.000000, bitrate: 81 kb/s'}
Processing.vue:135 {type: 'stderr', message: ' Stream #0:0[0x1](und): Video: h264 (High) (avc1 …6], 259 kb/s, 30 fps, 30 tbr, 15360 tbn (default)'}
Processing.vue:135 {type: 'stderr', message: ' Metadata:'}
Processing.vue:135 {type: 'stderr', message: ' creation_time : 2022-11-29T14:46:32.000000Z'}
Processing.vue:135 {type: 'stderr', message: ' handler_name : ISO Media file produced by Google Inc. Created on: 11/29/2022.'}
Processing.vue:135 {type: 'stderr', message: ' vendor_id : [0][0][0][0]'}
Processing.vue:135 {type: 'stderr', message: ' Stream #0:1[0x2](und): Audio: aac (LC) (mp4a / 0…706D), 44100 Hz, stereo, fltp, 127 kb/s (default)'}
Processing.vue:135 {type: 'stderr', message: ' Metadata:'}
Processing.vue:135 {type: 'stderr', message: ' creation_time : 2022-11-29T14:46:32.000000Z'}
Processing.vue:135 {type: 'stderr', message: ' handler_name : ISO Media file produced by Google Inc. Created on: 11/29/2022.'}
Processing.vue:135 {type: 'stderr', message: ' vendor_id : [0][0][0][0]'}
Processing.vue:135 {type: 'stderr', message: 'At least one output file must be specified'}
Processing.vue:135 {type: 'stderr', message: 'Aborted()'}
Processing.vue:135 {type: 'stderr', message: 'ffmpeg version 5.1.3 Copyright (c) 2000-2022 the FFmpeg developers'}
Processing.vue:135 {type: 'stderr', message: ' built with emcc (Emscripten gcc/clang-like repla…3.1.40 (5c27e79dd0a9c4e27ef2326841698cdd4f6b5784)'}
Processing.vue:135 {type: 'stderr', message: ' configuration: --target-os=none --arch=x86_32 --…e-libfreetype --enable-libfribidi --enable-libass'}
Processing.vue:135 {type: 'stderr', message: ' libavutil 57. 28.100 / 57. 28.100'}
Processing.vue:135 {type: 'stderr', message: ' libavcodec 59. 37.100 / 59. 37.100'}
Processing.vue:135 {type: 'stderr', message: ' libavformat 59. 27.100 / 59. 27.100'}
Processing.vue:135 {type: 'stderr', message: ' libavdevice 59. 7.100 / 59. 7.100'}
Processing.vue:135 {type: 'stderr', message: ' libavfilter 8. 44.100 / 8. 44.100'}
Processing.vue:135 {type: 'stderr', message: ' libswscale 6. 7.100 / 6. 7.100'}
Processing.vue:135 {type: 'stderr', message: ' libswresample 4. 7.100 / 4. 7.100'}
Processing.vue:135 {type: 'stderr', message: ' libpostproc 56. 6.100 / 56. 6.100'}
Processing.vue:135 {type: 'stderr', message: 'video-0_chunk-1: Invalid data found when processing input'}
Processing.vue:135 {type: 'stderr', message: 'Aborted()'}
Processing.vue:135 {type: 'stderr', message: 'ffmpeg version 5.1.3 Copyright (c) 2000-2022 the FFmpeg developers'}
Processing.vue:135 {type: 'stderr', message: ' built with emcc (Emscripten gcc/clang-like repla…3.1.40 (5c27e79dd0a9c4e27ef2326841698cdd4f6b5784)'}
Processing.vue:135 {type: 'stderr', message: ' configuration: --target-os=none --arch=x86_32 --…e-libfreetype --enable-libfribidi --enable-libass'}
Processing.vue:135 {type: 'stderr', message: ' libavutil 57. 28.100 / 57. 28.100'}
Processing.vue:135 {type: 'stderr', message: ' libavcodec 59. 37.100 / 59. 37.100'}
Processing.vue:135 {type: 'stderr', message: ' libavformat 59. 27.100 / 59. 27.100'}
Processing.vue:135 {type: 'stderr', message: ' libavdevice 59. 7.100 / 59. 7.100'}
Processing.vue:135 {type: 'stderr', message: ' libavfilter 8. 44.100 / 8. 44.100'}
Processing.vue:135 {type: 'stderr', message: ' libswscale 6. 7.100 / 6. 7.100'}
Processing.vue:135 {type: 'stderr', message: ' libswresample 4. 7.100 / 4. 7.100'}
Processing.vue:135 {type: 'stderr', message: ' libpostproc 56. 6.100 / 56. 6.100'}
Processing.vue:135 {type: 'stderr', message: 'video-0_chunk-2: Invalid data found when processing input'}
Processing.vue:135 {type: 'stderr', message: 'Aborted()'}
Processing.vue:135 {type: 'stderr', message: 'ffmpeg version 5.1.3 Copyright (c) 2000-2022 the FFmpeg developers'}
Processing.vue:135 {type: 'stderr', message: ' built with emcc (Emscripten gcc/clang-like repla…3.1.40 (5c27e79dd0a9c4e27ef2326841698cdd4f6b5784)'}
Processing.vue:135 {type: 'stderr', message: ' configuration: --target-os=none --arch=x86_32 --…e-libfreetype --enable-libfribidi --enable-libass'}
Processing.vue:135 {type: 'stderr', message: ' libavutil 57. 28.100 / 57. 28.100'}
Processing.vue:135 {type: 'stderr', message: ' libavcodec 59. 37.100 / 59. 37.100'}
Processing.vue:135 {type: 'stderr', message: ' libavformat 59. 27.100 / 59. 27.100'}
Processing.vue:135 {type: 'stderr', message: ' libavdevice 59. 7.100 / 59. 7.100'}
Processing.vue:135 {type: 'stderr', message: ' libavfilter 8. 44.100 / 8. 44.100'}
Processing.vue:135 {type: 'stderr', message: ' libswscale 6. 7.100 / 6. 7.100'}
Processing.vue:135 {type: 'stderr', message: ' libswresample 4. 7.100 / 4. 7.100'}
Processing.vue:135 {type: 'stderr', message: ' libpostproc 56. 6.100 / 56. 6.100'}
Processing.vue:135 {type: 'stderr', message: 'video-0_chunk-3: Invalid data found when processing input'}
Processing.vue:135 {type: 'stderr', message: 'Aborted()'}
Processing.vue:135 {type: 'stderr', message: 'ffmpeg version 5.1.3 Copyright (c) 2000-2022 the FFmpeg developers'}
Processing.vue:135 {type: 'stderr', message: ' built with emcc (Emscripten gcc/clang-like repla…3.1.40 (5c27e79dd0a9c4e27ef2326841698cdd4f6b5784)'}
Processing.vue:135 {type: 'stderr', message: ' configuration: --target-os=none --arch=x86_32 --…e-libfreetype --enable-libfribidi --enable-libass'}
Processing.vue:135 {type: 'stderr', message: ' libavutil 57. 28.100 / 57. 28.100'}
Processing.vue:135 {type: 'stderr', message: ' libavcodec 59. 37.100 / 59. 37.100'}
Processing.vue:135 {type: 'stderr', message: ' libavformat 59. 27.100 / 59. 27.100'}
Processing.vue:135 {type: 'stderr', message: ' libavdevice 59. 7.100 / 59. 7.100'}
Processing.vue:135 {type: 'stderr', message: ' libavfilter 8. 44.100 / 8. 44.100'}
Processing.vue:135 {type: 'stderr', message: ' libswscale 6. 7.100 / 6. 7.100'}
Processing.vue:135 {type: 'stderr', message: ' libswresample 4. 7.100 / 4. 7.100'}
Processing.vue:135 {type: 'stderr', message: ' libpostproc 56. 6.100 / 56. 6.100'}
Processing.vue:135 {type: 'stderr', message: 'video-0_chunk-4: Invalid data found when processing input'}
Processing.vue:135 {type: 'stderr', message: 'Aborted()'}
Notes:
- The sections which start with
Processing.vue
come from the logging system I've setup. - The pieces/chunks gotten from the network where stored in exactly the same order in which they came
- If you've seen the old question, the
ReferenceError
happens as a result of HMR by Vite- Similar to this, some logs were repeated twice because I was actively changing some things and the component had to rerun from the start
Summary: If my problem is still not clear, you could provide another way of fetching a large file (video) from a network, loading the file into memory and passing the file data to @ffmpeg/ffmpeg
for further processing