mirror of
https://github.com/videojs/video.js.git
synced 2025-01-17 10:46:00 +02:00
@forbesjo add an audio track selector menu button. closes #3223
This commit is contained in:
parent
249532ad45
commit
4156307792
@ -9,6 +9,7 @@ CHANGELOG
|
||||
* @BrandonOCasey added audio and video track support ([view](https://github.com/videojs/video.js/pull/3173))
|
||||
* @OwenEdwards added language attribute in HTML files for accessibility ([view](https://github.com/videojs/video.js/pull/3257))
|
||||
* @incompl clear currentSource_ after subsequent loadstarts ([view](https://github.com/videojs/video.js/pull/3285))
|
||||
* @forbesjo add an audio track selector menu button ([view](https://github.com/videojs/video.js/pull/3223))
|
||||
|
||||
--------------------
|
||||
|
||||
|
3
src/css/components/_audio.scss
Normal file
3
src/css/components/_audio.scss
Normal file
@ -0,0 +1,3 @@
|
||||
.video-js .vjs-audio-button {
|
||||
@extend .vjs-icon-audio;
|
||||
}
|
@ -35,6 +35,7 @@
|
||||
@import "components/chapters";
|
||||
@import "components/descriptions";
|
||||
@import "components/subtitles";
|
||||
@import "components/audio";
|
||||
@import "components/adaptive";
|
||||
@import "components/captions-settings";
|
||||
@import "components/modal-dialog";
|
||||
|
@ -0,0 +1,64 @@
|
||||
/**
|
||||
* @file audio-track-button.js
|
||||
*/
|
||||
import TrackButton from '../track-button.js';
|
||||
import Component from '../../component.js';
|
||||
import * as Fn from '../../utils/fn.js';
|
||||
import AudioTrackMenuItem from './audio-track-menu-item.js';
|
||||
|
||||
/**
|
||||
* The base class for buttons that toggle specific text track types (e.g. subtitles)
|
||||
*
|
||||
* @param {Player|Object} player
|
||||
* @param {Object=} options
|
||||
* @extends TrackButton
|
||||
* @class AudioTrackButton
|
||||
*/
|
||||
class AudioTrackButton extends TrackButton {
|
||||
constructor(player, options = {}) {
|
||||
options.tracks = player.audioTracks && player.audioTracks();
|
||||
|
||||
super(player, options);
|
||||
|
||||
this.el_.setAttribute('aria-label', 'Audio Menu');
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow sub components to stack CSS class names
|
||||
*
|
||||
* @return {String} The constructed class name
|
||||
* @method buildCSSClass
|
||||
*/
|
||||
buildCSSClass() {
|
||||
return `vjs-audio-button ${super.buildCSSClass()}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a menu item for each audio track
|
||||
*
|
||||
* @return {Array} Array of menu items
|
||||
* @method createItems
|
||||
*/
|
||||
createItems(items = []) {
|
||||
let tracks = this.player_.audioTracks && this.player_.audioTracks();
|
||||
|
||||
if (!tracks) {
|
||||
return items;
|
||||
}
|
||||
|
||||
for (let i = 0; i < tracks.length; i++) {
|
||||
let track = tracks[i];
|
||||
|
||||
items.push(new AudioTrackMenuItem(this.player_, {
|
||||
// MenuItem is selectable
|
||||
'selectable': true,
|
||||
'track': track
|
||||
}));
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
}
|
||||
|
||||
Component.registerComponent('AudioTrackButton', AudioTrackButton);
|
||||
export default AudioTrackButton;
|
@ -0,0 +1,71 @@
|
||||
/**
|
||||
* @file audio-track-menu-item.js
|
||||
*/
|
||||
import MenuItem from '../../menu/menu-item.js';
|
||||
import Component from '../../component.js';
|
||||
import * as Fn from '../../utils/fn.js';
|
||||
|
||||
/**
|
||||
* The audio track menu item
|
||||
*
|
||||
* @param {Player|Object} player
|
||||
* @param {Object=} options
|
||||
* @extends MenuItem
|
||||
* @class AudioTrackMenuItem
|
||||
*/
|
||||
class AudioTrackMenuItem extends MenuItem {
|
||||
constructor(player, options) {
|
||||
let track = options.track;
|
||||
let tracks = player.audioTracks();
|
||||
|
||||
// Modify options for parent MenuItem class's init.
|
||||
options.label = track.label || track.language || 'Unknown';
|
||||
options.selected = track.enabled;
|
||||
|
||||
super(player, options);
|
||||
|
||||
this.track = track;
|
||||
|
||||
if (tracks) {
|
||||
let changeHandler = Fn.bind(this, this.handleTracksChange);
|
||||
|
||||
tracks.addEventListener('change', changeHandler);
|
||||
this.on('dispose', () => {
|
||||
tracks.removeEventListener('change', changeHandler);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle click on audio track
|
||||
*
|
||||
* @method handleClick
|
||||
*/
|
||||
handleClick(event) {
|
||||
let tracks = this.player_.audioTracks();
|
||||
|
||||
super.handleClick(event);
|
||||
|
||||
if (!tracks) return;
|
||||
|
||||
for (let i = 0; i < tracks.length; i++) {
|
||||
let track = tracks[i];
|
||||
|
||||
if (track === this.track) {
|
||||
track.enabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle audio track change
|
||||
*
|
||||
* @method handleTracksChange
|
||||
*/
|
||||
handleTracksChange(event) {
|
||||
this.selected(this.track.enabled);
|
||||
}
|
||||
}
|
||||
|
||||
Component.registerComponent('AudioTrackMenuItem', AudioTrackMenuItem);
|
||||
export default AudioTrackMenuItem;
|
@ -19,6 +19,7 @@ import ChaptersButton from './text-track-controls/chapters-button.js';
|
||||
import DescriptionsButton from './text-track-controls/descriptions-button.js';
|
||||
import SubtitlesButton from './text-track-controls/subtitles-button.js';
|
||||
import CaptionsButton from './text-track-controls/captions-button.js';
|
||||
import AudioTrackButton from './audio-track-controls/audio-track-button.js';
|
||||
import PlaybackRateMenuButton from './playback-rate-menu/playback-rate-menu-button.js';
|
||||
import CustomControlSpacer from './spacer-controls/custom-control-spacer.js';
|
||||
|
||||
@ -63,6 +64,7 @@ ControlBar.prototype.options_ = {
|
||||
'descriptionsButton',
|
||||
'subtitlesButton',
|
||||
'captionsButton',
|
||||
'audioTrackButton',
|
||||
'fullscreenToggle'
|
||||
]
|
||||
};
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @file text-track-button.js
|
||||
*/
|
||||
import MenuButton from '../../menu/menu-button.js';
|
||||
import TrackButton from '../track-button.js';
|
||||
import Component from '../../component.js';
|
||||
import * as Fn from '../../utils/fn.js';
|
||||
import TextTrackMenuItem from './text-track-menu-item.js';
|
||||
@ -15,32 +15,20 @@ import OffTextTrackMenuItem from './off-text-track-menu-item.js';
|
||||
* @extends MenuButton
|
||||
* @class TextTrackButton
|
||||
*/
|
||||
class TextTrackButton extends MenuButton {
|
||||
class TextTrackButton extends TrackButton {
|
||||
|
||||
constructor(player, options = {}){
|
||||
options.tracks = player.textTracks();
|
||||
|
||||
constructor(player, options){
|
||||
super(player, options);
|
||||
|
||||
let tracks = this.player_.textTracks();
|
||||
|
||||
if (this.items.length <= 1) {
|
||||
this.hide();
|
||||
}
|
||||
|
||||
if (!tracks) {
|
||||
return;
|
||||
}
|
||||
|
||||
let updateHandler = Fn.bind(this, this.update);
|
||||
tracks.addEventListener('removetrack', updateHandler);
|
||||
tracks.addEventListener('addtrack', updateHandler);
|
||||
|
||||
this.player_.on('dispose', function() {
|
||||
tracks.removeEventListener('removetrack', updateHandler);
|
||||
tracks.removeEventListener('addtrack', updateHandler);
|
||||
});
|
||||
}
|
||||
|
||||
// Create a menu item for each text track
|
||||
/**
|
||||
* Create a menu item for each text track
|
||||
*
|
||||
* @return {Array} Array of menu items
|
||||
* @method createItems
|
||||
*/
|
||||
createItems(items=[]) {
|
||||
// Add an OFF menu item to turn all tracks off
|
||||
items.push(new OffTextTrackMenuItem(this.player_, { 'kind': this.kind_ }));
|
||||
|
44
src/js/control-bar/track-button.js
Normal file
44
src/js/control-bar/track-button.js
Normal file
@ -0,0 +1,44 @@
|
||||
/**
|
||||
* @file track-button.js
|
||||
*/
|
||||
import MenuButton from '../menu/menu-button.js';
|
||||
import Component from '../component.js';
|
||||
import * as Fn from '../utils/fn.js';
|
||||
|
||||
/**
|
||||
* The base class for buttons that toggle specific text track types (e.g. subtitles)
|
||||
*
|
||||
* @param {Player|Object} player
|
||||
* @param {Object=} options
|
||||
* @extends MenuButton
|
||||
* @class TrackButton
|
||||
*/
|
||||
class TrackButton extends MenuButton {
|
||||
|
||||
constructor(player, options){
|
||||
let tracks = options.tracks;
|
||||
|
||||
super(player, options);
|
||||
|
||||
if (this.items.length <= 1) {
|
||||
this.hide();
|
||||
}
|
||||
|
||||
if (!tracks) {
|
||||
return;
|
||||
}
|
||||
|
||||
let updateHandler = Fn.bind(this, this.update);
|
||||
tracks.addEventListener('removetrack', updateHandler);
|
||||
tracks.addEventListener('addtrack', updateHandler);
|
||||
|
||||
this.player_.on('dispose', function() {
|
||||
tracks.removeEventListener('removetrack', updateHandler);
|
||||
tracks.removeEventListener('addtrack', updateHandler);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Component.registerComponent('TrackButton', TrackButton);
|
||||
export default TrackButton;
|
Loading…
Reference in New Issue
Block a user