Why can't ffmpeg.wasm work well on Chrome? Please answer.
Describe the bug I want to use ffmpeg.wasm in my project. It may need to run in browsers such as chrome, firefox, safari, etc. However, a problem was discovered during the integration process: the demo I wrote can run well in firefox. It runs, but there is no way to run it in chrome. It will stop running after the video information appears (it may also be other unexpected situations). I don't know how to solve it. I hope the author can help me look at it and give me some suggestion
To Reproduce
<script setup>
import {FFmpeg} from "@ffmpeg/ffmpeg";
import {fetchFile, toBlobURL} from "@ffmpeg/util";
import {ref} from "vue";
const videoFile = ref('')
const videoSrc = ref('')
const ffmpeg = new FFmpeg()
const init_ffmpeg = async () => {
ffmpeg.on('log', e => {
console.log(e.message)
})
ffmpeg.on('progress', e => {
console.log(e.progress)
})
const baseURL = 'https://unpkg.com/@ffmpeg/[email protected]/dist/esm'
if (ffmpeg.loaded) {
return
}
await ffmpeg.load({
coreURL: await toBlobURL(`${baseURL}/ffmpeg-core.js`, 'text/javascript'),
wasmURL: await toBlobURL(`${baseURL}/ffmpeg-core.wasm`, 'application.wasm'),
workerURL: await toBlobURL(`${baseURL}/ffmpeg-core.worker.js`, 'text/javascript')
})
console.log('ffmpeg 加载完成')
}
const handleFileUpload = (event) => {
videoFile.value = event.target.files[0];
}
const convert = async () => {
console.log('enter convert')
await init_ffmpeg()
await ffmpeg.writeFile("123456.mp4", await fetchFile(videoFile.value))
console.log(videoFile.value.name)
try {
const target_name = "123456.mov"
const res = await ffmpeg.exec([
'-i', "123456.mp4",
target_name
])
console.log('result:', res)
const snatshot = await ffmpeg.readFile(target_name)
videoSrc.value = URL.createObjectURL(new Blob([snatshot.buffer], {type: 'video/quicktime'}))
await ffmpeg.deleteFile("123456.mp4")
await ffmpeg.deleteFile(target_name)
} catch (e) {
console.log(e)
}
}
</script>
Expected behavior I hope that I can convert mp4 files to mov files normally on the chrome browser without stopping working directly.
Screenshots
Desktop (please complete the following information):
- OS: Windows10
- Browser: Chrome
- Version: 125.0.06422.61
core-mt is broken in so many ways atm - I changed to the single thread version and all problems are gone.
still sad though
core-mt is broken in so many ways atm - I changed to the single thread version and all problems are gone.
still sad though
Can you tell me how you modified it into a single-threaded version? If possible, I hope you can give me a reference demo.
Can you tell me how you modified it into a single-threaded version?
Simply use the non-multithreaded core (core instead of core-mt)
@CxyJerry
const baseURL = 'https://unpkg.com/@ffmpeg/[email protected]/dist/esm';
Can you tell me how you modified it into a single-threaded version?
Simply use the non-multithreaded core (core instead of core-mt)
Thank you very much for your answer but I tried changing ffmpeg wasm version from core-mt to core but still doesn't work in chrome
@CxyJerry
const baseURL = 'https://unpkg.com/@ffmpeg/[email protected]/dist/esm';
Thank you very much for your answer but I tried changing ffmpeg wasm version from core-mt to core but still doesn't work in chrome
it can work, but is it too slow!
Microsoft Edge
版本 127.0.2651.98 (正式版本) (64 位)
Microsoft Edge/Chromium version 127
function upload(fn,accept){
let input = document.createElement('input');
input.type = 'file';
input.accept = accept;
input.addEventListener('change',e=>fn(e.target.files));
input.click();
}
upload(async files=>{
const worker = new MyWorker({url:'WorkerAppFFmpeg.js',type:'module',install:true});
worker.methods.set('log',function(data,port){
console.log(data.message);
});
worker.methods.set('wasmload',function(data,port){
console.log(data);
});
worker.methods.set('progress',function(data,port){
console.log(data);
});
await worker.setMethod();
console.log(await worker.ready);
await worker.callMethod('writeFile','0.mp4',new Uint8Array(await files[0].arrayBuffer()));
await worker.callMethod('exec',['-i','0.mp4','a.mov'],-1);
const file = await worker.callMethod('readFile','a.mov');
worker.terminate();
this.downURL(URL.createObjectURL(new Blob([file])),'a.mov');
});
other file
ffmpeg version 5.1.4 Copyright (c) 2000-2023 the FFmpeg developers
built with emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.40 (5c27e79dd0a9c4e27ef2326841698cdd4f6b5784)
configuration: --target-os=none --arch=x86_32 --enable-cross-compile --disable-asm --disable-stripping --disable-programs --disable-doc --disable-debug --disable-runtime-cpudetect --disable-autodetect --nm=emnm --ar=emar --ranlib=emranlib --cc=emcc --cxx=em++ --objcc=emcc --dep-cc=emcc --extra-cflags='-I/opt/include -O3 -msimd128' --extra-cxxflags='-I/opt/include -O3 -msimd128' --disable-pthreads --disable-w32threads --disable-os2threads --enable-gpl --enable-libx264 --enable-libx265 --enable-libvpx --enable-libmp3lame --enable-libtheora --enable-libvorbis --enable-libopus --enable-zlib --enable-libwebp --enable-libfreetype --enable-libfribidi --enable-libass --enable-libzimg
libavutil 57. 28.100 / 57. 28.100
libavcodec 59. 37.100 / 59. 37.100
libavformat 59. 27.100 / 59. 27.100
libavdevice 59. 7.100 / 59. 7.100
libavfilter 8. 44.100 / 8. 44.100
libswscale 6. 7.100 / 6. 7.100
libswresample 4. 7.100 / 4. 7.100
libpostproc 56. 6.100 / 56. 6.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '0.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf59.27.100
Duration: 00:00:13.24, start: 0.000000, bitrate: 1965 kb/s
Stream #0:0[0x1](und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(progressive), 1440x1080, 1826 kb/s, 30 fps, 30 tbr, 15360 tbn (default)
Metadata:
handler_name : VideoHandler
vendor_id : [0][0][0][0]
encoder : Lavc59.37.100 libx264
Stream #0:1[0x2](und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 129 kb/s (default)
Metadata:
handler_name : SoundHandler
vendor_id : [0][0][0][0]
Stream mapping:
Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
Stream #0:1 -> #0:1 (aac (native) -> aac (native))
[libx264 @ 0xe05090] using cpu capabilities: none!
[libx264 @ 0xe05090] profile High, level 4.0, 4:2:0, 8-bit
[libx264 @ 0xe05090] 264 - core 164 - H.264/MPEG-4 AVC codec - Copyleft 2003-2022 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=1 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
Output #0, mov, to 'a.mov':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf59.27.100
Stream #0:0(und): Video: h264 (avc1 / 0x31637661), yuv420p(progressive), 1440x1080, q=2-31, 30 fps, 15360 tbn (default)
Metadata:
handler_name : VideoHandler
vendor_id : [0][0][0][0]
encoder : Lavc59.37.100 libx264
Side data:
cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: N/A
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 128 kb/s (default)
Metadata:
handler_name : SoundHandler
vendor_id : [0][0][0][0]
encoder : Lavc59.37.100 aac
{method: 'progress', progress: 0, time: 0}
.....
{method: 'progress', progress: 1, time: 13235374}
video:2823kB audio:209kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.525693%
[libx264 @ 0xe05090] frame I:3 Avg QP:19.69 size: 97039
[libx264 @ 0xe05090] frame P:158 Avg QP:20.51 size: 12750
[libx264 @ 0xe05090] frame B:236 Avg QP:22.09 size: 2477
[libx264 @ 0xe05090] consecutive B-frames: 5.8% 42.3% 7.6% 44.3%
[libx264 @ 0xe05090] mb I I16..4: 31.3% 45.0% 23.8%
[libx264 @ 0xe05090] mb P I16..4: 6.6% 10.4% 0.6% P16..4: 19.9% 4.2% 1.6% 0.0% 0.0% skip:56.7%
[libx264 @ 0xe05090] mb B I16..4: 0.6% 0.8% 0.0% B16..8: 10.5% 1.1% 0.2% direct: 2.5% skip:84.4% L0:39.9% L1:55.7% BI: 4.4%
[libx264 @ 0xe05090] 8x8 transform intra:57.5% inter:76.2%
[libx264 @ 0xe05090] coded y,uvDC,uvAC intra: 26.9% 61.9% 10.8% inter: 2.8% 9.2% 0.3%
[libx264 @ 0xe05090] i16 v,h,dc,p: 25% 45% 7% 23%
[libx264 @ 0xe05090] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 22% 31% 26% 3% 4% 4% 5% 3% 3%
[libx264 @ 0xe05090] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 25% 28% 16% 4% 6% 6% 5% 5% 5%
[libx264 @ 0xe05090] i8c dc,h,v,p: 43% 31% 19% 8%
[libx264 @ 0xe05090] Weighted P-Frames: Y:0.0% UV:0.0%
[libx264 @ 0xe05090] ref P L0: 75.3% 8.7% 12.4% 3.6%
[libx264 @ 0xe05090] ref B L0: 91.0% 7.9% 1.0%
[libx264 @ 0xe05090] ref B L1: 98.8% 1.2%
[libx264 @ 0xe05090] kb/s:1747.24
[aac @ 0xdedca0] Qavg: 1035.761
Aborted()
@CxyJerry
const baseURL = 'https://unpkg.com/@ffmpeg/[email protected]/dist/esm';Thank you very much for your answer but I tried changing ffmpeg wasm version from core-mt to core but still doesn't work in chrome
@CxyJerry are you using Webpack instead of Vite? If so, you should use the umd URL
const baseURL = 'https://unpkg.com/@ffmpeg/[email protected]/dist/umd';
I'm having the same issue with multithreaded. Everything loads and initial ffmpeg output prints to console, but no encoding actually happens. Looking in the Network debug tab, there's a pending request to a blob that I think is the wasm blob. Many other requests to that blob have succeeded. Perhaps there is a browser bug with trying to access a large blob from many workers. Anyway, switching back to single-threaded fixes it.