繁体   English   中英

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

[英]start playing audio from a background task via AVAudioPlayer in Xcode

我试图通过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");
}

说明: bgtimstartDatedifference_player是全局声明的变量。 我从用户触发的方法调用- (void)restartHandler ,并在其内部启动一个10Hz的重复计时器- (void)upd 当达到预设差异时, - (void)playSoundFile调用- (void)playSoundFile并启动并启动播放器。 调用方法结束时的测试NSLog。

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

编辑

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

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

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

以下是我为iOS6和iOS7管理的方法。

1,在plist中添加音频UIBackgroundModes。

2,设置音频会话类别:

3,在主线程中创建AVQueuePlayer,并在应用程序进入后台之前将音频资产排入队列

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

4,确保AVQueuePlayer中的音频队列永远不会变空 ,否则您的应用程序将在完成播放最后一个资产时被暂停。

5,如果5秒不足以让你获得下一个资产,你可以使用后台任务来延迟暂停。 资产准备就绪后,您应该在10秒后调用endBackgroundTask

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

dispatch_async(dispatch_get_main_queue(), ^{

});

将此if添加到- (void) playSoundFile以检查是否创建了播放器,如果没有,则创建它

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

对我来说好像你没有设置合适的背景模式? Xcode截图

此外,看起来像另一个用户有相同的问题,并使用Apple Docs帖子修复它。 链接到邮政

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

[audioSession setActive:YES error:&activationError];

希望能帮助到你!

如果你需要开始在后台播放声音(没有一个技巧,比如继续播放音量为零,直到你需要声音):

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

这对我来说很有用。

对我来说固定的是在应用程序退出时开始播放一些音频,所以我在appDelegate的applicationWillResignActive中添加了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()



}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM