-
Notifications
You must be signed in to change notification settings - Fork 116
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
Subtitles #117
Subtitles #117
Conversation
src/lib/viewers/media/DashViewer.js
Outdated
*/ | ||
handleSubtitle() { | ||
const subtitleIdx = parseInt(cache.get('media-subtitles'), 10); | ||
if (subtitleIdx >= 0 && subtitleIdx < this.textTracks.length) { |
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.
nit: could just check for if (this.textTracts[subtitileIdx]) {
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.
done
@@ -279,9 +300,21 @@ class DashViewer extends VideoBaseViewer { | |||
addEventListenersForMediaControls() { | |||
super.addEventListenersForMediaControls(); | |||
this.mediaControls.addListener('qualitychange', this.handleQuality); | |||
this.mediaControls.addListener('subtitlechange', this.handleSubtitle); |
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.
This needs to be removed like qualitychange is. You could also just call removeAllListeners in the destroy method. https://nodejs.org/api/events.html#events_emitter_removealllisteners_eventname
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.
Thanks. Removing subtitlechange event in destroy. Can follow up with another commit later to refactor things to call removeAllListeners, since that seems generally better practice.
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.
What's your thinking on removeAllListeners
vs removeListener
? Typically I like explicitly removing only what I add since that lowers the probability you're stomping through some other listener.
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.
but if it's in a function like destroy(), is there still a risk?
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.
Probably not.
src/lib/viewers/media/DashViewer.js
Outdated
* @return {void} | ||
*/ | ||
loadSubtitles() { | ||
this.textTracks = this.player.getTextTracks().sort((track1, track2) => { return track1.id - track2.id; }); |
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.
nit: if you omit the '{}' for the function body in a one-liner like this there is an implicit return.
this.player.getTextTracks().sort((track1, track2) => track1.id - track2.id);
looks a little cleaner.
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.
cool. Done.
src/lib/viewers/media/DashViewer.js
Outdated
loadSubtitles() { | ||
this.textTracks = this.player.getTextTracks().sort((track1, track2) => { return track1.id - track2.id; }); | ||
if (this.textTracks.length > 0) { | ||
this.mediaControls.initSubtitles(this.textTracks.map((track) => { return track.language; })); |
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.
Same here, can remove the {}
and return
if you'd like.
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.
Done
@@ -35,6 +35,10 @@ | |||
<label class="bp-media-controls-label bp-media-controls-timecode">00:00</label> | |||
<span class="bp-media-controls-label"> / </span> | |||
<label class="bp-media-controls-label bp-media-controls-duration">00:00</label> | |||
<button class="bp-media-controls-btn bp-media-cc-icon"> | |||
<span class="bp-media-controls-cc-text">CC</span> |
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.
nit: rename this to "bp-media-cc-icon-text" to match with the 'icon-on' and parent button?
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.
Done
*/ | ||
toggleSubtitles() { | ||
this.show(); | ||
this.emit('togglesubtitles'); |
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.
nit: I've had trouble following this myself but I believe our convention is to emit absolutely last in a function. Here it wouldn't really make a difference but if we ran some time intensive code after it could cause issues.
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.
Makes sense, good catch. Done.
src/lib/viewers/media/Settings.js
Outdated
this.settingsEl.style.width = `${menu.offsetWidth + 18}px`; | ||
// height = n * $item-height + 2 * $padding (see Settings.scss) | ||
// where n is the number of displayed items in the menu | ||
const sumHeight = [].reduce.call(menu.children, (sum, child) => { return sum + child.offsetHeight; }, 0); |
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.
nit: can avoid the return here
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.
Done
src/lib/viewers/media/Settings.js
Outdated
if (prevValue !== newValue) { | ||
this.toggleToSubtitle = prevValue; | ||
} | ||
this.containerEl.classList.remove(CLASS_SETTINGS_SUBTITLES_ON); |
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.
nit: new line
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.
Not sure what you mean here.
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.
We generally add a line break after if blocks before other chunks of code
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.
Done
src/lib/viewers/media/Settings.js
Outdated
const subtitlesSubMenu = this.settingsEl.querySelector('.bp-media-settings-menu-subtitles'); | ||
subtitles.forEach((subtitle, idx) => { | ||
insertTemplate(subtitlesSubMenu, SUBTITLES_SUBITEM_TEMPLATE.replace(/{{language}}/g, subtitle).replace(/{{dataValue}}/g, idx)); | ||
}); |
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.
nit: I usually add new lines after any {}
block
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.
Not sure what you mean here.
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.
Line break
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.
Done, I think. Lemme know if I did it wrong.
src/lib/viewers/media/Settings.js
Outdated
}); | ||
this.containerEl.classList.remove(CLASS_SETTINGS_SUBTITLES_UNAVAILABLE); | ||
const subsCache = cache.get('media-subtitles'); | ||
if (subsCache !== null && subsCache !== '-1') { // Last video watched with subtitles, so turn them on here too |
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.
nit: doing if (subscache)
checks for falsey values, so it would catch things like null
and undefined
.
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.
Yea but it also catches things like empty string or 0. 0 in particular can be a problem because it's a valid index into the subtitle track list (though it should always be a string, so we should be fine, but just in case...)
@@ -279,9 +300,21 @@ class DashViewer extends VideoBaseViewer { | |||
addEventListenersForMediaControls() { | |||
super.addEventListenersForMediaControls(); | |||
this.mediaControls.addListener('qualitychange', this.handleQuality); | |||
this.mediaControls.addListener('subtitlechange', this.handleSubtitle); |
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.
What's your thinking on removeAllListeners
vs removeListener
? Typically I like explicitly removing only what I add since that lowers the probability you're stomping through some other listener.
src/lib/viewers/media/Settings.js
Outdated
if (prevValue !== newValue) { | ||
this.toggleToSubtitle = prevValue; | ||
} | ||
this.containerEl.classList.remove(CLASS_SETTINGS_SUBTITLES_ON); |
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.
We generally add a line break after if blocks before other chunks of code
src/lib/viewers/media/Settings.js
Outdated
toggleSubtitles() { | ||
if (this.subtitlesOn) { | ||
this.chooseOption('subtitles', '-1'); | ||
this.subtitlesOn = false; |
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.
Can we infer that subtitles are on / off without adding a property? (checking what option is set already, checking a shaka player property?, etc)
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.
Good tip. I'm going with checking the menu to see if it's off.
src/lib/viewers/media/Settings.js
Outdated
const subtitlesSubMenu = this.settingsEl.querySelector('.bp-media-settings-menu-subtitles'); | ||
subtitles.forEach((subtitle, idx) => { | ||
insertTemplate(subtitlesSubMenu, SUBTITLES_SUBITEM_TEMPLATE.replace(/{{language}}/g, subtitle).replace(/{{dataValue}}/g, idx)); | ||
}); |
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.
Line break
src/lib/viewers/media/Settings.js
Outdated
const subsCache = cache.get('media-subtitles'); | ||
if (subsCache !== null && subsCache !== '-1') { // Last video watched with subtitles, so turn them on here too | ||
this.toggleSubtitles(); | ||
} |
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.
Same thing with line breaks - we generally prefer less dense-looking code.
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.
done
src/lib/viewers/media/Settings.js
Outdated
* @private | ||
* @return {boolean} | ||
*/ | ||
subtitlesOn() { |
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.
areSubtitlesOn() - the current name is ambiguous between turning subtitles on vs checking if they're on
src/lib/viewers/media/Settings.js
Outdated
* @param {string} type - The submenu (e.g. speed, quality, subtitles) | ||
* @return {HTMLElement} The sub-item html element from the Settings menu that's selected | ||
*/ | ||
selectedOption(type) { |
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.
getSelectedOption(type) - function names should contain verbs if you're retrieving a value.
src/lib/viewers/media/Settings.js
Outdated
this.showSubMenu('speed'); | ||
} else if (curNode.getAttribute('data-type') === 'quality') { | ||
this.showSubMenu('quality'); | ||
const dataType = curNode.getAttribute('data-type'); |
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.
You can combine the if blocks and reduce arrowness of the function.
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.
Combining two if-blocks but leaving the top one, just for protection.
@@ -80,6 +87,21 @@ const SETTINGS_TEMPLATE = `<div class="bp-media-settings"> | |||
<div class="bp-media-settings-value">${__('media_quality_auto')}</div> | |||
</div> | |||
</div> | |||
<div class="bp-media-settings-menu-subtitles bp-media-settings-menu bp-media-settings-is-hidden" role="menu"> | |||
<div class="bp-media-settings-sub-item bp-media-settings-sub-item-subtitles" data-type="menu" tabindex="0" role="menuitem" aria-haspopup="true"> |
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.
If you are working on media stuff later, make all these classes variables.
We are repeating so many strings that we can just do <div class="${CLASSNAME}">
.
Should reduce file size.
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.
ok i'll keep that in mind next time
src/lib/viewers/media/DashViewer.js
Outdated
this.mediaControls.removeListener('qualitychange', this.handleQuality); | ||
this.mediaControls.removeListener('subtitlechange', this.handleSubtitle); |
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.
Why arent the last 2 in removeAllListeners()?
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.
Yea great question.... @jeremypress ?? I didn't notice removeAllListeners is already being called. Are these calls necessary?
src/lib/viewers/media/DashViewer.js
Outdated
this.emit('subtitlechange', track.language); | ||
} else { | ||
this.player.setTextTrackVisibility(false); | ||
this.emit('subtitlechange', __('off')); |
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.
Do not localize event data, its for developers using the preview sdk and not for end users.
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.
Done
*/ | ||
handleSubtitle() { | ||
const subtitleIdx = parseInt(cache.get('media-subtitles'), 10); | ||
if (this.textTracks[subtitleIdx] !== undefined) { |
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.
unnecessary !== undefined
if (this.textTracks[subtitleIdx])
should suffice, with it reveresed
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.
empty string
*/ | ||
loadSubtitles() { | ||
this.textTracks = this.player.getTextTracks().sort((track1, track2) => track1.id - track2.id); | ||
if (this.textTracks.length > 0) { |
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.
Should we be > 1?
As in should we show the menu at all if there is only 1 track?
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, because then they can see what language it is for instance
Added subtitles to the video menu. The subtitles menu only shows if the video is detected to have subtitles in it. This is only supported in the DashViewer. There is also a CC button for toggling subtitles on/off
No description provided.