chudin26
chudin26

Reputation: 1172

How to make delays between AVPlayerItems in AVQueuePlayer in background task?

I trying to make delays between AVPlayerItems, but I don't understand how to make this. I need to play sounds in background (when iOS app in background) with delays between these sounds. But AVQueuePlayer doesn't support this feature. When i trying to pause the sound after it finished, the next sound don't want to play. However, in foreground that algorithm works fine.

This is code, which i running in background task:

AVQueuePlayer *player = [[AVQueuePlayer alloc] initWithItems: items];
[player play];

NSUInteger currentIndex = 0;
AVPlayerItem *lastItem = nil;
while(currentIndex < items.count && self.enabled) {
    AVPlayerItem *currentItem = [player currentItem];

    while(currentItem == lastItem || currentItem == nil) {
        [NSThread sleepForTimeInterval:0.2f];
        currentItem = [player currentItem];
    }

    while(currentItem.status != AVPlayerItemStatusReadyToPlay) {
        [NSThread sleepForTimeInterval:0.2f];
        NSLog(@"Loading...");
    }

    lastItem = currentItem;

    CGFloat time = 0.0f;
    CGFloat duration = 0.0f;

    while(duration < 0.5f) {
        [NSThread sleepForTimeInterval: 0.5f];
        if(currentItem.duration.timescale > 0)
            duration = (double) currentItem.duration.value / (double) currentItem.duration.timescale;
    }

    while(time < duration - 0.1f) {
        [NSThread sleepForTimeInterval: 0.08f];
        time = (double) currentItem.currentTime.value / (double) currentItem.currentTime.timescale;
    }

    [player pause];

    CGFloat delay = someDelayBetweenSounds;
    [NSThread sleepForTimeInterval: delay];

    [player play];

    currentIndex++;
}

My English is very bad, therefore I apologize

Upvotes: 1

Views: 473

Answers (1)

Oren
Oren

Reputation: 5103

When an item finishes, you can pause the player and start it up again after a given delay. It's much better to do it this way than blocking an entire thread.

- (void) AVPlayerItemDidPlayToEndTimeNotification: (NSNotification *)notification {
    self.avQueuePlayer.rate = 0;
    CGFloat delay = 500;
    dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, (delay) * NSEC_PER_MSEC);
    dispatch_after(delay, dispatch_get_main_queue() , ^{
         self.avQueuePlayer.rate = 1;
});

Upvotes: 1

Related Questions