I’m having some trouble loading an audio file in WAV format returned from the backend as a Blob in Angular.
I have in my services the following:
getFileBlob(uniformName: string, path: string) {
const currentPath = path.replace(/\/g, '/');
return this.http.get(`${environment.api_url}/content/v1.4/${currentPath}/${uniformName}/_blob`, { responseType: 'blob' });
}
Where in my Angular component, I have the following:
this.dService.getFileBlob().subscribe((response: Blob) => {
const url = URL.createObjectURL(response);
this.type.set(response.type);
this.src.set(url);
});
I have the correct mapping in my audio source tag:
[
In my template, I have:
<audio #media [vgMedia]="$any(media)" id="myAudio" preload="{{ preload }}" crossorigin>
<source src="{{ src() }}" type="{{ type() }}">
<track
src="assets/data/Downloaded_transcriptVVV.vtt"
kind="metadata"
label="Cue Points"
default
#metadataTrack
/>
</audio>
When I paste the blob in the browser, I get the file downloaded – (blob:http://localhost:4200/7071f3e7-9738-4ad7-b08f-67ddb5852c53)
The problem is that the native HTML audio does not play at all.
One important note is that I’m using Angular in a zoneless mode.
If, however, I put a direct relative URL in the place of the src, it works:
`this.src.set(‘/assets/audio/E_2024-10-07_H_100748_060.wav’)
I would highly appreciate anyone’s advice on what I’m doing wrong.
2
Answers
The issue is that the audio player is loaded without a source. The player doesn’t listen for new or changed sources and is therefore unaware of the added audio. The fix is to use
audio.load()
, which forces the browser to recheck the sources and notice the now added audio.The example below demonstrates that the browser doesn’t play the audio if the
src
is set dynamically.The fix is to use
audio.load()
to reset the player and force it to recheck the sources.Wrap src() in an if clause
When reading the answer from @lusc I realized that this would probably also work and might be even more correct since it won’t render the audio link without a valid
src
:this will render the
audio
element only when you have asrc
hence there will be no need to callload()
afterwards…