3

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?

Jan
  • 184
  • 2
  • 15
  • 1
    I am not sure this is the case for applicationMusicPlayer, but try to define it where it can maintain a strong reference (so, var myPlayer = ApplicationMusicPlayer() ). – solenoid Jul 22 '17 at 17:17
  • @solenoid Well, not that it's being released... It is certainly retained and can playback music. The problem is that it won't playback track starting from certain time trough Apple Music – Jan Jul 22 '17 at 18:58
  • have you tried using systemMusicPlayer()? – solenoid Jul 22 '17 at 19:10
  • @solenoid Yeah, exactly the same behaviour. Seems like AM just doesn't allow the streaming playback from the specific point. – Jan Jul 23 '17 at 09:04
  • @solenoid btw, please see the update – Jan Jul 23 '17 at 09:39
  • That... seems like something apple would do. – solenoid Jul 23 '17 at 12:03
  • I have the same problem. While the player is playing, I can set the currentPlaybackTime and the player resumes from the given time. When I pause the player though, then set the currentPlaybackTime and play again, the currentPlaybackTime is reset to 0 and the player continues from there. Any solution yet, @Jan? – helkarli Aug 24 '17 at 08:33
  • @helkarli Well, I digged a little bit deeper in the topic and at some point found info from Apple that the ability to alter the playback itself is protected by all those agreements with artists and stuff. So from what I understood it's like "I, artist X grant the permission to Apple Music to change the playback of my songs" but it doesn't extend on third party devs like you and me. I can be hugely mistaken here, but that was the deepest level of cause that I could find that could explain why on Earth would Apple restrict that feature – Jan Aug 26 '17 at 16:52
  • @helkarli also I didn't quite understood how you managed to change the playback value when it goes to the given time. You mean that if player is in the state of playing, then we can explicitly give it a timestamp from which to play and when it's not playing, we can't? Is that music streamed from AM? Just a little explanation would be much appreciated – Jan Aug 26 '17 at 16:56
  • Hi @Jan! Yes, this is exactly what I am saying. `let player = MPMusicPlayerController.applicationMusicPlayer() player.setQueueWithStoreIDs(["some store id"]) player.play() player.currentPlaybackTime = 120 debugPrint(player.currentPlaybackTime) //prints 120` and continues the playing at that point. `let player = MPMusicPlayerController.applicationMusicPlayer() player.setQueueWithStoreIDs(["some id"]) player.play() player.pause() player.currentPlaybackTime = 120 player.play() debugPrint(player.currentPlaybackTime) //prints 0 and starts the song from the beginning` – helkarli Aug 28 '17 at 07:16
  • @helkarli are you sure that you are streaming the music from AM and not just playing it from the Library? Can it just happen that this particular song that you are playing is downloaded to the iPhone? Because I just checked your method and it still plays from the very beginning :( – Jan Aug 28 '17 at 11:59

1 Answers1

2

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;
        }
    }
});
Daniel Wood
  • 4,487
  • 3
  • 38
  • 36
  • 1
    Truly barbaric :D Don't you experience any interruptions in the playback? Everything sounds smooth? – Jan Nov 10 '17 at 14:26
  • @Jan I'm still not sure. On my device things sound as they should but I've had test users mention there is a tiny jitter in the music. – Daniel Wood Nov 10 '17 at 15:36
  • I'm using this workaround but my app occasionally crashes with EXC_BAD_ACCESS when it checks for player.currentPlaybackTime in the conditional inside the loop. No idea what's going on. – Germán Jan 09 '21 at 21:57