MPMusicPlayerController won't seek to given playbackTime

1.4k views Asked by At

I want MPMusicPlayerController.applicationMusicPlayer() instance to start playing from a specific starting time:

applicationMusicPlayer.setQueueWithStoreIDs([String(track.id)])
    applicationMusicPlayer.currentPlaybackTime = 10.0
    print(applicationMusicPlayer.currentPlaybackTime) // will print 10.0

But as soon as the player starts playing the item, it will reset its currentPlaybackTime to zero and will start from the beginning:

applicationMusicPlayer.play()
print(applicationMusicPlayer.currentPlaybackTime) // will print 0.0

I thought maybe it's because I set the playback to the player that has just been created and is not ready yet, but neither .prepareToPlay() or .isPreparedToPlay() help me with that situation.

I even tried to wait for a few seconds and only then start the playback from the position that I've set. No success at all, extremely frustrating.

Maybe it is somehow connected to the fact that I'm playing songs from Apple Music directly? I can't switch to AVPlayer 'cause I have to play music from Apple Music.

Would appreciate any thoughts and help!

UPDATE: I found the method beginSeekingBackward at the MPMediaPlayback and it says that if the content is streamed, it won't have any effect: https://developer.apple.com/documentation/mediaplayer/mpmediaplayback/1616248-beginseekingbackward?language=objc Seems like only built-in Music app has a control over streaming music playback?

1

There are 1 answers

3
Daniel Wood On

I had just run into this exact problem. I managed to get around it with the follow code.

It creates a background thread that continuously checks the currentPlaybackTime of the player. As soon as currentPlaybackTime is not the time I set it to be I set currentPlaybackTime back to what I wanted.

It feels like a terrible hack but it's working for me so far.

MPMusicPlayerController *player = [MPMusicPlayerController systemMusicPlayer];
player.currentPlaybackTime = _startTime;
[player play];

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul);
dispatch_async(queue, ^{
    while(true) {
        if (player.currentPlaybackTime != _startTime) {
            player.currentPlaybackTime = _startTime;
            break;
        }
    }
});