This is a chrome bug.
FF does expose the duration of the recorded media, and if you do set the currentTimeof 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…