-
Notifications
You must be signed in to change notification settings - Fork 7.5k
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
Audio button #3223
Audio button #3223
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
.video-js .vjs-audio-button { | ||
@extend .vjs-icon-audio; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why check that it exists? It should always be present. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you made a mock player to use with custom controls, this would fail, so, I guess we should keep it around for now, maybe remove it in a major bump. |
||
|
||
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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This object literal could be simplified to: {
track,
selectable: true
} There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To elaborate, I feel like we should start writing code that will pass the video.js linter even if the project at large won't pass it. |
||
})); | ||
} | ||
|
||
return items; | ||
} | ||
} | ||
|
||
Component.registerComponent('AudioTrackButton', AudioTrackButton); | ||
export default AudioTrackButton; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Or if the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not following, AudioTrackButton passes There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's because I am apparently illiterate. I mis-read |
||
|
||
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; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this used anywhere?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, it is, in the TrackButton, missed it.