Closed defagos closed 4 years ago
This is due to changes to background playback behavior introduced with iOS 12.
As tested with devices running iOS 9, 10 and 12:
With iOS 12, Apple introduced changes to background playback, some of them previously lead to issues on our side (see #66). By default, the behavior is now:
To compensate for this new video background behavior, a new preventsDisplaySleepDuringVideoPlayback
property has been added. This new abilities were probably introduced for experiences where video playback is not a highly interactive experience (e.g. autoplay in a news timeline, animated background for a login screen, etc.).
Our SRG Media Player controller should better manage this property so that video playback (either without attached layer or in background) never prevents the device from locking, as for audio.
We should have SRG Media Player automatically manage it so that, in cases where this does not
We must be especially careful to have a good behavior for the following use cases:
preventsDisplaySleepDuringVideoPlayback
is set to NO
, then the screen will lock itself automatically when using PiP on the dashboard, which is never what we want.We must therefore use the value provided by the user in the player configuration block, and possibly override it in the above use cases so that the behavior is the best possible one.
A fix proposal has been made on the feature/screen-lock-fix
branch. I tested it quite extensively but, since there is no way to unit test this behavior, further manual tests will probably be helpful.
I tested this fix in our Play app and... well, it does not work there. Device lock is not prevented, but playback sometimes pauses when going to background, even if the video layer has been detached.
I have an idea why this might happen, I'll investigate a fix for the fix.
Testing is a bit cumbersome and can only be manual. The device must also be detached from any debugger, which otherwise prevents the device from sleeping. It is best to kill and restart the app, this behavior could even persist when detaching the cable during my tests.
The main idea can be summarised as follows: If a view is attached to the player and installed in the view hierarchy, and if preventsDisplaySleepDuringVideoPlayback
is set to YES
, the device is prevented from sleeping while the media is playing. In all other cases the device can enter sleep mode.
I updated the inline demo so that playing with all kinds of different setups is easy. Just build the demo, end the debugging session and check that the following expected behaviours are fulfilled when playing a video. You should set device sleep duration to a minimum (30 seconds on an iPhone, 2 minutes on iPad):
View attached to the player | Video prevents sleep | Device prevented from sleeping? |
---|---|---|
Yes | Yes | Yes, but only when the video is playing |
Yes | No | No |
No | Yes | No |
No | No | No |
The device is always prevented from sleeping when video is playing, whether the player is bound to an installed view or not.
Fixed on the feature/background-behavior-fixes
branch. The results above have been verified in SRG Media Player, as well as in all of our SRG Media Player based products, following the same approach.
We still had an issue in our Play app nightlies. In some cases (yet to be determined), the screen could sleep even with a playing video visible.
I have an example of a use case where the behavior is incorrect in Play SRG
This would naively translate to the following use case for SRG Media Player inline demo:
In Media Player demo, though, this seems to work.
Also experienced with the following use case:
Also experienced with the following use case:
With the exact same procedure, but without waiting more than the device delay, this works correclty!
We don’t do anything different whether the device is locked by the user or whether the sleep delay is reached. Is there some undocumented behavior we don’t know of?
I confirm this is related to the fact that the device entered sleep mode on its own once. The following does not work either:
With the exact same procedure, but without waiting more than the device delay, this works correclty!
We don’t do anything different whether the device is locked by the user or whether the sleep delay is reached. Is there some undocumented behavior we don’t know of?
There is also a slight audio interruption when attaching or detaching the layer in the inline demo. This problem didn't exist before.
In understood what is going wrong: The -reloadPlayerConfiguration
persists the current value forever if it occurs while the values is overridden. Once set to NO
, it keeps this value forever (unless of course the configuration is reset).
The reason this appears in Letterbox is because Letterbox calls -reloadPlayerConfiguration
, whereas the inline SRG Media Player demo doesn't.
The current SRG Media Player implementation is therefore incorrect and must be fixed. I might already have a proposal but I need to test it thoroughly first.
Thank you for resuming all those test cases. To not forget, I repeat that I found too:
The device is always prevented from sleeping when video is playing, whether the player is bound to an installed view or not.
One case still have an issue: SRGMediaPlayViewController
+ Picture in Picture on iOS 12+.
SRG Media Player
player on an iPad.From reloadPlayerConfiguration:
if (self.pictureInPictureController.pictureInPictureActive)
is always NO
.if (! self.view.player || ! self.view.window)
is YES
, then self.player.preventsDisplaySleepDuringVideoPlayback = NO;
.Also:
mediaPlayerView:didMoveToWindow:
delegate method from SRGMediaPlayerViewDelegate
is never called.The correct behaviour founded with System
and Advanced Custom
players.
To fix the SRGMediaPlayerViewController
issue, I propose we simply disable overrides in this case. We do not control the picture in picture controller in this case, so we cannot rely on it.
Applications which want a custom behavior in this case (highly unlikely) can still implement the mechanism they need with playerConfigurationBlock
and AVPlayerViewControllerDelegate
.
Starting with iOS 12, video playback (even in background) prevents the device from locking by default. This should be avoided.
See https://github.com/SRGSSR/playsrg-ios/issues/139.