UIWebView 中的网络音频 API 停止了音乐应用的当前歌曲

Web Audio API in UIWebView stops Music app's current song

网络音频的简单用法API:

var UnprefixedAudioContext = window.AudioContext || window.webkitAudioContext;

var context;
var volumeNode;
var soundBuffer;

context = new UnprefixedAudioContext();
volumeNode = context.createGain();
volumeNode.connect(context.destination);
volumeNode.gain.value = 1;

context.decodeAudioData(base64ToArrayBuffer(getTapWarm()), function (decodedAudioData) {
    soundBuffer = decodedAudioData;
});

function play(buffer) {
    var source = context.createBufferSource();
    source.buffer = buffer;
    source.connect(volumeNode);
    (source.start || source.noteOn).call(source, 0);
};

function playClick() {
    play(soundBuffer);
}

UIWebView 中工作正常(播放声音);但是当您切换到“音乐”应用程序并播放歌曲,然后返回应用程序并显示 UIWebView 时,歌曲停止播放。

同样的代码在Safari里面没有这个问题

是否有避免这种行为的解决方法?

这是完整的fiddle:

http://jsfiddle.net/gabrielmaldi/4Lvdyhpx/

你在 iOS 吗?这对我来说听起来像是一个音频会话类别问题。 iOS 应用定义了音频与音频的交互方式。来自 Apple's documentation:

Each audio session category specifies a particular pattern of “yes” and “no” for each of the following behaviors, as detailed in Table B-1:

Interrupts non-mixable apps audio: If yes, non-mixable apps will be interrupted when your app activates its audio session.

Silenced by the Silent switch: If yes, your audio is silenced when the user moves the Silent switch to silent. (On iPhone, this switch is called the Ring/Silent switch.)

Supports audio input: If yes, app audio input (recording), is allowed.

Supports audio output: If yes, app audio output (playback), is allowed.

默认类别似乎会静音来自其他应用的音频:

AVAudioSessionCategorySoloAmbient—(Default) Playback only. Silences audio when the user switches the Ring/Silent switch to the “silent” position and when the screen locks. This category differs from the AVAudioSessionCategoryAmbient category only in that it interrupts other audio.

这里的关键在最后一句:"it interrupts other audio"。

根据您是否希望在屏幕锁定时静音等,您可以使用许多其他类别。AVAudioSessionCategoryAmbient 不会静音。

在您应用的 objective-c 部分尝试一下:

NSError *setCategoryError = nil;

BOOL success = [[AVAudioSession sharedInstance]
                setCategory: AVAudioSessionCategoryAmbient
                      error: &setCategoryError];

if (!success) { /* handle the error in setCategoryError */ }