diff --git a/src/js/tech/html5.js b/src/js/tech/html5.js
index 969dd62c3..368aa40b6 100644
--- a/src/js/tech/html5.js
+++ b/src/js/tech/html5.js
@@ -428,7 +428,30 @@ class Html5 extends Tech {
* @return {Number}
*/
duration() {
- return this.el_.duration || 0;
+ // Android Chrome will report duration as Infinity for VOD HLS until after
+ // playback has started, which triggers the live display erroneously.
+ // Return NaN if playback has not started and trigger a durationupdate once
+ // the duration can be reliably known.
+ if (this.el_.duration === Infinity &&
+ browser.IS_ANDROID && browser.IS_CHROME) {
+ if (this.el_.currentTime === 0) {
+ // Wait for the first `timeupdate` with currentTime > 0 - there may be
+ // several with 0
+ const checkProgress = () => {
+ if (this.el_.currentTime > 0) {
+ // Trigger durationchange for genuinely live video
+ if (this.el_.duration === Infinity) {
+ this.trigger('durationchange');
+ }
+ this.off(this.player_, 'timeupdate', checkProgress);
+ }
+ };
+
+ this.on(this.player_, 'timeupdate', checkProgress);
+ return NaN;
+ }
+ }
+ return this.el_.duration || NaN;
}
/**
diff --git a/test/unit/tech/html5.test.js b/test/unit/tech/html5.test.js
index 270d879f7..01644205b 100644
--- a/test/unit/tech/html5.test.js
+++ b/test/unit/tech/html5.test.js
@@ -562,3 +562,22 @@ QUnit.test('Exception in play promise should be caught', function() {
tech.el_ = oldEl;
});
+
+test('When Android Chrome reports Infinity duration with currentTime 0, return NaN', function() {
+ const oldIsAndroid = browser.IS_ANDROID;
+ const oldIsChrome = browser.IS_CHROME;
+ const oldEl = tech.el_;
+
+ browser.IS_ANDROID = true;
+ browser.IS_CHROME = true;
+
+ tech.el_ = {
+ duration: Infinity,
+ currentTime: 0
+ };
+ ok(Number.isNaN(tech.duration()), 'returned NaN with currentTime 0');
+
+ browser.IS_ANDROID = oldIsAndroid;
+ browser.IS_CHROME = oldIsChrome;
+ tech.el_ = oldEl;
+});