ffmpeg.wasm
ffmpeg.wasm copied to clipboard
Help and explanation please: `Uncaught (in promise) RuntimeError: null function or function signature mismatch` + Code
I do not actually know what this error means on the language of this package, but I can provide you with a simple example where it appears and breaks the worker (meaning worker becomes unusable until a page reload).
Here is the video.
https://github.com/ffmpegwasm/ffmpeg.wasm/assets/109352196/0e88899b-d14a-4fc4-8937-ef68672d2d50
See the code below.
Next 14.0.4
A simple mockup project I bootstrapped just to show the error in your package guys
'use client'
import { FFmpeg } from '@ffmpeg/ffmpeg'
import { fetchFile, toBlobURL } from '@ffmpeg/util'
import { downloadZip } from 'client-zip'
import { useRef, useState } from 'react'
export default function HomePage() {
const [loaded, setLoaded] = useState(false)
const [isLoading, setIsLoading] = useState(false)
const ffmpegRef = useRef(new FFmpeg())
const load = async () => {
setIsLoading(true)
const baseURL = 'https://unpkg.com/@ffmpeg/[email protected]/dist/umd'
const ffmpeg = ffmpegRef.current
await ffmpeg.load({
coreURL: await toBlobURL(`${baseURL}/ffmpeg-core.js`, 'text/javascript'),
wasmURL: await toBlobURL(`${baseURL}/ffmpeg-core.wasm`, 'application/wasm'),
})
setLoaded(true)
setIsLoading(false)
}
const convertAndDownload = async (files: File[]) => {
const ffmpeg = ffmpegRef.current
const convertedFiles = await Promise.all(
files.map(async (song) => {
const key = song.size
const iName = key + '.mp3'
const oName = key + '.ogg'
await ffmpeg.writeFile(iName, await fetchFile(song))
await ffmpeg.exec(['-i', iName, oName])
const o = (await ffmpeg.readFile(oName)) as Uint8Array
return new File([o.buffer], song.name, { type: 'audio/ogg' })
})
)
const blob = await downloadZip(convertedFiles).blob()
const url = URL.createObjectURL(blob)
const a = document.createElement('a')
a.href = url
a.download = 'songs.zip'
a.click()
}
return (
<main>
{loaded ? (
<input
type='file'
multiple
name=''
id=''
accept='audio/mpeg'
onChange={async (e) => {
const mp3Files = Array.from(e.target.files!)
convertAndDownload(mp3Files)
}}
/>
) : (
<button onClick={load}>{isLoading ? 'loading...' : 'load'}</button>
)}
</main>
)
}
If you ever encountered this error, please give your feedback and solutions. Thanks
I also tried recreating Ffmpeg instance for every new file I wanted to convert following the logic "If one worker can do one file, I need a new instance for each file" which took the shape of this code:
- it did not help btw, same error 😞
async function onSongsInput(e: React.ChangeEvent<HTMLInputElement>) {
const files = Array.from(e.target.files!)
for (let i = 0; i < files.length; i++) {
const ffmpeg = new FFmpeg()
ffmpeg.on('progress', ({ progress }) => {
setProgress(progress)
})
const baseURL = 'https://unpkg.com/@ffmpeg/[email protected]/dist/umd'
await ffmpeg.load({
coreURL: await toBlobURL(`${baseURL}/ffmpeg-core.js`, 'text/javascript'),
wasmURL: await toBlobURL(`${baseURL}/ffmpeg-core.wasm`, 'application/wasm'),
})
console.log('starting ' + i)
console.log(files[i])
await convertAndDownload(ffmpeg, files[i])
ffmpeg.terminate()
}
}
const convertAndDownload = async (ffmpeg: FFmpeg, song: File) => {
const key = song.size
const iName = key + '.mp3'
const oName = key + '.ogg'
await ffmpeg.writeFile(iName, await fetchFile(song))
await ffmpeg.exec(['-i', iName, oName])
const o = (await ffmpeg.readFile(oName)) as Uint8Array
const convertedSong = new File([o.buffer], oName, { type: 'audio/ogg' })
const blob = await downloadZip([convertedSong]).blob()
const url = URL.createObjectURL(blob)
const a = document.createElement('a')
a.href = url
a.download = 'songs.zip'
a.click()
}