WebFM API

Non-standard
This feature is not on a current W3C standards track, but it is supported on the Firefox OS platform. Although implementations may change in the future and it is not supported widely across browsers, it is suitable for use in code dedicated to Firefox OS apps.

This API is available on Firefox or Firefox OS for installed or higher privileged applications.

Summary

The WebFM API provides access to the device FM radio. It allows turning the radio on/off and switching among radio stations. This API is available through the navigator.mozFMRadio property which is a FMRadio object.

Turn the radio on/off

Basicaly, the radio is turn on with the FMRadio.enable() method and turn off with the FMRadio.disable() method.

Before turning the radio on, it's wise to check if an antenna is available (without an antena, the build-in radio will not be able to receive any signal). This information is available via the FMRadio.antennaAvailable property. On mobile device, it's the headphone cable that is used as an antenna. Because it's possible to plug/unplugged that cable, the WebFM API will fire an antennaavailablechange event each time the availability of the antenna change.

To turn the radio on it's necessary to provide a frequency to listen. That frequency (in MHz) is a number pass to the FMRadio.enable() method.

// The frequency of the radio station
// to listen express in MHz
var frequency = 99.1;
var radio = navigator.mozFMRadio;
if (radio.antennaAvailable) {
  radio.enable(frequency);
} else {
  alert("You need to plug your headphone");
}
radio.addEventListener('antennaavailablechange', function () {
  if (radio.antennaAvailable) {
    radio.enable(frequency);
  } else {
    radio.disable();
  }
})

Note: The audio is output through the normal audio channel available on the device.

Switching among frequency

Switching from on frequency to another can be done manually or automatically. In any case, the current radio frequency listened to by the built-in radio is always available with the FMRadio.frequency property. That property is number representing the frequency in MHz.

Manual switch

The FMRadio.setFrequency() method must be used to set a new frequency to listen. However, there are some constraints about the value that can be set. The method will return a DOMRequest object to handle the success or error of the method call. The frequency must fulfill the following requirements:

  • The frequency must be in the range defined by FMRadio.frequencyLowerBound and FMRadio.frequencyUpperBound. If the frequency is out of range, it will result in an error.
  • The frequency must be stepped based on the value of FMRadio.channelWidth. If it's not the case, the frequency will be rounded accordingly. For example, if 100MHz is a valid frequency and if channelWidth has the value 0.2, trying to set a frequency of 100.15 will result in a frequency set to 100.2.
var change = radio.setFrequency(frequency);
change.onerror = function () {
  var min = radio.frequencyLowerBound;
  var max = radio.frequencyUpperBound;
  console.warn('The frequency must be within the range [' + min + ',' + max + ']');
}
change.onsuccess = function () {
  console.log('The frequency has been set to ' + radio.frequency);
}

Automated seeking

The WebFM API also provides a convenient way to seek radio channels automatically. To that end, we can use the FMRadio.seekUp() (to find a radio channel on a higher frequency than the current one) and FMRadio.seekDown() method. The former is used to find a radio channel with a higher frequency than the current one, and the latter for a radio channel with a lower frequency. Those methods return a DOMRequest object to handle the success or error of each method call.

Both methods will circle back to higher or lower frequency once they reach the frequencyLowerBound or frequencyUpperBound values. When they find a new radio channel, they change the current frequency and fire a frequencychange event.

It's not possible to seek twice at the same time (e.g. it's not possible to seek up and down at the same time), trying to do so, will result in an error. But if necessary it's possible to stop seeking by calling the FMRadio.cancelSeek() method. This method will also return a DOMRequest object.

var radio   = navigator.mozFMRadio;
var seeking = false;
var UP      = document.querySelector("button.up");
var DOWN    = document.querySelector("button.down");
// When the frequency change, the seek
// functions automatically stop to seek.
radio.onfrequencychange = function () {
  seeking = false;
}
function seek(direction) {
  var cancel, search;
  // If the radio is already seeking
  // we will cancel the current search.
  if (seeking) {
    var cancel = radio.cancelSeek();
    cancel.onsuccess = function () {
      seeking = false;
      // Once the radio no longer seek,
      // we can try to seek as expected
      seek(direction);
    }
  // Let's seek up
  } else if (direction === 'up') {
    // Just to be sure that the radio is turned on
    if (!radio.enabled) {
      radio.enable(radio.frequencyLowerBound);
    }
    search = radio.seekUp();
  // Let's seek up
  } else if (direction === 'down' {
    // Just to be sure that the radio is turned on
    if (!radio.enabled) {
      radio.enable(radio.frequencyUpperBound);
    }
    search = radio.seekDown();
  }
  if (search) {
    search.onsuccess = function () {
      // Ok, we are seeking now.
      seeking = true;
    };
    search.onerror = function () {
      // Something goes wrong... ok, let's try again.
      seek(direction);
    }
  }
}
UP.addEventListener('click', function () {
  seek('up');
});
DOWN.addEventListener('click', function () {
  seek('down');
});

Specification

Not part of any specification.

See also

Document Tags and Contributors

 Last updated by: chrisdavidmills,