Skip to content

Commit 661962c

Browse files
authored
fix(player): Ensure fluid works when dimensions not initially known (#7023)
The video dimensions aren't necessarily known at loadedmetadata particularly with native playback on iOS. In fluid mode, the player defaults to 16:9 and does not update once the dimensions are known. - Updates player styles on resize events. - Fixes arguments passed to addEventedCallback so the callbacks are executed. Fixes #6939
1 parent a000fed commit 661962c

File tree

2 files changed

+43
-4
lines changed

2 files changed

+43
-4
lines changed

src/js/player.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,7 @@ class Player extends Component {
473473
}
474474

475475
if (this.fluid_) {
476-
this.on('playerreset', this.updateStyleEl_);
476+
this.on(['playerreset', 'resize'], this.updateStyleEl_);
477477
}
478478
// We also want to pass the original player options to each component and plugin
479479
// as well so they don't need to reach back into the player for options later.
@@ -912,13 +912,13 @@ class Player extends Component {
912912
this.fluid_ = !!bool;
913913

914914
if (isEvented(this)) {
915-
this.off('playerreset', this.updateStyleEl_);
915+
this.off(['playerreset', 'resize'], this.updateStyleEl_);
916916
}
917917
if (bool) {
918918
this.addClass('vjs-fluid');
919919
this.fill(false);
920-
addEventedCallback(function() {
921-
this.on('playerreset', this.updateStyleEl_);
920+
addEventedCallback(this, () => {
921+
this.on(['playerreset', 'resize'], this.updateStyleEl_);
922922
});
923923
} else {
924924
this.removeClass('vjs-fluid');

test/unit/player.test.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,45 @@ QUnit.test('should default to 16:9 when fluid', function(assert) {
480480
player.dispose();
481481
});
482482

483+
QUnit.test('should resize fluid player on resize', function(assert) {
484+
const player = TestHelpers.makePlayer({fluid: true});
485+
let ratio = player.currentHeight() / player.currentWidth();
486+
487+
// account for some rounding of 0.5625 up to 0.563
488+
assert.ok(((ratio >= 0.562) && (ratio <= 0.563)), 'fluid player without dimensions defaults to 16:9');
489+
490+
player.tech_.videoWidth = () => 100;
491+
player.tech_.videoHeight = () => 50;
492+
493+
player.trigger('resize');
494+
495+
this.clock.tick(1);
496+
497+
ratio = player.currentHeight() / player.currentWidth();
498+
499+
assert.ok(ratio === 0.5, 'player aspect ratio changed on resize event');
500+
501+
player.dispose();
502+
});
503+
504+
QUnit.test('should resize fluid player on resize if fluid enabled post initialisation', function(assert) {
505+
const player = TestHelpers.makePlayer({fluid: false});
506+
507+
player.tech_.videoWidth = () => 100;
508+
player.tech_.videoHeight = () => 30;
509+
510+
player.fluid(true);
511+
player.trigger('resize');
512+
513+
this.clock.tick(1);
514+
515+
const ratio = player.currentHeight() / player.currentWidth();
516+
517+
assert.ok(ratio === 0.3, 'player aspect ratio changed on resize event');
518+
519+
player.dispose();
520+
});
521+
483522
QUnit.test('should set fluid to true if element has vjs-fluid class', function(assert) {
484523
const tag = TestHelpers.makeTag();
485524

0 commit comments

Comments
 (0)