音频播放器应该在后台播放,并且应该基于硬件静音开关工作。

8
我希望能够在前台和后台播放音频文件,并且它应该与静音开关配合使用,即如果静音开关打开,则不应播放,如果静音开关关闭,则应播放音频。
我正在开发一个SIP电话应用程序。当用户接收到电话时,应用程序应该播放声音/铃声。无论应用程序处于前台还是后台,它都应该播放,并且如果硬件静音开关为ON/OFF,则应该静音/取消静音。
为此,我使用了以下代码AVPlyaer。
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryPlayback error:&error];
[session setActive:YES error:nil];

NSURL * audioFileUrl = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"test1" ofType:@"mp3"]];
AVPlayer *player = [[AVPlayer alloc] initWithURL: audioFileUrl];
[player play];

我还在info.plist中的后台模式中添加了"应用程序通过AirPlay播放音频或流视频"。

在这两种模式下都可以播放,但在硬件静音开关打开时不会静音。 如果使用AVAudioSessionCategoryAmbient,则无法在后台模式下播放。 我使用了AVAudioPlayer,但不能在硬件静音开关打开时找到静音。


可能是 https://dev59.com/aGox5IYBdhLWcg3wOx1i 的重复问题。 - Juan Carlos Ospina Gonzalez
@Juan AVAudioSessionCategoryAmbient在后台没有播放。 - Ganee....
似乎不可能做到。 - NSDeveloper
3个回答

3
你的音频会话类别可能设置不正确。 由于您希望尊重静音开关,因此应使用SoloAmbient。
AVAudioSessionCategorySoloAmbient 默认类别, 除非您使用setCategory:error:或setCategory:withOptions:error:方法设置了一个类别。
通过屏幕锁定和静音开关(在iPhone上称为Ring / Silent开关),使您的音频静音。
默认情况下,使用此类别意味着您的应用程序音频是不可混合的,激活会话将中断任何其他非混合的音频会话。 若要允许混合,请改用AVAudioSessionCategoryAmbient类别。
可在iOS 3.0及更高版本中使用。
您似乎已经使用了这个类别:

AVAudioSessionCategoryPlayback

播放已录制的音乐或其他声音的类别,这些声音对于您的应用程序的成功使用至关重要。

使用此类别时,即使将静音开关设置为静音或屏幕锁定,您的应用程序音频也将继续播放。(在 iPhone 上,该开关称为铃声/静音开关。)如果要在应用程序转换到后台时(例如,当屏幕锁定时)继续播放音频,请将音频值添加到信息属性列表文件中的 UIBackgroundModes 键中。

默认情况下,使用此类别意味着您的应用程序的音频是不可混合的 - 激活会中断任何其他非混合的音频会话。要允许此类别进行混合,请使用 AVAudioSessionCategoryOptionMixWithOthers 选项。

在 iOS 3.0 及更高版本中提供。

Source: https://developer.apple.com/library/prerelease/ios/documentation/AVFoundation/Reference/AVAudioSession_ClassReference/index.html#//apple_ref/doc/constant_group/Audio_Session_Categories


"AVAudioSessionCategoryAmbient" 无法在后台播放,而 "AVAudioSessionCategoryPlayback" 无法与静音开关配合使用。请问有没有一种同时适用于这两种情况的解决方案?或者是否有其他方法可以实现此功能? - Ganee....
@Ganee.... 好的,抱歉我误解了。您想在屏幕关闭时播放音频,但不想在静音时播放。这正确吗?那么我和您一样遇到了同样的障碍。苹果似乎没有为此提供音频类别。很抱歉我没有帮上忙。:( - dss539
但是,Skype 是如何实现这个功能的呢 :( 有任何建议吗? - Ganee....
@Ganee.... 对不起,我不是iOS开发者。我甚至没有iOS设备。希望有人能帮助你。 - dss539
1
这个答案解决了我的问题。我在应用商店收到了负面评价,因为用户将手机设为静音,以为应用程序出故障了。我认为我必须将音频会话设置为AVAudioSessionCategorySoloAmbient,这样你就可以在其他应用程序/ iTunes上播放其音频。然而,使用AVAudioSessionCategoryPlayback,并将其选项设置为AVAudioSessionCategoryOptionMixWithOthers,现在允许我的应用在静音模式下播放声音,同时不中断其他音频源。谢谢! - vikzilla

2

很高兴告诉大家,我找到了Skype是如何实现这个功能的。

在前台,我们可以使用AVAudioSession和任何一个类别来播放铃声。

AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory: AVAudioSessionCategorySoloAmbient error:&error];
[session setActive:YES error:nil];

NSURL * audioFileUrl = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"test1" ofType:@"mp3"]];
AVPlayer *player = [[AVPlayer alloc] initWithURL: audioFileUrl];
[player play];

在后台,我们需要使用带有自定义声音的本地通知。这将与硬件静音开关一起工作。但是此处声音文件长度不应超过30秒。
    UILocalNotification* notification = [[UILocalNotification alloc] init];
    [notification @"Title"];
    [notification setAlertBody:@"Body"];
    [notification setAlertAction:noteAction];
    [notification setSoundName:@"ringtone.mp3"];
    [[UIApplication sharedApplication] presentLocalNotificationNow:notification];

希望这对你有所帮助:)。

1
你能提供更多关于这段代码的上下文吗?我不确定你是在哪里实现它/它如何为你提供关于静音开关的信息。 - vikzilla
它不会提供任何信息,通知声音将根据静音开关工作,AVAudioSession也不会根据静音开关工作。 - Ganee....
@ Ganee....,但是如果在后台状态下有VoIP通话进来并且用户点击了它,前台回来后,您如何管理播放铃声? - Anilkumar iOS - ReactNative
在后台模式下,当您点击通知时,通知声音将停止并打开应用程序。在应用程序打开后(即在前台模式下),如果呼叫仍处于响铃模式,则可以使用AVPlayer播放音频。 - Ganee....
@Ganee.... 这看起来是正确的解决方案,非常感谢!我仍然不明白为什么苹果不提供正确的类别,可以在前台和后台都遵守静音开关。 - Guven

0

这对于iOS9非常有效,不使用后台使用。 - Miro
@Miro,我无法让它正常工作。你有没有可能分享一下你的代码? - vikzilla
他们的网站给了我代码,但是在将他们的.h/.m文件复制到你的项目后,它基本上就是这样的: _detector = [SharkfoodMuteSwitchDetector shared]; _detector.silentNotify = ^(BOOL silent){ /* 在这里做些什么 */ } - Miro

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