3

I've looked at MPMoviePlayerController multitasking problem and MPMovieplayerController doesn't play next URL when in background, as well as many other similar questions. None of these solutions have worked for me.

I, like many others, am trying to play a playlist of remote files in the background. I am playing YouTube video files in this case, parsed and played with XCDYouTubeKit. The Kit's XCDYouTubeViewController handles parsing the YouTube video identifier (the sequence of characters after "watch=" in every YouTube URL) and changing the contentURL. I have an array of videos in a PlayQueue singleton, and it plays each of them consecutively correctly when the application is in the foreground. But when it's in the background, the next song loads but it is immediately paused. It plays fine if the user presses play in Control Center or on the lock screen, but I was hoping for a seamless transition between songs.

I have this method that plays the videos (self.moviePlayer is a XCDYouTubeViewController and self.moviePlayer.moviePlayer is the MPMoviePlayerController):

- (void)playVideoWithIdenfifier:(NSString*)identifier
{   
    if ([self checkReachability]) // this simply checks if there's an internet connection
    {
        if (!self.moviePlayer)
        {
            self.moviePlayer = [[XCDYouTubeVideoPlayerViewController alloc] initWithVideoIdentifier:identifier];
            self.moviePlayer.moviePlayer.view.userInteractionEnabled = NO;
            self.moviePlayer.moviePlayer.backgroundPlaybackEnabled = YES;
            [self.moviePlayer presentInView:self.playerContainer];
            [self.moviePlayer.moviePlayer setControlStyle:MPMovieControlStyleNone];
        }
        else self.moviePlayer.videoIdentifier = identifier

        NSError *activationError = nil;
        AVAudioSession *audioSession = [AVAudioSession sharedInstance];
        [audioSession setCategory:AVAudioSessionCategoryPlayback error:&activationError];
        [audioSession setActive:YES error:&activationError];

        [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
        [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:NULL];
        [self becomeFirstResponder];

        [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(sliderUpdate) userInfo:nil repeats:YES];

        self.moviePlayer.moviePlayer.shouldAutoplay = YES;
        [self.moviePlayer.moviePlayer play];

        NSMutableDictionary *songInfo = [[NSMutableDictionary alloc] init];

        MPMediaItemArtwork *albumArt = [[MPMediaItemArtwork alloc] initWithImage:self.imageView.image];

        [songInfo setObject:self.song.title forKey:MPMediaItemPropertyTitle];
        [songInfo setObject:[NSString stringWithFormat:@"%@ - Playing from umusio",self.song.album] forKey:MPMediaItemPropertyAlbumTitle];
        [songInfo setObject:self.song.artist forKey:MPMediaItemPropertyArtist];
        [songInfo setObject:albumArt forKey:MPMediaItemPropertyArtwork];
        [songInfo setObject:[NSNumber numberWithFloat:self.moviePlayer.moviePlayer.currentPlaybackTime] forKey:MPNowPlayingInfoPropertyElapsedPlaybackTime];
        [songInfo setObject:[NSNumber numberWithFloat:self.moviePlayer.moviePlayer.duration] forKey:MPMediaItemPropertyPlaybackDuration];
        [songInfo setObject:[NSNumber numberWithInt:1] forKey:MPNowPlayingInfoPropertyPlaybackRate];
        [[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:songInfo];

        [self.playButton setImage:[UIImage imageNamed:@"BeamMusicPlayerController.bundle/images/pause.png"] forState:UIControlStateNormal];
        [self.playButton setImage:[UIImage imageNamed:@"BeamMusicPlayerController.bundle/images/pause.png"] forState:UIControlStateSelected];
    }
    else [[[UIAlertView alloc] initWithTitle:@"error" message:@"reachability check failed" delegate:nil cancelButtonTitle:@"ok" otherButtonTitles:nil] show];
}

When a video ends, it calls this method, which changes the "current song" property and calls checkSongID, which contacts Parse and matches the iTunesSong to a YouTube video identifier. From there, checkSongID calls the previous method, playVideoWithIdentifier: and passes in the video identifier that it got from Parse. I won't include checkSongID here, it is not a problem as it works fine in the foreground and doesn't interact with the moviePlayer at all.

- (void)moviePlayBackDidFinish:(NSNotification*)notification
{
    iTunesSong* nextSong = [[PlayQueue sharedPlayQueue] nextSong]; // iTunesSong is a custom class that I made.

    self.song = nextSong;
    [self checkSongID];

}

This all works fine in the foreground, any ideas why it immediately pauses in the background?

Community
  • 1
  • 1
Nahum G
  • 125
  • 1
  • 9
  • The following link shows how you can accomplish this: http://stackoverflow.com/questions/15540726/ios-mpmovieplayercontroller-playing-audio-in-background – davetw12 Aug 02 '14 at 21:19
  • @davetw12 I can control the music in the background. My only problem is that when changing videos while the application is in the background, it doesn't automatically start playing- it's paused and the user has to manually press play. – Nahum G Aug 02 '14 at 21:23
  • Did you ever figure this out? If so I'd love to know as I'm having the exact same problem. – gbachik Aug 20 '14 at 03:09

0 Answers0