From 64e55f5492237b170dc3f88b27be5c307ae3a62b Mon Sep 17 00:00:00 2001 From: Harisha Rajam Swaminathan <35213866+harisha-swaminathan@users.noreply.github.com> Date: Tue, 1 Mar 2022 15:50:46 -0500 Subject: [PATCH] feat: Add audioPosterMode option (#7629) --- docs/guides/options.md | 8 ++++++++ src/css/components/_poster.scss | 15 ++++++--------- src/js/player.js | 34 ++++++++++++++++++++++++++++++++- test/unit/player.test.js | 33 ++++++++++++++++++++++++++++++++ 4 files changed, 80 insertions(+), 10 deletions(-) diff --git a/docs/guides/options.md b/docs/guides/options.md index 3ebf4eead7..3e27db329b 100644 --- a/docs/guides/options.md +++ b/docs/guides/options.md @@ -21,6 +21,7 @@ * [width](#width) * [Video.js-specific Options](#videojs-specific-options) * [aspectRatio](#aspectratio) + * [audioPosterMode](#audiopostermode) * [autoSetup](#autosetup) * [breakpoints](#breakpoints) * [children](#children) @@ -181,6 +182,13 @@ Puts the player in [fluid](#fluid) mode and the value is used when calculating t Alternatively, the classes `vjs-16-9`, `vjs-9-16`, `vjs-4-3` or `vjs-1-1` can be added to the player. +### `audioPosterMode` + +> Type: `boolean` +> Default: `false` + +If set to true, it enables the poster viewer experience by hiding the video element and displaying the poster image persistently. This option can be set to `true` or `false` by calling `audioPosterMode([true|false])` at runtime. + ### `autoSetup` > Type: `boolean` diff --git a/src/css/components/_poster.scss b/src/css/components/_poster.scss index 31ec5a8466..a0d3fe9611 100644 --- a/src/css/components/_poster.scss +++ b/src/css/components/_poster.scss @@ -16,17 +16,14 @@ height: 100%; } -// Hide the poster after the video has started playing -.vjs-has-started .vjs-poster { +// Hide the poster after the video has started playing and when native controls are used +.vjs-has-started .vjs-poster, +.vjs-using-native-controls .vjs-poster { display: none; } -// Don't hide the poster if we're playing audio -.vjs-audio.vjs-has-started .vjs-poster { +// Don't hide the poster if we're playing audio or when audio-poster-mode is true +.vjs-audio.vjs-has-started .vjs-poster, +.vjs-has-started.vjs-audio-poster-mode .vjs-poster { display: block; } - -// Hide the poster when native controls are used otherwise it covers them -.vjs-using-native-controls .vjs-poster { - display: none; -} diff --git a/src/js/player.js b/src/js/player.js index ba2d1d0d5b..bdefc4848b 100644 --- a/src/js/player.js +++ b/src/js/player.js @@ -4293,6 +4293,37 @@ class Player extends Component { return !!this.isAudio_; } + /** + * Get the current audioPosterMode state or set audioPosterMode to true or false + * + * @param {boolean} [value] + * The value to set audioPosterMode to. + * + * @return {boolean} + * True if audioPosterMode is on, false otherwise. + */ + audioPosterMode(value) { + + if (this.audioPosterMode_ === undefined) { + this.audioPosterMode_ = this.options_.audioPosterMode; + } + + if (typeof value !== 'boolean' || value === this.audioPosterMode_) { + return this.audioPosterMode_; + } + + this.audioPosterMode_ = value; + + if (this.audioPosterMode_) { + this.tech_.hide(); + this.addClass('vjs-audio-poster-mode'); + return; + } + // Show the video element and hide the poster image if audioPosterMode is set to false + this.tech_.show(); + this.removeClass('vjs-audio-poster-mode'); + } + /** * A helper method for adding a {@link TextTrack} to our * {@link TextTrackList}. @@ -5099,7 +5130,8 @@ Player.prototype.options_ = { }, breakpoints: {}, - responsive: false + responsive: false, + audioPosterMode: false }; [ diff --git a/test/unit/player.test.js b/test/unit/player.test.js index fd5a120da4..851ce56570 100644 --- a/test/unit/player.test.js +++ b/test/unit/player.test.js @@ -1570,6 +1570,39 @@ QUnit.test('should add an audio player region if an audio el is used', function( player.dispose(); }); +QUnit.test('default audioPosterMode value at player creation', function(assert) { + const player = TestHelpers.makePlayer({}); + + assert.ok(player.audioPosterMode() === false, 'audioPosterMode is false by default'); + + const player2 = TestHelpers.makePlayer({ + audioPosterMode: true + }); + + assert.ok(player2.audioPosterMode() === true, 'audioPosterMode can be set to true when the player is created'); + player.dispose(); + player2.dispose(); +}); + +QUnit.test('get and set audioPosterMode value', function(assert) { + const player = TestHelpers.makePlayer({}); + + player.audioPosterMode(true); + assert.ok(player.audioPosterMode() === true, 'audioPosterMode is set to true'); +}); + +QUnit.test('vjs-audio-poster-mode class and video element visibility when audioPosterMode is true', function(assert) { + const player = TestHelpers.makePlayer({}); + + player.audioPosterMode(true); + assert.ok(player.el().className.indexOf('vjs-audio-poster-mode') !== -1, 'vjs-audio-poster-mode class is present'); + assert.ok(player.tech_.el().className.indexOf('vjs-hidden') !== -1, 'video element is hidden'); + + player.audioPosterMode(false); + assert.ok(player.el().className.indexOf('vjs-audio-poster-mode') === -1, 'vjs-audio-poster-mode class is removed'); + assert.ok(player.tech_.el().className.indexOf('vjs-hidden') === -1, 'video element is visible'); +}); + QUnit.test('should setScrubbing when seeking or not seeking', function(assert) { const player = TestHelpers.makePlayer(); let isScrubbing;