在iOS上同时录制和播放(Phonegap构建)

5

我正在使用Phonegap Build版本3.3.0开发iOS和Android应用程序。

应用程序的主要重点是在后台播放另一段音频/音乐的同时进行音频录制。

对于这两种情况,我都使用了Phonegap媒体API,并使用正确的音频文件进行录制(iOS- *.wav / Android- *.amr)和播放(iOS和Android- *.mp3)。

例如:

var audioRec = new Media(audioRecSrc, onSuccess, onError);
audioRec.startRecord();

var audioPlay = new Media(audioPlaySrc, onSuccess, onError);
audioPlay.play();

Example在Android上运行没有任何问题。声音可以记录并播放正常。但是在iOS上只有一个功能可用。无论是play还是record都是最后一个被调用的。另一个返回错误,错误代码为4

这是Phonegap Media API在iOS上的限制还是我漏掉了什么?


我相信这是iOS本身的限制。我不确定,因为我不是一个苹果开发者,但即使在iPad上尝试在GarageBand中录制同时播放音乐也会强制停止音乐。在iPad上进行Skype会话时也会出现同样的情况。 - Kyle
1
我不相信这是iOS的限制,因为我在iOS上玩过本地(非phonegap)音乐游戏(StarComposer - URL: https://itunes.apple.com/si/app/starcomposer/id670221315?mt=8),在那里这个功能是可以实现的。当然需要使用耳机,但仍然可以实现。 - matjazu
有关这个问题有任何新的消息吗?你设法解决了吗? - cherouvim
@cherouvim,我添加了一个新的更新,尝试一下其他的方法。我的第一个答案可能是错误的;显然,在iOS中录制音频有一个小问题。 - aecend
@user3564695,请告诉我我发布的答案是否对您有帮助。 - aecend
显示剩余3条评论
2个回答

3
为了能够同时播放媒体和录制音频,必须将AVAudioSession的category属性设置为AVAudioSessionCategoryPlayAndRecord。要做到这一点,您必须部署一个自定义的iOS插件来设置相应的值。
目前来看,这个过程并不是非常简单,因为Cordova Media插件中存在一个bug。在开始录制之前,插件会 indiscriminately 设置AVAudioSession的category为AVAudioSessionCategoryRecord。由于这个原因,在开始录制后,播放所需的媒体就变得不可能了,除非您在调用record方法后明确设置AVAudioSession category为play-and-record。这表明只有在录制开始后才能播放您的媒体。 然而,这个解决方法在许多场景下可能是不可接受的,因为它要求在录音之前开始播放媒体。因此,我已经报告了这个问题的错误,并在此处提供了报告链接:

iOS Media plugin: cannot play video and record audio simultaneously

另外,我已经应用了修复,并执行了以下拉取请求:

在录音之前检查avSession.category是否已设置为“AVAudioSessionCategoryPlayAndRecord”

这只需要一个小修复(只有两行代码),因此我相信它很快就会应用于主分支。


根据您的发现,我尝试使用低延迟音频插件来找到解决方法,该插件使用AudioToolbox框架中的Sound Services而不是AVAudio。我使用所提到插件的preloadFX函数加载音频文件,并使用使用AVAudio的标准Media类进行录制。然而,尝试也失败了,只有Media类记录工作,而Low Latency Audio没有播放任何错误。基于此(两个不同系统音频播放器的组合也没有帮助),我不确定更改AVAudioSession的category属性是否真的有帮助。 - matjazu
事实上,你提到的插件的Objective-C代码依赖于AVFoundation。因此,很明显底层机制与AVAudioSession实例绑定。尽管如此,在发布之前我的理论已经得到了证实,因为我目前正在开发一个需要同时播放Html5视频和录制音频的项目。 - nachos
我不知道LLA插件在使用AudioToolbox框架的Sound Service时也依赖于AV。我想这就是正确的答案。谢谢你的分享 :) - matjazu

0

更新

经过进一步的调查,我可能是错的。根据Cordova Media API documentation,在iOS中录制音频时,您要录制的文件必须已经存在并且是.wav文件。也许您已经尝试过这个(如果是这样,那么我的先前答案可能是正确的),但是这里有一个简单的脚本来创建文件,一旦文件句柄准备好就开始录制:

var audioRecSrc = "myrecording.wav";
var audioPlaySrc = "audiotoplay.mp3"

// Wait for PhoneGap to load
document.addEventListener("deviceready", onDeviceReady, false);

// PhoneGap is ready
function onDeviceReady() {
    window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFS, fail);
}

function gotFS(fileSystem) {
    fileSystem.root.getFile(audioRecSrc, {create: true, exclusive: false}, gotFileEntry, fail);
}

function gotFileEntry(fileEntry) {
    var audioRec = new Media(audioRecSrc, onSuccess, onError);
    audioRec.startRecord();

    var audioPlay = new Media(audioPlaySrc, onSuccess, onError);
    audioPlay.play();
}

function fail(error) {
    console.log("error : " + error.code);
}

如果您需要参考,这里是Cordova文件API文档的链接。您还需要确保在应用程序配置中具有适当的权限以使用文件和媒体API(您需要的所有内容都在我链接的页面上)


先前内容

这是iOS的一个限制。以下是Mobile Safari文档的摘录(当PhoneGap使用iPhone SDK编译时,它使用本地UIWebView):

多个同时音频或视频流

目前,运行iOS的所有设备都仅限于同时播放一个音频或视频流。在iOS设备上不支持播放多个视频——并排,部分重叠或完全重叠。同时播放多个音频流也不受支持。但是,您可以动态更改音频或视频源。有关详细信息,请参见“按顺序替换媒体源”(第41页)

从逻辑上讲,如果不能同时播放两个流,则同时进行播放和录制也是不可能的。至于关于StarComposer应用的评论,原生iPhone应用程序与使用PhoneGap的应用程序之间有很大的区别。PhoneGap使用Cordova使开发人员可以使用JavaScript访问本机设备功能的子集,而原生应用具有完整的功能范围。您所经历的有限流媒体功能是由于iOS平台上HTML5实现的缘故。这是我从中引用上述语录的文档,它在第23页:

https://developer.apple.com/library/safari/documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/Using_HTML5_Audio_Video.pdf


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接