AudioPlayer icon indicating copy to clipboard operation
AudioPlayer copied to clipboard

Playback magically resumes when being paused from lockscreen and screen goes off

Open MattesGroeger opened this issue 8 years ago • 5 comments

Ok, this one is not very obvious :)

Steps to reproduce:

  1. Play an item queue
  2. Go to the lockscreen and pause the playback
  3. Wait for the screen to turn off, the playback will now continue (Paused -> Buffering -> Playing)

Results from my investigation:

The playback is triggered because the KVO on currentItem.playbackBufferEmpty is triggered. It then sets the state to buffering and afterwards starts the background task.

First question is probably why the playbackBuffer is suddenly empty. But as this comes from the AVPlayer framework it's probably sth. to deal with. One way would be to just stay in the .Paused state? Not sure which consequences that would have.

Hope for your help once again. Thanks for your great effort!

MattesGroeger avatar Apr 13 '16 16:04 MattesGroeger

Hi @MattesGroeger, Thanks again for reporting this issue, I appreciate it very much. Anyhow, I cannot seem to reproduce the issue. What I tried based on your scenario:

1. Play an item
2. Wait for it to start playing (but not fully buffered)
3. Go to lock screen immediately
4. Pause
5. Wait for it to resume playing

I waited like ~5mins but still, the player was Paused. Here are my logs:

Buffering
Playing
Paused

I also tried this but couldn't complete the test:

1. Play an item
2. Don't wait for it to start playing and go to lock screen
3. Go immediately to lock screen
4. Since the player hasn't started emitting any sound, the lock screen doesn't display `MPNowPlayingInfoCenter` yet.

delannoyk avatar Apr 14 '16 17:04 delannoyk

Yes I did exactly that, multiple times and it always resumed. I tested on an iPhone 4S with iOS 8.x, though. Maybe that makes the difference? It might also be other changes that cause this or the way we use it in our app. I can try on Monday with your latest stable version again. Thanks for trying to reproduce this.

MattesGroeger avatar Apr 16 '16 11:04 MattesGroeger

Ok, I tried again with your latest version 69a0e5d393ae4ca869d4e36035860394c2e6c647 (without any of our changes) on iPhone 4S, iOS 8.4.1 and still get the same behavior. I even have the same behavior when I pause the playback from inside the app by doing the following:

1. Start playback and have the track buffered completely
2. Pause the playback
3. Switch to a different app
4. Wait for the screen to turn off
5. It will start playing again

Here are my state changes (see the timestamps, it's 3 minutes and 47 seconds later):

12:19:46 [Debug] [main] [Player.swift:190] audioPlayer(_:didChangeStateFrom:toState:) > State change – from: Playing to: Paused
12:22:59 [Debug] [main] [Player.swift:190] audioPlayer(_:didChangeStateFrom:toState:) > State change – from: Paused to: Buffering
12:23:01 [Debug] [main] [Player.swift:190] audioPlayer(_:didChangeStateFrom:toState:) > State change – from: Buffering to: Playing

Then I tested on an iPhone 6 Plus, iOS 9.2.1. Here the behavior is a bit different as it doesn't start playback from the lockscreen:

1. Start playback
2. Lock the device
3. Pause the playback
4. Wait, nothing happens
5. Unlock the phone again, playback starts instantly (where it shouldn't)

State changes logged:

12:34:10 [Debug] [main] [Player.swift:190] audioPlayer(_:didChangeStateFrom:toState:) > State change – from: Playing to: Paused
error in __connection_block_invoke_2: Connection interrupted
error in __connection_block_invoke_2: Connection interrupted
12:35:34 [Debug] [main] [Player.swift:190] audioPlayer(_:didChangeStateFrom:toState:) > State change – from: Paused to: Buffering
12:35:35 [Debug] [main] [Player.swift:190] audioPlayer(_:didChangeStateFrom:toState:) > State change – from: Buffering to: Playing

On which devices and iOS versions were you testing?

MattesGroeger avatar Apr 18 '16 10:04 MattesGroeger

Right now, I'm testing on latest iOS version (iOS 9.3) since it's my only test device for now. Also, I'm still not seeing the issue unfortunately but I really appreciate effort you put into reporting it.

Can I ask you what is the value of shouldResumePlaying and stateBeforeBuffering when the player restart, and also, what method makes the player restart playing? This would help a lot in order to understand the issue you are facing.

delannoyk avatar Apr 18 '16 17:04 delannoyk

Yeah, I know it's hard to fix something that one can't reproduce ;)

As I wrote in the original issue:

The playback is triggered because the KVO on currentItem.playbackBufferEmpty is triggered. It then sets the state to buffering and afterwards starts the background task.

The state at line 911 when the lockscreen turns off:

player.currentItem!.playbackBufferEmpty: true
shouldResumePlaying: false
stateBeforeBuffering: nil

Your code then triggers state = .Buffering as reachability.isReachable() is true (line 919) which ultimately leads to playing the track again.

To me it looks like an unusual behaviour of the AVPlayer. Why would the playbackBuffer suddenly be empty? Because the lockscreen turns off?

MattesGroeger avatar Apr 20 '16 15:04 MattesGroeger