15

iOS の StackOverflow でのバックグラウンド ミュージックの再生に関して、多くの質問があります。すべてのエッジ ケースを完全に調査するものはありません。この質問の目的は、iOS のバックグラウンド オーディオに関する質問の最後の言葉になることです。

定義と仮定

すべてのコード、質問、および例はを参照しています。

"background" — ユーザーがホーム ボタンまたは電源ボタンを押したとき (デバイスがロック画面を表示するとき) にアプリが置かれる状態。マルチタスク スイッチャーまたは iPad のマルチタスク ジェスチャを使用して、アプリをバックグラウンドにすることもできます。

"audio" — AudioQueue (AVAudioPlayer を含む) を使用して再生されるオーディオ

前提条件

私が理解しているように、アプリがバックグラウンドでオーディオを再生するには、2 つの要件があります。

  1. に設定UIBackgroundModes_audioInfo.plist
  2. [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];

要件

私のユースケースは、バックグラウンドで比較的長いオーディオ (音楽) を再生することです。何百ものトラックが存在する可能性があり、アプリはそれらを順番に再生します。オーディオは無期限に再生されると見なすことができます。

アプリは、再生を一時停止することで中断を処理します。

質問

私はさまざまな成功を収めました:

[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:...];

バックグラウンドでオーディオを再生できるようにします。しかし、それが必要かどうか、およびそれが次のようにどのように異なるかについて、私は混乱しています:

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

エッジケース

  1. 中断。の代理人になって、音声の中断(電話など)の通知を受け取るように登録すると、AVAudioPlayer. たとえば、中断の開始時に音声を一時停止または停止し、中断の終了時に再開する場合、中断が 10 分 (バックグラウンド タスクの完了に許可される最大時間) を超えた場合、アプリは中断されますか?

  2. 以下を使用しているときに Lock または Home が呼び出されると、シミュレーターは音声を停止します。

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

ただし、これはデバイス上で機能します。これは既知の問題ですか?

4

2 に答える 2

5

GPS バックグラウンド モードとバックグラウンド オーディオの経験があります。これはあなたの状況とまったく同じではありません (あなたは長いオーディオ ファイルを再生したいのですが、私は短いメッセージを再生します)。

  • beginBackgroundTaskWithExpirationHandlerこのセレクターには、バックグラウンドで呼び出される場合の目的が 1 つあります。それは、アプリケーションが、コードを呼び出すことができない一時停止状態に戻らないようにすることです (「フリーズ」しています)。beginBackgroundTaskWithExpirationHandlerそのため、長時間実行されているタスクを で終了する前に呼び出している限りbeginBackgroundTaskWithExpirationHandler、CPU を使用し、バッテリーを消費します。バックグラウンドでファイルを再生すると、アプリが実行されているかのように iPhone のバッテリーを使用する必要があるとは思えないので、それが実際にフローに関与しているとは
    思えません。beginBackgroundTaskWithExpirationHandler

  • シミュレーター: シミュレーターに依存しないでください: シミュレーターはバックグラウンド モードを完全には実装していません。実際には、ホーム ボタンをクリックするとアプリがバックグラウンドになりますが、この段階ではまだアプリでコードを実行できる場合があります。しばらくすると、アプリが一時停止 (= 凍結) され、バッテリーを節約するためにコードの実行が一時停止されます。このサスペンド状態はシミュレータ上では発生しません。

  • 中断。電話がかかってきたときに再生を一時停止/再開するのはあなた次第ではありません。プラットフォームがこれを担当しており、AVAudioSessionDelegateでこれに反応することができます。ただし、オーディオ セッションでプロパティを設定することにより、セッションが他のオーディオ サウンドと対話する方法に影響を与えることができます (たとえば、 kAudioSessionProperty_OverrideCategoryMixWithOthersを参照してください)。フローは以上です。オーディオ セッションがシステムの残りの部分と対話する方法を記述します。システムはそれに応じてサウンドをミックスし、セッションが中断された場合は、AVAudioSessionDelegate で通知されます。

お役に立てれば。

于 2012-08-29T15:29:11.363 に答える
3

以下のコードをデバイス制御に使用しました-

[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[self becomeFirstResponder];

リモコンをリッスンするためのレジスタを取得するために使用されます。完了したら、それを削除します -

[[UIApplication sharedApplication] endReceivingRemoteControlEvents];
[self resignFirstResponder];

アプリをcanBecomeFirstResponderにする-

- (BOOL)canBecomeFirstResponder {
    return YES;
}

デリゲート メソッドを使用して、ホーム ボタンを 2 回タップしている間の再生や一時停止など、iPhone の制御を処理しました。

- (void)remoteControlReceivedWithEvent:(UIEvent *)event {
    //if it is a remote control event handle it correctly
    if (event.type == UIEventTypeRemoteControl) {
        if (event.subtype == UIEventSubtypeRemoteControlPlay) {
           [audioPlayer play];
            NSLog(@"play");
        } else if (event.subtype == UIEventSubtypeRemoteControlPause) {
           [audioPlayer stop];
             NSLog(@"pause");
        } else if (event.subtype == UIEventSubtypeRemoteControlTogglePlayPause) {
            NSLog(@"toggle");
        }
    }
}
于 2012-08-30T12:24:55.747 に答える