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:
你在 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 */ }
网络音频的简单用法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:
你在 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 */ }