-
Notifications
You must be signed in to change notification settings - Fork 6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Tune time bar update based on duration #5496
Conversation
mediaTimeUpdatePeriodMs is the number of media time seconds needed until one real time second passed (that's our designated update interval). For example for playback speed 0.5, this is 500ms. I agree that is is very complicated and took me a while to figure out what's going on here. Feel free to simplify this with your change, but keep in mind different playback speeds when doing this. The duration of live windows is either C.TIME_UNSET in which case we don't display a progress at all (because we don't anything about it), or it's the duration of the current live window and will change from time to time. For this purpose it's fine to assume that the live duration works the same as a VOD duration and you can also assume the duration itself won't change (even if the live window moves). |
…y before the next update
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
General approach looks good, thanks! I've added some suggestions to the code for further improvements. Please take a look.
@@ -219,6 +219,8 @@ | |||
private @Nullable long[] adGroupTimesMs; | |||
private @Nullable boolean[] playedAdGroups; | |||
|
|||
private int densityDpi; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you make that final and move up to the other final variables?
* | ||
* @return Width of time bar in dps | ||
*/ | ||
int getTimeBarWidth(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add dp to the name, i.e. getTimeBarWidthDp?
@@ -835,4 +843,8 @@ public static int getDefaultPlayedAdMarkerColor(int adMarkerColor) { | |||
private static int dpToPx(DisplayMetrics displayMetrics, int dps) { | |||
return (int) (dps * displayMetrics.density + 0.5f); | |||
} | |||
|
|||
private static int pxToDp(int densityDpi, int px) { | |||
return (int) (px / ((float) densityDpi / DisplayMetrics.DENSITY_DEFAULT)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't (float) densityDpi / DisplayMetrics.DENSITY_DEFAULT the same as displayMetrics.density? See method dpToPx avove. If so, it's probably better to use the same conversion such that both methods obviously do the same thing, just the other way round.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it's the same, I can use that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But I can't pass the DisplayMetrics instead of density, because the width of the view can't be obtained yet in the ctr.
@@ -196,6 +197,9 @@ | |||
public static final int MAX_WINDOWS_FOR_MULTI_WINDOW_TIME_BAR = 100; | |||
|
|||
private static final long MAX_POSITION_FOR_SEEK_TO_PREVIOUS = 3000; | |||
private static final int DEFAULT_UPDATE_DP = 5; | |||
private static final long MIN_UPDATE_FREQUENCY_MS = 50; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems we already use a minimum delay of 200ms for the cases where the playback speed is > 5.0f. Can you change that accordingly, and also use the same constants in updateProgress()?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if I understood correctly. Should I change MIN_UPDATE_FREQUENCY_MS to 200ms? The other half is done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thinking about it again, 50ms might actually be a better minimum value. :)
After your change. we'll only use such low values for very short video durations and given that the human eye can easily see 20 updates per second, this seems like a good value to get smooth movements.
@@ -196,6 +197,9 @@ | |||
public static final int MAX_WINDOWS_FOR_MULTI_WINDOW_TIME_BAR = 100; | |||
|
|||
private static final long MAX_POSITION_FOR_SEEK_TO_PREVIOUS = 3000; | |||
private static final int DEFAULT_UPDATE_DP = 5; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just curious: How did you choose this value?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By checking a couple of values, how it looks visually. 20dp was too high and the progress jumped way too much. In my opinion of course.
// Calculate the designated update interval, taking duration into consideration as well | ||
long mediaTimeUpdatePeriodMs = duration / numberOfUpdates; | ||
|
||
// Limit the designated update interval, to avoid too frequent / infrequent updates |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that should happen at the very end after taking playback speed into account. Otherwise the playback speed may still scale the delay to very large or small values.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Be aware though, that the duration can be 0 (e.g. for live streams with unset duration).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same is probably true for the timeBarWidth? Could be 0 if the view is embedded in a strange way where the the timebar isn't really visible anymore.
@@ -835,13 +839,33 @@ private void updateProgress() { | |||
if (playbackSpeed <= 0.1f) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These test for speed <0.1 and speed > 5.0 where specifically chosen because all speed values between 0.1 and 5.0 would result in a delay between 200ms and 1000ms anyway.
As you now limit to the delay in another way and based on other criteria, I think you should be able to just remove these extra tests and let all cases go through the central code.
Done, let me know if any further changes are needed :) |
@@ -196,6 +197,9 @@ | |||
public static final int MAX_WINDOWS_FOR_MULTI_WINDOW_TIME_BAR = 100; | |||
|
|||
private static final long MAX_POSITION_FOR_SEEK_TO_PREVIOUS = 3000; | |||
private static final int DEFAULT_UPDATE_DP = 5; | |||
private static final long MIN_UPDATE_FREQUENCY_MS = 50; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thinking about it again, 50ms might actually be a better minimum value. :)
After your change. we'll only use such low values for very short video durations and given that the human eye can easily see 20 updates per second, this seems like a good value to get smooth movements.
int numberOfUpdates = timeBarWidth / DEFAULT_UPDATE_DP; | ||
|
||
// Calculate the designated update interval, taking duration into consideration as well | ||
long mediaTimeUpdatePeriodMs = duration / numberOfUpdates; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for being nitty about this, but this can still result in divisions by zero. For example if timeBarWidth==3. The same is true for the other two divisions on line 852 and 861.
Maybe the easiest solution is to move this code to a separate private static method getTimeBarUpdateDelayMs. Then you do the steps and return early if an intermediate value is outside the valid range. This avoids a lot of nested if conditions. Something like:
int numberOfUpdate = ...
if (numberOfUpdates <= 0) {
return MAX_UPDATE_FREQUENCY_MS;
}
etc.
[ We usually put static methods below non-static ones, so please move that new method down to the other static methods. Thanks. ]
Moved the calculations to a separate method, and added some verifications. Let me know if it's OK or something else needs to be adjusted. |
Thanks! Looks good now. I'll merge this change next week. |
Going to merge this PR soon. Note that we did some updates to your PR:
|
Alright, sounds good! |
Hi @tonihei , @ojw28
I've started to implement the thing what we've discussed on #5040.
Two things are unclear where I would need some guidance:
duration
works in that cases?