This is a chrome bug.
FF does expose the duration of the recorded media, and if you do set the currentTime
of the recorded media to more than its actual duration
, then the property is available in chrome…
function exportAudio(blob) {
const aud = document.getElementById("aud");
aud.src = URL.createObjectURL(blob);
aud.addEventListener("loadedmetadata", () => {
// It should have been already available here
console.log("duration:", aud.duration);
// Handle chrome's bug
if (aud.duration === Infinity) {
// Set it to bigger than the actual duration
aud.currentTime = 1e101;
aud.addEventListener("timeupdate", () => {
console.log("after workaround:", aud.duration);
aud.currentTime = 0;
}, { once: true });
}
});
}
// We need user-activation
document.getElementById("button").onclick = async ({ target }) => {
target.remove();
const resp = await fetch("https://upload.wikimedia.org/wikipedia/commons/4/4b/011229beowulf_grendel.ogg");
const audioData = await resp.arrayBuffer();
const ctx = new AudioContext();
const audioBuf = await ctx.decodeAudioData(audioData);
const source = ctx.createBufferSource();
source.buffer = audioBuf;
const dest = ctx.createMediaStreamDestination();
source.connect(dest);
const recorder = new MediaRecorder(dest.stream);
const chunks = [];
recorder.ondataavailable = ({data}) => chunks.push(data);
recorder.onstop = () => exportAudio(new Blob(chunks));
source.start(0);
recorder.start();
console.log("Recording...");
// Record only 5 seconds
setTimeout(function() {
recorder.stop();
}, 5000);
}
<button id="button">start</button>
<audio id="aud" controls></audio>
So the advice here would be to star the bug report so that chromium’s team takes some time to fix it, even if this workaround can do the trick…