SpeakHere的AudioQueue代码在iPad上失败
我在创建必须播放的应用程序中使用SpeakHere音频类&同时记录。SpeakHere的AudioQueue代码在iPad上失败
我在通用应用程序构建中使用带有3.2设备目标的最新SDK(目标为iPad & iPhone)。
该应用程序使用MPMoviePlayerController播放流式电影并同时录制音频。
这在iPhone上100%完美。
但是,它在我的客户iPad上100%失败。日志显示!AudioSession只是拒绝活动的错误!我从他那里收到的每个日志文件都包含众多的中断&路由变更(即类别)被返回给回调函数。 **在iPhone上我根本看不到任何这样的东西。日志只显示记录是创建的,并记录到指定的文件。没有中断,没有路线变化,没有废话。
这里的相关日志:
Jul 10 07:15:21 iPad mediaserverd[15502] <Error>: [07:15:21.464 <0x1207000>] AudioSessionSetClientPlayState: Error adding running client - session not active
Sat Jul 10 07:15:21 iPad mediaserverd[15502] <Error>: [07:15:21.464 <AudioQueueServer>] AudioQueue: Error '!act' from AudioSessionSetClientPlayState(15642)
我掐灭我的两个回调函数仅仅记录中断和路由变化(有原因)的发生。所以我不会打扰发布代码,因为它没有字面意思。我曾多次在iPad上看到这些日志,但一次尝试在iPad上开始录制。
我已经阅读了几乎所有可以在Apple Dev论坛和StackOverflow中找到的帖子,但似乎无法找到具有相同问题或Apple文档中解释iPad行为差异的相关笔记的人。 - 注意:iPad确实显示了一些其他已修复的缺陷行为,例如不匹配的Begin Interruption调用永不结束(所以我从不停用会话)。
我从来没有收到任何日志,指出从AudioQueue或AudioSession代码中的任何失败的初始化或激活调用。当我尝试开始录制时,它会失败。 - 我甚至试图强制AudioSessionSetActive(true);在每次尝试使用音响系统之前都会打电话,但我仍然收到这些错误。
下面是初始化调用的相关代码:
//Initialize the Sound System
OSStatus error = AudioSessionInitialize(NULL, NULL, interruptionListener, self);
if (error){ printf("ERROR INITIALIZING AUDIO SESSION! %d\n", (int)error); }
else {
//must set the session active first according to devs talking about some defect....
error = AudioSessionSetActive(true);
if (error) NSLog(@"AudioSessionSetActive (true) failed");
UInt32 category = kAudioSessionCategory_PlayAndRecord;
error = AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(category), &category);
if (error) printf("couldn't set audio category!\n");
error = AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, propListener, self);
if (error) printf("ERROR ADDING AUDIO SESSION PROP LISTENER! %d\n", (int)error);
//Force mixing!
UInt32 allowMixing = true;
error = AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryMixWithOthers, sizeof (allowMixing), &allowMixing);
if (error) printf("ERROR ENABLING MIXING PROPS! %d\n", (int)error);
UInt32 inputAvailable = 0;
UInt32 size = sizeof(inputAvailable);
// we do not want to allow recording if input is not available
error = AudioSessionGetProperty(kAudioSessionProperty_AudioInputAvailable, &size, &inputAvailable);
if (error) printf("ERROR GETTING INPUT AVAILABILITY! %d\n", (int)error);
isInputAvailable = (inputAvailable) ? YES : NO;
//iPad doesn't require the routing changes, branched to help isolate iPad behavioral issues
if(! [Utils GetMainVC].usingiPad){
//redirect to speaker? //this only resets on a category change!
UInt32 doChangeDefaultRoute = 1;
error = AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryDefaultToSpeaker, sizeof (doChangeDefaultRoute), &doChangeDefaultRoute);
if (error) printf("ERROR CHANGING DEFAULT ROUTE PROPS! %d\n", (int)error);
//this resets with interruption and/or route changes
UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
error = AudioSessionSetProperty(kAudioSessionProperty_OverrideAudioRoute,sizeof (audioRouteOverride),&audioRouteOverride);
if (error) printf("ERROR SPEAKER ROUTE PROPS! %d\n", (int)error);
}
// we also need to listen to see if input availability changes
error = AudioSessionAddPropertyListener(kAudioSessionProperty_AudioInputAvailable, propListener, self);
if (error) printf("ERROR ADDING AUDIO SESSION PROP LISTENER! %d\n", (int)error);
error = AudioSessionSetActive(true);
if (error) NSLog(@"AudioSessionSetActive (true) failed");
}
// Allocate our singleton instance for the recorder & player object
myRecorder = new AQRecorder();
myPlayer = new AQPlayer();
后来在LoadState的回调视频我只是尝试启动记录到预定的文件路径:
myRecorder->StartRecord((CFStringRef)myPathStr);
录音完全失败。
感谢您的时间和帮助。
原来这是一个奇怪的问题。
1)只使用录音和回放,代码在iPad上完美运行。
2)添加电影播放,不要调用任何路由更改,并在iPad上正常工作。
以某种方式,Movie Player播放的存在足以以某种方式更改AudioSession,从而强制更改任何路由(如使用设备扬声器而不是耳机),导致AudioSession变为非活动状态。