1
votes

I have an application that loads an audio clip into an audio tag dynamically at runtime. It does this by converting the audio to a base64 data-url and assigning that to the tag's src attribute.

The issue is that the audio tag does not process the data until after the audio clip has been fully played through once. This issue shows up on the tag as (1) a lack of audio length, (2) a disabled time-scrubber and (3) the 3-dot icon not displaying. These features do appear as soon as the audio clip has been played for the first time.

I need a way to get the audio tag to process the audio clip as soon as it has been assigned. The user needs to be able to download the audio and fastforward with the time-scrubber without being forced to play through the entire audio clip.

I've searched extensively for a solution to this. I've tried audioTag.preload = "auto"; and calling audioTag.load(); after assigning the src. I've also let it sit for 15 minutes, in case it was just slow to load.

I am open to an alternative to using a base64 data-url formatting, if it will allow me to bypass this issue.

Thanks for any help you can provide.

EDIT: I see this issue in Chrome 80 and Firefox 75.

EDIT: I am generating an audio clip and assigning it to the audio tag in two ways: (1) from a 'file' input tag (2) from a MediaRecorder (connected to the web audio api).

Here is the 'file' input tag loading:

const reader = new FileReader();
reader.onload = () =>
{
    const audioTag = document.getElementById("audioTag");
    audioTag.preload = "auto";
    audioTag.src = reader.result;
    audioTag.load();
};
reader.readAsDataURL(fileInputTag.files[0]);

Here is the MediaRecorder loading:

mediaRecorder.onstop = () =>
{
    const blob = new Blob(audioChunks, {type : "audio/wav"});
    let reader = new FileReader();
    reader.onload = () =>
    {
        let audioTag = document.getElementById("rec");
        audioTag.preload = "auto";
        audioTag.src = reader.result;
        audioTag.load();
    };
    reader.readAsDataURL(blob);
};

I've just determined that opening a wav file created with audacity works fine. The issue only shows when opening an audio file saved from the MediaRecorder.

I've determined that MediaRecorder is actually producing 'webM/opus' files rather than 'wav' files. Research strongly suggests that 'webM' is the only recording option available for MediaRecorder on chrome (firefox also allows 'ogg'). No 'wav' file support. I'm going to post a "solution" now.

1
Yeah, don't use base64 encoding for things like this. :-) There are definitely alternatives (such as using a Blob), but you didn't mention what specifically it is you're trying to do so it's hard to figure out what to suggest. Why did you choose data URIs to begin with? Where is this dynamic audio data coming from?Brad
may you provide a simple snippet? preload works fine in normal workflowMhmdrz_A
@Brad. I am using base64 dada uri's just because that's what I saw being used in articles I read. I also tried loading a blob through URL.createObjectURL, but it didn't fix the problem. However, I've recently determined that it is the audio data itself causing the issue. See my posted answer if your curious.Jonathan Heard

1 Answers

0
votes

I've determined that this issue involves my use of MediaRecorder to generate the audio clips and then to save the audio clips to files. The audio is actually in 'webm/opus' format. MediaRecorder doesn't support 'wav' or 'ogg' (at least in chrome). Moreoever, the clips created by MediaRecorder are not seekable and can only be scrubbed or downloaded once they are played through completely at least once, as discussed in this chromium bug.

I will be looking for an alternative way to record audio as MediaRecorder is currently insufficient for my needs due to (1) clip unseekability (2) format incompatibility.