web-dev-qa-db-ja.com

バックグラウンドiOSでアプリ中にオーディオを再生

私は主にコアBluetoothをベースにしたアプリを持っています。特定のことが発生すると、コアBluetoothバックグラウンドモードを使用してアプリが起動し、アラームが鳴りますが、アプリがフォアグラウンドにない場合、アラームを機能させることができません。

AVAudioPlayerを次のように初期化するAlarmSingletonクラスがあります。

_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);を使用するバイブレーションは完全に機能します

この音が鳴らない理由はありますか?

ありがとう

12
Darren

バックグラウンドオーディオも必要なアプリがありますが、アプリは時々録音する必要があるため、アプリのバックグラウンドモード「VoiceoverIP」で動作します。バックグラウンドオーディオを再生して、アプリシングルトンにバックグラウンドでオーディオを再生する必要があることを伝えます。

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];   
}
9
Pablo Romeu

Appleのドキュメントにはこれに関する素晴らしい 技術的なQ&A記事 があります( バックグラウンドオーディオの再生と録音 も参照してください)。

欠けている大きなことの1つは、Xcode設定でオーディオバックグラウンドモードをアクティブにしていないことです。 enter image description here

アラートメソッドに[self.player prepareToPlay]を追加することも役立つかもしれません。

13
Michael Dorner

Apple docs

[機能]タブの[バックグラウンドモード]セクションからオーディオサポートを有効にする

または、UIBackgroundModesキーとaudio値を含めて、このサポートを有効にします。アプリのInfo.plistファイル

3
zeeawan

アプリにオーディオバックグラウンドモードが指定されていると思います。それでも、バックグラウンドでオーディオセッションをアクティブに設定できるかどうかはわかりません。バックグラウンドに入る前にアクティブ化する必要があります。これをアクティブに保つためにサイレントオーディオを再生する必要がある場合もありますが、これは悪い習慣のようです(バッテリーを消耗する可能性があります)。通知のドキュメントを見ると、バンドルに含まれているオーディオサンプルをローカル通知で再生する方法があるようです。これはあなたがやりたいことのように思われるので、おそらくそれが方法です。

2
Lewis Gordon

これを試して :

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

リンク

これを試してください http://www.sagorin.org/ios-playing-audio-in-background-audio/

1
tilak

バックグラウンドでオーディオセッションの中断(および終了した中断)を処理できるようにアプリを有効にする必要があります。アプリは通知センターを介して音声の中断を処理します。

  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

1
Kaveh Vejdani

私も同じ問題に直面していましたが、アプリがバックグラウンドにあるときにサウンドを再生しようとした最初の時間にのみ直面していました。アプリがフォアグラウンドになり、バックグラウンドでも動作するよりも1回だけサウンドを再生しました。 。

したがって、私の場合、アプリが起動/ログインが成功するとすぐに、次のコードを実行していました。

[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;
}
0
Gitesh Agarwal