简体   繁体   中英

AVPlayer not forwarding streaming track in background

I'm having an issue with AVPlayer not playing in the background.

Here's the details:

I have an AVPlayer object and an AVPlayerItem as an instance variable of my view controller to stream music from links stored in the NSMutableArray, linkArray . When the user taps a track a track in a UITableView, both objects are instantiated like so:

musicPlayerItem = [[AVPlayerItem alloc] initWithURL:[NSURL URLWithString:[linkArray objectAtIndex:indexPath.row]]];
player = [[AVPlayer alloc] initWithPlayerItem:musicPlayerItem];

...And it plays perfectly. Whenever the track finishes while the app is active it'll skip fine, or when I manually trigger the app to skip track (whether it's active or backgrounded). But, when the app is in the background (including when the device is locked) it will not play the next track when it skips.

So, it skips to the next track on its own but doesn't play it. I either have to make the app active again or invoke the playing (via the headphone controls or the system-wide music controls).

Here is the code for the skipTrack method that is called both when manually invoked or by the system when the song reaches the end of the track:

        if (nowPlaying == [linkArray count]-1) {
            nowPlaying = 0;
            musicPlayerItem = [[AVPlayerItem alloc] initWithURL:[NSURL URLWithString:[linkArray objectAtIndex:0]]];
            player = [[AVPlayer alloc] initWithPlayerItem:musicPlayerItem];
        } else {
            NSLog(@"NowPlaying (before increment: %i", nowPlaying);
            //If not, increment nowPlaying by one and play
            nowPlaying++;
            NSLog(@"NowPlaying (after increment: %i", nowPlaying);
            musicPlayerItem = [[AVPlayerItem alloc] initWithURL:[NSURL URLWithString:[linkArray objectAtIndex:nowPlaying]]];
            player = [[AVPlayer alloc] initWithPlayerItem:musicPlayerItem];
     }

Really hope someone can help me with

So the problem is that because you've enabled your app to play audio in the background it will stay active while music is playing. As soon as the music stops it will be suspended. So you need to request time to execute tasks in the background as soon as the song stops (most players have a callback function for when the song completes, put this code at the beginning). So your code would look something like this...

UIBackgroundTaskIdentifier newTaskID = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
    // Clean up any unfinished task business by marking where you.
    // stopped or ending the task outright.
    [application endBackgroundTask:newTaskID];
    newTaskID = UIBackgroundTaskInvalid;
}];];

if (nowPlaying == [linkArray count]-1) {
        nowPlaying = 0;
        musicPlayerItem = [[AVPlayerItem alloc] initWithURL:[NSURL URLWithString:[linkArray objectAtIndex:0]]];
        player = [[AVPlayer alloc] initWithPlayerItem:musicPlayerItem];
    } else {
        NSLog(@"NowPlaying (before increment: %i", nowPlaying);
        //If not, increment nowPlaying by one and play
        nowPlaying++;
        NSLog(@"NowPlaying (after increment: %i", nowPlaying);
        musicPlayerItem = [[AVPlayerItem alloc] initWithURL:[NSURL URLWithString:[linkArray objectAtIndex:nowPlaying]]];
        player = [[AVPlayer alloc] initWithPlayerItem:musicPlayerItem];
 }

[[UIApplication sharedApplication] endBackgroundTask:newTaskID];
newTaskID = UIBackgroundTaskInvalid;'

The "beginBackgroundTaskWithExpirationHandler:" method will grant you some time to do things while in the background. If your time runs out the block of code that was sent to that method is executed. You need to include that incase something goes wrong and you need to clean up the task. Read more about it at the dev library: here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM