簡體   English   中英

音頻播放時在背景iOS中的應用程序

[英]Audio playing while app in background iOS

我有一個主要基於核心藍牙的應用程序。 當某些特定事件發生時,使用核心藍牙背景模式喚醒應用程序並觸發警報,但是當應用程序不在前台時,我無法使鬧鍾正常工作。

我有一個Alarm Singleton類,它會像這樣初始化AVAudioPlayer

NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle]
                    pathForResource:soundName
                             ofType:@"caf"]];

self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
[[AVAudioSession sharedInstance] setActive: YES error: nil];
[self.player prepareToPlay];
self.player.numberOfLoops = -1;
[self.player setVolume:1.0];

NSLog(@"%@", self.player);

這是調用我的警報代碼時調用的方法:

-(void)startAlert
{
    NSLog(@"%s", __FUNCTION__);

    playing = YES;
    [self.player play];
    NSLog(@"%i", self.player.playing);

    if (vibrate) {
        [self vibratePattern];
    }
}

現在,當應用程序位於前台時, self.player.playing返回1但是當應用程序在后台時, self.player.playing返回0 為什么會這樣? 正在調用所有代碼,因此應用程序清醒且運行正常。 振動工作完美,使用AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);

知道為什么這個聲音不會播放?

謝謝

Apple在其文檔中有一篇很好的技術問答文章 (另請參閱播放和錄制背景音頻 )。

我認為缺少的一件事是你沒有在Xcode設置中激活音頻背景模式 在此輸入圖像描述

也許在警報方法中添加[self.player prepareToPlay]會很有幫助。

我有一個應用程序,但也需要背景音頻但我的應用程序使用應用程序后台模式“IP語音”,因為它有時需要記錄。 我播放背景音頻告訴應用程序單例我需要在后台播放音頻:

UIBackgroundTaskIdentifier newTaskId = UIBackgroundTaskInvalid;
if([thePlayer play]){
    newTaskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:NULL];   
}

編輯:您必須調用[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:NULL]; 在你的應用程序進入后台之前。 在我的應用中,它是在你開始播放的同時,如果播放器可能在后台啟動,你應該這樣做:

- (void)applicationDidEnterBackground:(UIApplication *)application{
  // You should retain newTaskId to check for background tasks and finish them 
  newTaskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:NULL];   
}

Apple文檔

從“ 功能”選項卡的“后台模式”部分啟用音頻支持

或者通過在應用程序的Info.plist文件中包含帶有音頻值的UIBackgroundModes鍵來啟用此支持

我認為你有為應用程序指定的音頻背景模式。 即便如此,我也不確定您是否可以將音頻會話設置為在后台處於活動狀態。 你需要在進入后台之前激活它。 您可能還需要播放一些靜音以保持此功能,但這似乎是不好的做法(可能會耗盡電池電量)。 查看通知文檔似乎有一種方法可以讓本地通知播放包含在您的包中的音頻樣本,這似乎是您想要做的,所以也許這就是要走的路。

您需要啟用應用程序以在后台處理音頻中斷(並結束中斷)。 應用通過通知中心處理音頻中斷:

  1. 首先,在通知中心注冊您的應用:

     - (void) registerForMediaPlayerNotifications { [notificationCenter addObserver : self selector: @selector (handle_iPodLibraryChanged:) name: MPMediaLibraryDidChangeNotification object: musicPlayer]; [[MPMediaLibrary defaultMediaLibrary] beginGeneratingLibraryChangeNotifications]; } 
  2. 現在在中斷開始時保存玩家狀態:

     - (void) audioPlayerBeginInterruption: player { NSLog (@"Interrupted. The system has paused audio playback."); if (playing) { playing = NO; interruptedOnPlayback = YES; } } 
  3. 並在中斷結束時重新激活音頻會話並恢復播放:

     -(void) audioPlayerEndInterruption: player { NSLog (@"Interruption ended. Resuming audio playback."); [[AVAudioSession sharedInstance] setActive: YES error: nil]; if (interruptedOnPlayback) { [appSoundPlayer prepareToPlay]; [appSoundPlayer play]; playing = YES; interruptedOnPlayback = NO; } } 

這是Apple的示例代碼,完全實現了您要實現的目標:

https://developer.apple.com/library/ios/samplecode/AddMusic/Introduction/Intro.html#//apple_ref/doc/uid/DTS40008845

嘗試這個 :

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:nil];

鏈接

試試這個http://www.sagorin.org/ios-playing-audio-in-background-audio/

我也遇到了同樣的問題,但是我只是在最初的時候才面對它,當我在應用程序處於后台時嘗試播放聲音時,一旦應用程序進入前景並且我播放聲音一次而不是它在后台工作也。

因此,一旦應用程序啟動/登錄成功,我運行此代碼:

[self startRingcall];
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self stopRingcall];
    });
- (void)startRingcall
{
    if( self.audioPlayer )
        [self.audioPlayer stop];
    NSURL* musicFile = [NSURL fileURLWithPath:[[[UILayer sharedInstance] getResourceBundle] pathForResource:@"meetcalling" ofType:@"caf"]];
    NSError *error;
    self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:musicFile error:&error];
    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
    [[AVAudioSession sharedInstance] setActive: YES error: nil];
    if (error != nil) {
        NSLog(@"meetringer sound error -> %@",error.localizedDescription);
    }
    self.audioPlayer.volume = 0;
    [self.audioPlayer play];
    self.audioPlayer.numberOfLoops = 1;
}

- (void)stopRingcall
{
    if( self.audioPlayer )
        [self.audioPlayer stop];
    self.audioPlayer = nil;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM