【问题标题】:AVAudioPlayer cannot play music with a NSTimer in backgroundAVAudioPlayer 无法在后台使用 NSTimer 播放音乐
【发布时间】:2011-12-10 14:20:54
【问题描述】:

我想使用 NSTimer 通过 AVAudioPlayer 播放音乐,但 [player prepareToPlay] 返回 NO 并且不在后台播放。

有人可以给我一些想法吗?

这是我的代码:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(playMusic:) userInfo:nil repeats:NO];
    [self.window makeKeyAndVisible];
    return YES;
}

- (void)playMusic:(NSTimer *)timer{
    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
    NSString *fileName = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"Apologize.mp3"];
    NSURL *fileUrl = [NSURL fileURLWithPath:fileName];
    NSError *error;
    AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:fileUrl error:&error];
    if ([player prepareToPlay]) {
        [player play];
        NSLog(@"start!");
    }else{
        NSLog(@"error msg :%@",error);
    }
}

- (void)applicationDidEnterBackground:(UIApplication *)application {

    if ([[UIApplication sharedApplication] respondsToSelector:@selector(beginReceivingRemoteControlEvents)]){
        [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
    }

    UIBackgroundTaskIdentifier backgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
    //        /* just fail if this happens. */
        [[UIApplication sharedApplication] endBackgroundTask:backgroundTask];
    }];
}

【问题讨论】:

    标签: iphone ios4 background nstimer avaudioplayer


    【解决方案1】:

    您需要在 viewDidLoad 中执行此初始化:

    NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:@"test"
                                                              ofType:@"mp3"];
    NSURL *fileURL = [[NSURL alloc] initFileURLWithPath:soundFilePath];
    self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL
                                                              error:nil];
    [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
    
    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
    [[AVAudioSession sharedInstance] setActive: YES error: nil];
    

    这是用于音频初始化。在这里,在项目中导入了一个名为 test 的 MP3。 请注意,beginReceivingRemoteControlEvents 部分非常重要。没有它,您将无法从后台开始播放,只能继续听已经从前台播放的音乐。

    现在您需要监听事件 didEnterInBackGround(您可以使用应用委托的 applicationDidEnterBackground,但这样您可以将代码放在它的类中属于):

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(didEnterBG:)
                                                 name:UIApplicationDidEnterBackgroundNotification
                                               object:nil];
    

    现在在那个 didEnterBG 方法中:

    self.backgroundTimer = [NSTimer scheduledTimerWithTimeInterval:10.0 target:self selector:@selector(backgroundWork) userInfo:nil repeats:YES];
    [self.backgroundTimer fire];
    

    出于个人原因,我在这里每 10 秒重复一次此声音,但请随心所欲。 最后,backgroundWork方法:

    - (void)backgroundWork{
        [self.audioPlayer prepareToPlay];
        [self.audioPlayer play];
    }
    

    现在您的音频文件正在后台播放:-)

    您还应该注意,您的应用需要拥有特定权限才能继续在后台执行工作。您需要选中“YourTarget”下的框 -> 功能 -> 背景模式:音频和 AirPlay。否则,操作系统将在几分钟内终止您的应用(在没有调试器或仪器的情况下)。

    【讨论】:

    • 这真的很有帮助,但如果我只想在后台模式下启动声音怎么办?因为使用 [self.backgroundTimer fire] 会调用 backgroundWork 并且应用会播放声音
    • 好吧,由于UIApplicationDidEnterBackgroundNotification调用了后台工作函数,所以只有当应用真正进入后台模式时才会播放声音。
    【解决方案2】:

    在开始编码之前。您需要告诉操作系统您想要在后台播放音乐的权限。 您可以通过在应用的 info.plist 中设置 Key 来做到这一点

    <key>UIBackgroundModes</key>
        <array>
                <string>audio</string>
        </array>
    

    这样做,您将能够在应用移至后台时播放音频。

    【讨论】:

    • 但是当我在应用程序中开始播放音乐时,它可以在后台播放...这让我疯狂了很长时间...>_
    【解决方案3】:

    我有同样的问题,但我从这篇文章中找到了解决方案:http://developer.apple.com/library/ios/#qa/qa1668/_index.html

    #import <AVFoundation/AVFoundation.h>
    #import <AudioToolbox/AudioToolbox.h>
    
    AVAudioSession *audioSession = [AVAudioSession sharedInstance];
    
    NSError *setCategoryError = nil;
    [audioSession setCategory:AVAudioSessionCategoryPlayback error:&setCategoryError];
    if (setCategoryError) { /* handle the error condition */ }
    
    NSError *activationError = nil;
    [audioSession setActive:YES error:&activationError];
    if (activationError) { /* handle the error condition */ }
    

    【讨论】:

      猜你喜欢
      • 2011-11-29
      • 2011-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多