Skip to content
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

feat: Audio Only Mode #7647

Merged
merged 17 commits into from
Mar 10, 2022
Merged
8 changes: 8 additions & 0 deletions docs/guides/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
* [width](#width)
* [Video.js-specific Options](#videojs-specific-options)
* [aspectRatio](#aspectratio)
* [audioOnlyMode](#audioonlymode)
* [autoSetup](#autosetup)
* [breakpoints](#breakpoints)
* [children](#children)
Expand Down Expand Up @@ -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.

### `audioOnlyMode`

> Type: `boolean`
> Default: `false`

If set to true, it hides all player components except the control bar, as well as any specific controls that are needed only for video. This option can be set to `true` or `false` by calling `audioOnlyMode([true|false])` at runtime.

### `autoSetup`

> Type: `boolean`
Expand Down
4 changes: 4 additions & 0 deletions src/css/components/_captions.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
.video-js .vjs-captions-button .vjs-icon-placeholder {
@extend .vjs-icon-captions;
}

.video-js.vjs-audio-only-mode .vjs-captions-button {
display: none;
}
10 changes: 6 additions & 4 deletions src/css/components/_control-bar.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@
@include background-color-with-alpha($primary-background-color, $primary-background-transparency);
}

// Video has started playing
.vjs-has-started .vjs-control-bar {
// Video has started playing or we are in audioOnlyMode
.vjs-has-started .vjs-control-bar,
.vjs-audio-only-mode .vjs-control-bar {
@include display-flex;
visibility: visible;
opacity: 1;
Expand Down Expand Up @@ -41,8 +42,9 @@
display: none !important;
}

// Don't hide the control bar if it's audio
.vjs-audio.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar {
// Don't hide the control bar if it's audio or in audioOnlyMode
.vjs-audio.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar,
.vjs-audio-only-mode.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar {
opacity: 1;
visibility: visible;
}
Expand Down
4 changes: 4 additions & 0 deletions src/css/components/_descriptions.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
.video-js .vjs-descriptions-button .vjs-icon-placeholder {
@extend .vjs-icon-audio-description;
}

.video-js.vjs-audio-only-mode .vjs-descriptions-button {
display: none;
}
5 changes: 5 additions & 0 deletions src/css/components/_fullscreen.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
@extend .vjs-icon-fullscreen-enter;
}
}

.video-js.vjs-audio-only-mode .vjs-fullscreen-control {
display: none;
}

// Switch to the exit icon when the player is in fullscreen
.video-js.vjs-fullscreen .vjs-fullscreen-control .vjs-icon-placeholder {
@extend .vjs-icon-fullscreen-exit;
Expand Down
4 changes: 4 additions & 0 deletions src/css/components/_layout.scss
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@
height: 100%;
}

.video-js.vjs-audio-only-mode .vjs-tech {
display: none;
}

// Fullscreen Styles
body.vjs-full-window {
padding: 0;
Expand Down
5 changes: 5 additions & 0 deletions src/css/components/_picture-in-picture.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
@extend .vjs-icon-picture-in-picture-enter;
}
}

.video-js.vjs-audio-only-mode .vjs-picture-in-picture-control {
display: none;
}

// Switch to the exit icon when the player is in Picture-in-Picture
.video-js.vjs-picture-in-picture .vjs-picture-in-picture-control .vjs-icon-placeholder {
@extend .vjs-icon-picture-in-picture-exit;
Expand Down
4 changes: 4 additions & 0 deletions src/css/components/_subs-caps.scss
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,7 @@
font-size: 1.5em;
line-height: inherit;
}

.video-js.vjs-audio-only-mode .vjs-subs-caps-button {
display: none;
}
76 changes: 75 additions & 1 deletion src/js/player.js
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,15 @@ class Player extends Component {
// Init debugEnabled_
this.debugEnabled_ = false;

// Init state audioOnlyMode_
this.audioOnlyMode_ = false;

// Init state audioOnlyCache_
this.audioOnlyCache_ = {
playerHeight: null,
hiddenChildren: []
};

// if the global option object was accidentally blown away by
// someone, bail early with an informative error
if (!this.options_ ||
Expand Down Expand Up @@ -574,6 +583,7 @@ class Player extends Component {

this.breakpoints(this.options_.breakpoints);
this.responsive(this.options_.responsive);
this.audioOnlyMode(this.options_.audioOnlyMode);
}

/**
Expand Down Expand Up @@ -4290,6 +4300,69 @@ class Player extends Component {
return !!this.isAudio_;
}

/**
* Get the current audioOnlyMode state or set audioOnlyMode to true or false.
*
* Setting this to `true` will hide all player components except the control bar,
* as well as control bar components needed only for video.
*
* @param {boolean} [value]
* The value to set audioOnlyMode to.
*
* @return {boolean}
* True if audioOnlyMode is on, false otherwise.
*/
audioOnlyMode(value) {
if (typeof value !== 'boolean' || value === this.audioOnlyMode_) {
return this.audioOnlyMode_;
}

if (value === true) {
alex-barstow marked this conversation as resolved.
Show resolved Hide resolved
// Update styling immediately so we can get the control bar's height
this.addClass('vjs-audio-only-mode');

const playerChildren = this.children();
const controlBar = this.getChild('ControlBar');
const controlBarHeight = controlBar && controlBar.height();
alex-barstow marked this conversation as resolved.
Show resolved Hide resolved

// Hide all player components except the control bar. Control bar components
// needed only for video are hidden with CSS
playerChildren.forEach(child => {
if (child === controlBar) {
return;
}

if (child.el_ && !child.hasClass('vjs-hidden')) {
child.hide();

this.audioOnlyCache_.hiddenChildren.push(child);
}
});

this.audioOnlyCache_.playerHeight = this.height();

// Set the player height the same as the control bar
this.height(controlBarHeight);

// Fullscreen is not supported in audioOnlyMode, so exit if we need to
if (this.isFullscreen()) {
this.exitFullscreen();
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we also exit PiP?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we exit fs/pip before getting the control bar height, in case it's different in fullscreen? At least exitFullscreen should have a promise for knowing when exiting has finished.

} else {
this.removeClass('vjs-audio-only-mode');

// Show player components that were previously hidden
this.audioOnlyCache_.hiddenChildren.forEach(child => child.show());

// Reset player height
this.height(this.audioOnlyCache_.playerHeight);
}

this.audioOnlyMode_ = value;

this.trigger('audioonlymodechange');
}

/**
* A helper method for adding a {@link TextTrack} to our
* {@link TextTrackList}.
Expand Down Expand Up @@ -5096,7 +5169,8 @@ Player.prototype.options_ = {
},

breakpoints: {},
responsive: false
responsive: false,
audioOnlyMode: false
};

[
Expand Down
Loading