Skip to content

Commit

Permalink
Change UI to show text/audio roles.
Browse files Browse the repository at this point in the history
Closes shaka-project#2307

Change-Id: I13ce5d6185f27a4bfa7481eff4fef629520ff0ce
  • Loading branch information
theodab committed Dec 20, 2019
1 parent 6667ea5 commit 9aaeded
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 33 deletions.
16 changes: 7 additions & 9 deletions ui/audio_language_selection.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,11 @@ shaka.ui.AudioLanguageSelection = class extends shaka.ui.SettingsMenu {
/** @private */
updateAudioLanguages_() {
const tracks = this.player.getVariantTracks();
const languages = this.player.getAudioLanguages();

shaka.ui.LanguageUtils.updateLanguages(tracks, this.menu,
languages,
(lang) => this.onAudioLanguageSelected_(lang), /* updateChosen */ true,
this.currentSelection,
this.localization);
shaka.ui.LanguageUtils.updateTracks(tracks, this.menu,
(track) => this.onAudioTrackSelected_(track),
/* updateChosen */ true, this.currentSelection, this.localization,
this.controls.getConfig().trackLabelFormat);
shaka.ui.Utils.focusOnTheChosenItem(this.menu);

this.controls.dispatchEvent(
Expand All @@ -79,11 +77,11 @@ shaka.ui.AudioLanguageSelection = class extends shaka.ui.SettingsMenu {
}

/**
* @param {string} language
* @param {!shaka.extern.Track} track
* @private
*/
onAudioLanguageSelected_(language) {
this.player.selectAudioLanguage(language);
onAudioTrackSelected_(track) {
this.player.selectAudioLanguage(track.language, track.roles[0]);
}


Expand Down
10 changes: 9 additions & 1 deletion ui/externs/ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ shaka.extern.UIVolumeBarColors;
* castReceiverAppId: string,
* clearBufferOnQualityChange: boolean,
* seekBarColors: shaka.extern.UISeekBarColors,
* volumeBarColors: shaka.extern.UIVolumeBarColors
* volumeBarColors: shaka.extern.UIVolumeBarColors,
* trackLabelFormat: shaka.ui.TrackLabelFormat
* }}
*
* @property {!Array.<string>} controlPanelElements
Expand Down Expand Up @@ -89,6 +90,13 @@ shaka.extern.UIVolumeBarColors;
* The CSS colors applied to the volume bar. This allows you to override the
* colors used in the linear gradient constructed in JavaScript, since you
* cannot do this in pure CSS.
* @property {shaka.ui.TrackLabelFormat} trackLabelFormat
* An enum that determines what is shown in the labels for text track and
* audio variant selection.
* LANGUAGE means that only the language of the item is shown.
* ROLE means that only the role of the item is shown.
* LANGUAGE_ROLE means both are shown, or just language if there is no role.
* Defaults to LANGUAGE.
*/
shaka.extern.UIConfiguration;

Expand Down
67 changes: 56 additions & 11 deletions ui/language_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,24 @@ shaka.ui.LanguageUtils = class {
/**
* @param {!Array.<shaka.extern.Track>} tracks
* @param {!HTMLElement} langMenu
* @param {!Array.<string>} languages
* @param {function(string)} onLanguageSelected
* @param {function(!shaka.extern.Track)} onTrackSelected
* @param {boolean} updateChosen
* @param {!HTMLElement} currentSelectionElement
* @param {shaka.ui.Localization} localization
* @param {shaka.ui.TrackLabelFormat} trackLabelFormat
*/
// TODO: Do the benefits of having this common code in a method still
// outweigh the complexity of the parameter list?
static updateLanguages(tracks, langMenu, languages, onLanguageSelected,
updateChosen, currentSelectionElement, localization) {
static updateTracks(tracks, langMenu, onTrackSelected, updateChosen,
currentSelectionElement, localization, trackLabelFormat) {
// Using array.filter(f)[0] as an alternative to array.find(f) which is
// not supported in IE11.
const activeTracks = tracks.filter((track) => {
return track.active == true;
});
const selectedTrack = activeTracks[0];

// Remove old languages
// Remove old tracks
// 1. Save the back to menu button
const backButton = shaka.ui.Utils.getFirstDescendantWithClassName(
langMenu, 'shaka-back-to-overflow-button');
Expand All @@ -42,19 +42,64 @@ shaka.ui.LanguageUtils = class {
// 3. Add the backTo Menu button back
langMenu.appendChild(backButton);

// 4. Add new buttons
for (const language of languages) {
// 4. Figure out which languages have multiple roles.
const getRolesString = (track) => {
if (track.type == 'variant') {
return track.audioRoles ? track.audioRoles.join(', ') : undefined;
} else {
return track.roles.join(', ');
}
};
/** @type {!Map.<string, !Set.<string>>} */
const rolesByLanguage = new Map();
for (const track of tracks) {
if (!rolesByLanguage.has(track.language)) {
rolesByLanguage.set(track.language, new Set());
}
rolesByLanguage.get(track.language).add(getRolesString(track));
}

// 5. Add new buttons
/** @type {!Set.<string>} */
const combinationsMade = new Set();
for (const track of tracks) {
const language = track.language;
const rolesString = getRolesString(track);
const combinationName = language + ': ' + rolesString;
if (combinationsMade.has(combinationName)) {
continue;
}
combinationsMade.add(combinationName);

const button = shaka.util.Dom.createHTMLElement('button');
button.addEventListener('click', () => {
onLanguageSelected(language);
onTrackSelected(track);
});

const span = shaka.util.Dom.createHTMLElement('span');
span.textContent =
shaka.ui.LanguageUtils.getLanguageName(language, localization);
button.appendChild(span);

if (updateChosen && (language == selectedTrack.language)) {
span.textContent =
shaka.ui.LanguageUtils.getLanguageName(language, localization);
switch (trackLabelFormat) {
case shaka.ui.TrackLabelFormat.ROLE:
if (!rolesString) {
// Fallback behavior. This probably shouldn't happen.
shaka.log.alwaysWarn('Track #' + track.id + ' does not have a ' +
'role, but the UI is configured to only show role.');
span.textContent = '?';
} else {
span.textContent = rolesString;
}
break;
case shaka.ui.TrackLabelFormat.LANGUAGE_ROLE:
if (rolesString) {
span.textContent += ': ' + rolesString;
}
break;
}

if (updateChosen && (track == selectedTrack)) {
button.appendChild(shaka.ui.Utils.checkmarkIcon());
span.classList.add('shaka-chosen-item');
button.setAttribute('aria-selected', 'true');
Expand Down
19 changes: 7 additions & 12 deletions ui/text_selection.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,20 +118,15 @@ shaka.ui.TextSelection = class extends shaka.ui.SettingsMenu {
updateTextLanguages_() {
const tracks = this.player.getTextTracks();

const languagesAndRoles = this.player.getTextLanguagesAndRoles();
const languages = languagesAndRoles.map((langAndRole) => {
return langAndRole.language;
});

shaka.ui.LanguageUtils.updateLanguages(tracks, this.menu,
languages,
(lang) => this.onTextLanguageSelected_(lang),
shaka.ui.LanguageUtils.updateTracks(tracks, this.menu,
(track) => this.onTextTrackSelected_(track),

// Don't mark current text language as chosen unless captions are
// enabled
this.player.isTextTrackVisible(),
this.currentSelection,
this.localization);
this.localization,
this.controls.getConfig().trackLabelFormat);

// Add the Off button
const offButton = shaka.util.Dom.createHTMLElement('button');
Expand Down Expand Up @@ -162,14 +157,14 @@ shaka.ui.TextSelection = class extends shaka.ui.SettingsMenu {


/**
* @param {string} language
* @param {!shaka.extern.Track} track
* @return {!Promise}
* @private
*/
async onTextLanguageSelected_(language) {
async onTextTrackSelected_(track) {
await this.player.setTextTrackVisibility(true);
if (this.player) { // May have become null while awaiting
this.player.selectTextLanguage(language);
this.player.selectTextLanguage(track.language, track.roles[0]);
}
}

Expand Down
14 changes: 14 additions & 0 deletions ui/ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ shaka.ui.Overlay = class {
base: 'rgba(255, 255, 255, 0.54)',
level: 'rgb(255, 255, 255)',
},
trackLabelFormat: shaka.ui.TrackLabelFormat.LANGUAGE,
};
}

Expand Down Expand Up @@ -377,6 +378,19 @@ shaka.ui.Overlay = class {
}
};

/**
* Describes what information should show up in labels for selecting audio
* variants and text tracks.
*
* @enum {number}
* @export
*/
shaka.ui.TrackLabelFormat = {
'LANGUAGE': 0,
'ROLE': 1,
'LANGUAGE_ROLE': 2,
};

if (document.readyState == 'complete') {
// Don't fire this event synchronously. In a compiled bundle, the "shaka"
// namespace might not be exported to the window until after this point.
Expand Down

0 comments on commit 9aaeded

Please sign in to comment.