Closed defagos closed 4 years ago
In 3.0.0 we are using basically two kinds of timers:
AVPlayer
periodic time observers, which fire when the player is actually playing, when time jumps occur and when playback stops.NSTimer
for other refresh needs, most notably when playback is paused.We also have a periodic time observer concept, similar to the one of AVPlayer
, but ensuring that updates also occur when playback is paused. Those were essentially meant for correct UI refreshes when playing DVR streams.
Looking into timers a bit more, this situation is sub-optimal:
AVPlayer
time observers should be used for light time-related periodic updates, as this is their true purpose.To improve the situation, I propose the following internal changes:
AVPlayer
standard periodic time observers. In addition to time discontinuities, supported natively and generating additional events in addition to the periodic ones, we also generate events for time range discontinuities. For on-demand streams those will occur mostly when playback starts, while for livestreams they will be generated as chunks are retrieved.NSTimer
are used for processes not directly bound to playback. We introduce the recommended tolerance of 10% so that the system can package several timer events together to reduce energy impact.A good thing is that NSTimer
s are automatically suspended by the system when the app is sent to the background. For media playback apps, having background audio enabled, they will continue to fire in background if content is being played, which is similar to what periodic time observers do (they are themselves internally implemented with GCD dispatch sources).
Contrary to what I initially thought, this does not require us to implement a special kind of timer to support the kind of behavior we need:
NSTimer
.In any case, if nothing is being played and the application is sent to the background, timers will not be fired.
To measure the result of above measures, the energy protocol we thought of should be applied for all players in the demo:
The protocol should be repeated in the following cases:
AOD, 60 minutes, playback in foreground.
AOD, 60 minutes, playback paused in foreground.
AOD, 60 minutes, playback in background.
AOD, 60 minutes, playback paused in background.
Livestream, 60 minutes, playback in foreground.
Livestream, 60 minutes, playback paused in foreground.
Livestream, 60 minutes, playback in background.
Livestream, 60 minutes, playback paused in background.
By comparing the values we get for we can evaluate the efficiency of our implementation against the standard Apple experience.
It is important to check livestreams and on-demand streams separately, as the refresh needs are different. Checking with Instruments time profiler tool, this is true for the system player as well, which exhibits extra refresh activity for livestreams, probably due to time range changes.
It would probably be interesting to deliver a visual representation of the above cases, reduced to 1 minute, as delivered by Instruments with its time and energy profiler tools (including results of 2.0.0 for comparison purposes).
Here are a few activity traces, captured for a minute in the above cases. Only for audio (video would be the same, though with more activity).
I compared the native AVPlayerViewController
with the AdvancedPlayerViewController
demo, which uses all views provided by our library. Background corresponds bot to the app being sent to the background or the device being locked. The advanced player is compared with the latest release (3.0) and the one updated for energy efficiency.
Note that the native AVPlayerViewController
provides basic control center integration, which can lead to additional CPU time being used (but this should not be reasonable, as they probably let the system calculate the position).
Test setup:
The complete Instrument traces can be downloaded here for further analysis.
After looking at Instrument time profiling statistics, I suspected we could gain some more battery life by replacing the NSDateComponentsFormatter
s we use, and by having accessibility labels being returns as readonly properties somehow (i.e. only when an item gets the focus).
After having checked with a simple formatter implementation costing far less more according to Instruments, I didn't experience better mAh consumed in comparison to the current implementation. I therefore recommend we stick with the current system formatters.
Both the system and the advanced player use ~120 mAh on my test iPhone 7 for 1 hour of AOD playback in foreground (screen always on, min brightness). The measures were repeated 3 times to eliminate any discrepancy.
Version 3.0.0 introduced KVO for more controller properties, reducing the need for periodic time observation during playback.
Further improvements In the way timers are managed can be made. This should further reduce the rate of update and thus improve player energy efficiency.