max-audio-player
max-audio-player
Vue 3 audio player that plays broken audio (bad headers, truncated or damaged WhatsApp/phone recordings) by repairing it in the browser with ffmpeg.wasm. Healthy files play natively and never download ffmpeg.
Install
npm install max-audio-player
Requires Vue ^3.3. @ffmpeg/ffmpeg and @ffmpeg/util are installed as dependencies.
Usage
<script setup>
import { MaxAudioPlayer } from 'max-audio-player'
</script>
<template>
<MaxAudioPlayer src="https://example.com/voice.mp4" autoplay @recovered="onFixed" />
</template>
Global registration:
import MaxAudioPlayer from 'max-audio-player'
app.use(MaxAudioPlayer) // <MaxAudioPlayer src="…" />
Vite setup (required)
ffmpeg runs in a web worker that Vite's dependency optimizer breaks. Add to vite.config.js:
export default {
optimizeDeps: { exclude: ['@ffmpeg/ffmpeg', '@ffmpeg/util'] },
}
How it works
- Plays the file natively (fast path).
- If the browser raises an error, downloads the bytes and repairs them with
ffmpeg (
-err_detect ignore_err), then plays the result as a blob URL. - If the download is blocked by CORS and
enable-wisp-proxyis set, retries it through libcurl.js and your Wisp proxy. - If repair fails, shows an error (with a CORS hint when the download is blocked).
Bypassing CORS with a Wisp proxy
<MaxAudioPlayer
:src="url"
enable-wisp-proxy
wisp-proxy-url="wss://wisp.example.com/"
/>
You host the proxy yourself (e.g. epoxy-server
or wisp-server-python) behind TLS so
it is reachable as wss://. TLS stays end to end inside libcurl.js, so the proxy sees only the
destination host. Restrict it to the hosts you need — an open Wisp server is an open TCP proxy.
libcurl.js is LGPL-3.0-or-later.
Props
| prop | default | description |
|---|---|---|
src |
required | audio URL |
recover |
'auto' |
'auto', 'always' (repair first) or 'never' |
format |
'mp3' |
repaired output: mp3, wav, ogg |
autoplay, loop, controls, preload |
passed to <audio> |
|
coreBaseURL |
jsDelivr @ffmpeg/core@0.12.6/dist/esm |
self-host the ffmpeg core here |
fetchOptions |
extra fetch() options for the repair download |
|
enableWispProxy |
false |
retry CORS-blocked downloads through libcurl.js (needs wispProxyUrl) |
wispProxyUrl |
Wisp proxy URL (wss://…) used by enableWispProxy |
|
showStatus |
true |
built-in status text (or use the status slot) |
Events: status, ready, recovered(blobUrl), error(err).
Exposed: audio, play(), pause(). Other attributes fall through to <audio>.
Utilities
import { recoverAudio } from 'max-audio-player'
const playableUrl = await recoverAudio('https://example.com/broken.m4a', {
format: 'mp3',
wispProxyUrl: 'wss://wisp.example.com/', // optional CORS fallback
})
recoverAudio(src, opts) accepts format, coreBaseURL, wispProxyUrl, fetchOptions,
signal and onStep, and resolves to a blob URL. Lower-level helpers are also exported:
repairWithFFmpeg(bytes, opts) and canDecode(bytes).
Limitations
- CORS: repair needs the file to be downloadable. If the host blocks
fetch, use the Wisp proxy fallback, or serve or proxy the file from your own origin. - Expired links: signed URLs (e.g. WhatsApp/Facebook CDN
oe=links) that have expired return 403/404 — there is nothing left to repair. - First repair downloads ~30 MB of ffmpeg core (cached afterwards).
License
MIT
Related Packages
A simple yet powerful music player for VueJs inspired by xns-audio-player
Audio Recorder is a powerful Nuxt.js module that provides advanced audio recordi...
Version History
| Version | Released | Vue | License |
|---|---|---|---|
| 0.1.2 | ^3.3.0 | MIT | |
| 0.1.1 | ^3.3.0 | MIT | |
| 0.1.0 | ^3.3.0 | MIT |
Pre-releases (1)
| Version | Released | License |
|---|---|---|
| 0.0.0-stage |