MDN wants to learn about developers like you: https://qsurvey.mozilla.com/s3/MDN-dev-survey

B2G OS

Using the AudioChannels API

현재 번역은 완벽하지 않습니다. 한국어로 문서 번역에 동참해주세요.

Non-standard
This feature is non-standard and is not on a standards track. Do not use it on production sites facing the Web: it will not work for every user. There may also be large incompatibilities between implementations and the behavior may change in the future.

오디오 채널 API(Audio Channels API)는 현재 Firefox OS 전용 기능으로, 응용프로그램의 오디오 컨텐트를 중요성에 따른 계층구조로 배치하도록 한다. 이는 다른 오디오의 재생과 액션 발생에 반응하여 오디오가 일시정지되고 다시재생될 때를 지시하고 다른 종류의 볼륨을 제어할 수 있도록 한다. 이 가이드는 오디오 채널에 대한 기본적인 사용방법을 보여줄 것이다.

오디오 채널의 종류는 다음과 같다.

채널 이름 중요도 용도 앱 권한 수준
normal 1 UI 효과음, 앱과 웹 컨텐트 Normal
content 2 음악, 라디오, 비디오 Normal
notification 3 새 이메일, SMS 수신음 Privileged
alarm 4 알람 시계, 캘린더 알람 Privileged
ringer 5 전화 수신 벨소리 Internal
telephony 6 진행중인 통화, VOIP 통화 Internal
publicnotification 7 강제된 카메라 셔터음 Internal

하나의 오디오 채널이 사용되면, 언제든지 낮은 우선순위의 채널들은 자동으로 일시정디 된다. 단, 한가지 예외가 있는데, "normal"과 "content"채널은 동일한 우선순위를 가진다. 이는 "content"채널이 사용된다면 "normal"채널과 믹싱된다는 것을 의미한다. 만약 두 앱이 동시에 "content" 채널을 사용하려 한다면, 포어그라운드 앱이 우선권을 가진다. 만약 두 앱 모두 백그라운드 앱이라면, 마지막에 채널을 사용시도한 앱이 우선권을 가진다.

Note: 각 채널은 음소거와 볼륨 설정을 따로 가지고 있다.

Note: "telephony" 채널은 통화용 내장 스피커를 사용한다. 다른 모든 채널은 스피커 또는 헤드폰/헤드셋 등을 사용한다.

유즈 케이스

As obvious user-centric uses cases, audio channels allow users to play music from audio player apps even when they are running in the background, so they can do other things as it plays. However, they probably want the music to pause when someone rings the phone. As another example, when users mute their phone, they probably don't want to also mute their wake up alarm for the next morning.

Other use cases:

  • When the user leaves an app, under normal circumstances the app should be muted.
  • When the volume keys are used it should change the volume for different audio types depending on context. For example while in the alarm app, the volume keys should adjust the alarm volume and not the "normal" volume.
  • When a video app starts playing audio, background music should be muted while the video is playing.
  • Turn down the volume of background audio rather than completely silence it when the "notification" channel is used.
  • Show which applications/tabs are currently playing audio.
  • Show UI to mute a specific app/tag.
  • Enable a spotify-app/tab to be treated as a music app. I.e. it should be able to get the same benefits as if it had mozaudiochannel=content. Including both the automatic muting of other content audio, and the ability to play in the background.
  • Control which application/tab gets to play audio if there are several background applications that all are attempting to use the "content" channel, but no visible apps using the "content" channel.

예제 앱

To explain audio channel functionality, we have built a sample app, imaginitively called audio-channels-demo (you can see it running live here.) The following shows what it looks like on Firefox OS.

A demo showing a title of AudioChannels demo, with an audio player and a select box to choose an audio channel to play the audio in.

The demo provides an audio player, and a <select> box for choosing what audio channel to play the audio in (only "Normal" and "Content" are provided.) When the content audio channel is selected, you will be able to go to the homescreen and put the app in the background but still have the music keep playing. This is not the case with the normal channel — "normal" audio content is stopped when an app goes into the background.

To interrupt the playing of "content" audio content, you could try phoning the phone that the app is running on, or setting off an alarm. As you can see from the table above, these are both in higher priority audio channels.

The app also fires notifications when audio is interrupted or play resumes, and when the headphones are unplugged or plugged in again. Let's explore how this functionality is implemented.

매니페스트 권한이 요구된다

As explained in the table near the top, the different audio channels require a range of different permission levels for their use in apps, ranging from normal (hosted apps) to internal (also known as certified.) In any case, you do need to declare the permissions field in your manifest.webapp file to use AudioChannels, once per channel (note that we also declared permission to use system notifications, as they are used in our demo app also.)

"permissions": {
  "audio-channel-normal" : {
    "description" : "Needed to play this app's audio content on the normal channel"
  },
  "audio-channel-content" : {
    "description" : "Needed to play this app's audio content on the content channel"
  },
  "desktop-notification" : {
    "description" : "Needed to fire system notifications"
  }
}

Selecting the audio channel

Changing the audio channel to play the audio through in the app is a slightly more complex matter than you might think. Declaring the channel type statically in your HTML might look like this:

<audio mozaudiochannel="content" autoplay src="myAudio.ogg"></audio>

Declaring it dynamically in your JavaScript might look like this:

var player = new Video();
player.mozAudioChannelType = 'content';
player.src = '../video-clips/myVideo.ogv';

However you do it, you need to declare the channel before you declare the src of the media you want to play, so it can be loaded and placed into the right channel. For this reason, our demo app does it in a slightly convoluted way, deleting and then recreating the audio player each time the audio channel is changed:

function createAudio(channelValue) {

  ...

  audioContainer.innerHTML = '';
  var player = document.createElement('audio');
  var source1 = document.createElement('source');
  var source2 = document.createElement('source');

  player.controls = true;
  player.mozAudioChannelType = channelValue;
  source1.src = 'audio/dragon.ogg';
  source1.type = 'audio/ogg';
  source2.src = 'audio/dragon.mp3';
  source2.type = 'audio/mpeg';

  player.appendChild(source1);
  player.appendChild(source2);
  audioContainer.appendChild(player);

  ...

}

channelSelect.addEventListener('change', function() {
  createAudio(channelSelect.value);
});

So the createAudio() function is run when the <select> box (referenced in the JS as channelSelect) has its value changed, with the channelSelect value as a parameter. In this function, the audioContainer (a simple <div> that wraps the audio player) has its contents deleted. Next, a new audio player and <source> elements are created, have their necessary attributes filled in, and are added back into the audioContainer. Note that player.mozAudioChannelType = channelValue; is included before the audio source is set.

So with the audio channel set to "content", you can now keep the audio playing even when the app is in the background.

Setting which channel's volume to control

As well as setting what audio channel your audio is going to play in, you can also separately set what channel will have its volume adjusted when the user presses the device's volume keys. This for example allows us to adjust our standard content's volume without affect ringer or alarm volume. It is controlled using the AudioChannelManager.volumeControlChannel property. So at the top of the createAudio() function, we include this block:

function createAudio(channelValue) {
  if (navigator.mozAudioChannelManager) {
    if(channelValue == 'normal') {
      navigator.mozAudioChannelManager.volumeControlChannel = 'normal';
    } else if(channelValue == 'content') {
      navigator.mozAudioChannelManager.volumeControlChannel = 'content';
    }
    console.log(navigator.mozAudioChannelManager.volumeControlChannel);
  }

  ...

}

The AudioChannelManager object is accessed by a call to the navigator.mozAudioChannelManager property — note the moz prefix. This is first done to provide some rudimentary feature detection, so trying to access this feature won't break the app on platforms that don't support it. Next, we include an if ... else if block to check what channel value was passed into the function from the <select> element, and then set the volumeControlChannel value accordingly.

Firing notifications when the audio is interrupted

Now we have audio playing in an audio channel, it will be interrupted either when a more important audio channel starts being played (for example when a telephone call is received), or when the app is moved into the background in the case of the lowest priority "normal" channel. When this condition ends, our channel will resume playing. We can respond to these events using the mozinterruptbegin and mozinterruptend event handlers, which can be attached to the video or audio player playing the audio. You can see these handlers being used at the bottom of the createAudio() function:

function createAudio(channelValue) {

  ...

  player.addEventListener('mozinterruptbegin', function() {
    var notification = new Notification('Metal interrupted!', { body: "Something more important?" });
  });

  player.addEventListener('mozinterruptend', function() {
    var notification = new Notification('Metal resumed!', { body: "Important thing finished." });
  });
}

Here we attach both relevant event listeners to the audio player; when the events occur, we run simple functions that fire system notifications to tell the user what has happened. See the following screenshots for what it will look like:

A notification at the top of the Firefox OS interface saying Metal interrupted: something more important? A notification at the top of the Firefox OS interface saying Metal resumed: important thing finished?

Firing notifications when the headphones are (un)plugged

The AudioChannelManager object includes a headphones property that returns true if headphones are plugged into the device and false if not, and an event handler — onheadphoneschange — which fires whenever headphones are plugged in to or unplugged from the device. We decided to use these together to create a headphone status notification system:

if (navigator.mozAudioChannelManager) {
  navigator.mozAudioChannelManager.onheadphoneschange = function() {
    if(navigator.mozAudioChannelManager.headphones == true) {
      var notification = new Notification('Headphones plugged in!');
    } else {
      var notification = new Notification('Headphones unplugged!');
    }
  }
}

Let's go through this and explain what's happening. Again, multiple calls are made to navigator.mozAudioChannelManager, first for feature detection, then to set up a function that runs when the onheadphoneschange handler fires. Inside this function, we check whether the headphones property returns true — if so, the headphones are plugged in, so we tell the user that with a notification. If not, they must be unplugged, so we return a suitable notification for that case too. The notifications will look something like this:

A notification at the top of the Firefox OS interface saying Headphones plugged in!

Specifications

The AudioChannels API has no official spec at the moment; see https://wiki.mozilla.org/WebAPI/AudioChannels for implementation details, WebIDL, etc.

Browser compatibility

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari (WebKit)
General support Not supported Not supported Not supported Not supported Not supported
Feature Android Chrome Firefox Mobile (Gecko) Firefox OS IE Phone Opera Mobile Safari Mobile
General support Not supported Not supported Not supported 1.0.1 Not supported Not supported Not supported
publicnotification Not supported Not supported Not supported 1.2 Not supported Not supported Not supported

See also

문서 태그 및 공헌자

 이 페이지의 공헌자: maesiltea
 최종 변경: maesiltea,