Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 通过Xcode中的AVAudioPlayer开始从后台任务播放音频_Ios_Iphone_Objective C_Ios7 - Fatal编程技术网

Ios 通过Xcode中的AVAudioPlayer开始从后台任务播放音频

Ios 通过Xcode中的AVAudioPlayer开始从后台任务播放音频,ios,iphone,objective-c,ios7,Ios,Iphone,Objective C,Ios7,我正试图通过一个AVAudioPlayer从一个后台任务开始播放声音,这个AVAudioPlayer被实例化了,下面是我得到的 为了便于阅读,我删掉了所有用户选择的值 - (void)restartHandler { bg = 0; bg = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{ [[UIApplication sharedApplication

我正试图通过一个AVAudioPlayer从一个后台任务开始播放声音,这个AVAudioPlayer被实例化了,下面是我得到的

为了便于阅读,我删掉了所有用户选择的值

- (void)restartHandler {
    bg = 0;
    bg = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
        [[UIApplication sharedApplication] endBackgroundTask:bg];
    }];
    tim = [NSTimer timerWithTimeInterval:.1 target:self selector:@selector(upd) userInfo:nil repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:tim forMode:NSRunLoopCommonModes];
}

- (void)upd {
    if ([[NSDate date] timeIntervalSinceDate:startDate] >= difference) {
        [self playSoundFile];
        [tim invalidate];
        [[UIApplication sharedApplication] endBackgroundTask:bg];
    }
}

- (void)playSoundFile {

    NSError *sessionError = nil;
    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&sessionError];


    // new player object
    _player = [[AVQueuePlayer alloc] init];
    [_player insertItem:[AVPlayerItem playerItemWithURL:[[NSBundle mainBundle] URLForResource:@"Manamana" withExtension:@"m4a"]] afterItem:nil];

    [_player setVolume:.7];
    [_player play];

    NSLog(@"Testing");
}
说明:
bg
tim
startDate
difference
\u player
是全局声明的变量。我从用户启动的方法调用
-(void)restartHandler
,并在其中为
-(void)upd
启动一个10Hz的重复计时器。当达到预设差异时,
-(void)playSoundFile
将被调用并启动播放器。调用方法末尾的测试NSLog

现在奇怪的是,如果我在应用程序处于活动状态时调用
-(void)playSoundFile
,一切正常,但如果我从后台任务启动它,它就不会播放任何声音

编辑

所以我尝试在运行时使用不同的线程,看起来,如果播放器没有在主线程上实例化,同样的问题也会出现。
我还尝试使用了
AVPlayer
AVAudioPlayer
,其中
AVAudioPlayer
。playing
属性确实返回了YES,但仍然没有声音播放。

在下面包含您的
playSoundFile
调用,这应该总是在主线程中运行

dispatch_async(dispatch_get_main_queue(), ^{

});
将此if添加到您的
-(void)playSoundFile
以检查是否创建了播放机,如果未创建,则创建播放机

if(!_player) {
    _player = [[AVQueuePlayer alloc] init];
}

在我看来,好像你没有适当的背景模式设置?

另外,看起来另一个用户也有同样的问题,并用Apple Docs的帖子修复了它

您可能只需执行以下步骤即可将音频会话设置为活动:

[audioSession setActive:YES error:&activationError];

希望有帮助

根据我在编写播放器应用程序后了解到的情况,当应用程序在后台的时间超过X秒时,似乎无法开始播放音频,即使您已正确配置了所有内容

要修复它,您必须明智地使用后台任务。 最重要的是,您必须不要在
playSoundFile
之后立即调用
endBackgroundTask
延迟约5-10秒。

下面是我如何为iOS6和iOS7做到这一点的

1、在plist中添加音频UIBackgroundModes

2、设置音频会话类别:

3、在应用程序进入后台之前,在主线程中创建一个AVQueuePlayer并将音频资源排队。

*用于在后台继续播放(如播放播放列表)*

4、确保AVQueuePlayer中的音频队列永远不会变为空,否则您的应用程序在播放完最后一个资源后将被挂起


5,如果5秒不足以获取下一个资源,您可以使用后台任务延迟暂停。当资源准备就绪时,您应在10秒后调用
endBackgroundTask

如果需要开始在后台播放声音(无需技巧,例如在需要声音之前一直以零音量播放):

  • 在p列表中设置背景模式音频
  • 将AudioSession类别设置为AVAudioSessionCategoryPlayback
  • 将AudioSession设置为活动
  • 当你的后台应用程序运行时,在播放声音之前启动一个后台任务(显然,当剩余的后台时间少于10秒时,声音不会播放)

这对我来说现在起作用了。

我解决的办法是在应用程序退出时开始播放一些音频,所以我在AppDelegate的ApplicationWillResignative中添加了1秒空白音频

func applicationWillResignActive(_ application: UIApplication) {

        self.backgroundUpdateTask = UIApplication.shared.beginBackgroundTask(expirationHandler: {
            self.endBackgroundUpdateTask(true)
        })


        let secSilence = URL(fileURLWithPath: Bundle.main.path(forResource: "1secSilence", ofType: "mp3")!)

        do {
            audioPlayer = try AVAudioPlayer(contentsOf: secSilence)
        }
        catch {
            print("Error in loading sound file")
        }

        audioPlayer.prepareToPlay()
        audioPlayer.play()



}

mh,如果我使用这个,当我返回应用程序并使其激活时,首先创建整个播放器…mh是的,但无论是否有,都会创建_播放器,但处理程序只会在应用程序再次激活时被调用。如果应用程序再次激活,将不会再次创建_播放器,因为它不会为零,如果我误解,请纠正我谢谢你的评论。不,我的意思是,我在dipatch_async中写的所有内容只有在我返回应用程序时才会被调用…这是个好主意,但我已经这么做了,但没有任何帮助。我正计划尽快用一个新项目来尝试所有内容。谢谢你,先生!这是天才。我不确定苹果是否会接受我目前的持续循环的解决方案g是一个.m4文件,在播放器开始播放之前一直保存一个空声波,但现在它可以工作。你们是否在未被禁止的情况下将其提交到应用商店?请检查beginBackgroundTaskWithName:expiration handler: