Mik
Mik

Reputation: 385

How to get MIME type of audio stream?

I want to display a type of audio (mp3, ogg, aac e.t.c) while a Web radio station playing. My player code is simple in briefly:

let audio = new Audio;
audio.addEventListener('loadeddata', () => audio.play());
audio.src = 'https://some-radio-station.com/stream';

I found no way to get file or HTTP response metadata using web audio API. May be is possible to load a short part of stream using fetch?

By the way is there a method to detect audio bitrate too?

Upvotes: 1

Views: 783

Answers (2)

Marcel
Marcel

Reputation: 15742

You could issue a second request, as you already propose. It's actually possible to get the headers only, keeping server load low, even with the Fetch API itself. See this existing answer: https://stackoverflow.com/a/47241400/79485

fetch(url, {method: 'HEAD'})

Then extract the content-type header to get the, well, content type.

To get other metadata of the media file / stream itself, you still would need to get actual content. Not all media formats provide the same metadata, and in the same format. You would need to handle each format separately.

Cheat

If you, however, are only interested in approximate bitrates, and know the duration of your sound (given it's already loaded in the audio element), and the headers provide an content-length info, you can calculate the raw bitrate like this: https://stackoverflow.com/a/21663002/79485. It's already been done here: https://stackoverflow.com/a/11587642/79485

Upvotes: 0

Mik
Mik

Reputation: 385

The way I could make work:

//module
function ObtainStreamHeaders(src) {
  return new Promise((resolve, reject) => {
    const controller = new AbortController;
    fetch(src, {signal: controller.signal})
      .then(response => {
        controller.abort();
        let headers = {};
        for (var pair of response.headers.entries()) {
          headers[pair[0]] = pair[1];
        }
        resolve(headers);
      })
      .catch(e => reject(e));
  });
}
export default ObtainStreamHeaders;
//using
import ObtainStreamHeaders from './ObtainStreamHeaders.js';
audio.onplaying = () => ObtainStreamHeaders(audio.src)
      .then(headers => {
        document.getElementById('mime').innerText = 
          headers['content-type'] || 'unknown';
        document.getElementById('br').innerText = headers['icy-br'] ? 
          (parseInt(headers['icy-br'], 10) + 'kbps') : 'unknown';
      });

This code downloads a small part of an audio stream and gets server headers

Upvotes: 1

Related Questions