3

アプリが国のチャンネル (USA) に接続し、そのチャンネルからレコードの再生を開始する必要があります。これは基本的にユーザーが運営するチャンネルであり、ユーザーはレコードをチャンネルにアップロードし、1 つずつ再生します。チャンネルに接続したユーザーは、チャンネルを聴き始めます。

サーバーは、ソケット経由で再生する必要があるレコードの URL を iOS アプリに送信します。iOS アプリは、URL をAVQueuePlayer( を使用してAVPlayerItems) 1 つずつ再生するために作成します。

チャンネルがほぼ 1 日ほどレコードでいっぱいになっているときにアプリをバックグラウンドにしておくと、アプリは実行を続け、すべてのレコードを 1 つずつ再生し続けます。AVQueuePlayer再生する新しいプレーヤー アイテムを受け取ると、アプリケーションを強制終了せずに常に実行する処理が行われることを私は知っています。

ただし、チャネルにレコードがなく、ユーザーがチャネルに接続した場合、アプリのアイドル時間が 10 分を超えると、アプリはバックグラウンドでレコードを再生しません。

新しいレコード URL を常に受信できるように、ソケット接続を開いたままにするバックグラウンド タスク識別子を使用してコードを記述しました。

デバイスにいくつかのクラッシュ レポートが表示されます。"AppName(my app) has active assertions beyond permitted time"

ここで何が問題なのかを知ることができますか。

バックグラウンドタスクコードも投稿しています

- (void)keepBroadcastPersistentConnection {

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    if(self._bgTaskIdentifier)
        self._bgTaskIdentifier = UIBackgroundTaskInvalid;
    self._bgTaskIdentifier = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler: ^{

        [[UIApplication sharedApplication] endBackgroundTask:self._bgTaskIdentifier];
        self._bgTaskIdentifier = UIBackgroundTaskInvalid;
        CGLog(@"========================================end bg task at time %@", [NSDate date]);
        CGLog(@"Time taken by app to run in bg is %f seconds", [[NSDate date] timeIntervalSinceDate:self.date]);
    }];

    [[BroadcastSocketConnecter sharedSocketConnecter].socketIO sendHeartbeat]; // this keep the socket alive
    self.date = [NSDate date];
    CGLog(@"========================================begin bg task at time %@", self.date);
});
}

ありがとう

4

1 に答える 1

4

オーディオ セッション プログラミング ガイドから:

通常、デフォルトのオーディオ セッションが望ましくない理由

シナリオ 3. Audio Queue Services を使用して再生するストリーミング ラジオ アプリケーションを作成します。ユーザーが聞いている間に電話がかかってきて、予想どおりサウンドが停止します。ユーザーは呼び出しを無視することを選択し、アラートを無視します。ユーザーは [再生] をもう一度タップして音楽ストリームを再開しますが、何も起こりません。再生を再開するには、ユーザーはアプリケーションを終了して再起動する必要があります。

オーディオ キューの中断を適切に処理するには、デリゲート メソッドを実装するか、オーディオ セッション コールバック関数を記述して、アプリケーションが自動的に再生を継続できるようにするか、ユーザーが手動で再生を再開できるようにします。「<a href="https://developer.apple.com/library/ios/documentation/Audio/Conceptual/AudioSessionProgrammingGuide/Cookbook/Cookbook.html#//apple_ref/doc/uid/TP40007875-CH6-SW7" rel を参照してください。 ="nofollow noreferrer">オーディオ セッションの中断に対応しています。」</p>

すぐに解決策は、AVAudioSessionDelegateプロトコルbeginInterruptionendInterruptionメソッドを実装することです。ただし、このクラスのdelegateプロパティはiOS6 で廃止されたため、代わりにNotificationsを使用する必要があります。つまり、あなたが興味を持っているのはAvAudioSessionAVAudioSessionInterruptionNotification

解決。この話によると、再生が停止した場合は、オーディオ セッションを明示的に再度アクティブにして、アプリが終了しないようにする必要があります。

以下はデリゲート実装のソースですが、ロジックは通知によってあまり変わらないので、情報源としてはまだ良いと思います。

- (void) beginInterruption {
    if (playing) {
        playing = NO;
        interruptedWhilePlaying = YES;
        [self updateUserInterface];
    }
}

NSError *activationError = nil;
- (void) endInterruption {
    if (interruptedWhilePlaying) {
        BOOL success = [[AVAudioSession sharedInstance] setActive: YES error: &activationError];
        if (!success) { /* handle the error in activationError */ }
        [player play];
        playing = YES;
        interruptedWhilePlaying = NO;
        [self updateUserInterface];
    }
}

まだ有効ですが、エレガントなソリューションではない古い応答

バックグラウンドでオーディオの再生を開始することはできません。この回答は、上記のコメントで述べたことを説明しています: https://stackoverflow.com/a/16568437/768935でトリックを行ってAudioSessionも、このポリシーには影響がないようです。

解決策として、オーディオを再生し続ける必要があります。キューに項目がない場合は、「無音」オーディオ トラックを挿入します。ただし、このトリックを使用したアプリが App Store で認められるかどうかは疑問です。アプリを再起動すると音声再生が再開されることをユーザーに通知した方がよい場合があります。

于 2013-09-18T13:40:05.150 に答える