/**
* Check if the kind is of audio description type.
*
* @param {String} kind indicates the category of the audio
*
* @returns {Boolean} true if audio description, false otherwise
*/
function isAudioDescription(kind) {
return ['description', 'descriptions', 'main-desc'].includes(kind);
}
/**
* Check if the kind is of regular audio type.
*
* @param {String} kind indicates the category of the audio
*
* @returns {Boolean} true if regular audio, false otherwise
*/
function isRegularTrack(kind) {
return ['alternative', 'main', 'translation'].includes(kind);
}
/**
* Find the active track.
*
* @param {Array} tracks array of audio tracks
*
* @returns {Object|undefined} the active track or undefine if no track is active
*/
function findActiveTrack(tracks) {
return Array.from(tracks).find(({ enabled }) => enabled);
}
/**
* Find all audio tracks by language regardless of type.
*
* @param {*} language language code
* @param {Array} tracks array of audio tracks
*
* @returns {Array}
*/
function findAllTracksByLanguage(language, tracks) {
return tracks.filter(track => track.language === language);
}
/**
* Find a track by language.
*
* @param {String} language language code
* @param {Array} tracks array of audio tracks
* @returns {Object|undefined} the track or undefined if no track correspond to the language.
*/
function findTrackByLanguage(language, tracks) {
return tracks.find(track => track.language === language);
}
/**
* Find an audio described track by language.
*
* @param {String} language language code
* @param {Array} tracks array of audio tracks
*
* @returns {Object|undefined} the track or undefined if no audio described track is found.
*/
function findAudioDescriptionTrackByLanguage(language, tracks) {
return tracks.find(track => track.language === language && isAudioDescription(track.kind));
}
/**
* Check if a language exists in a track list.
*
* @param {String} language language code
* @param {Array} tracks array of audio tracks
*
* @returns {Boolean} true if the language exists false otherwise
*/
function hasLanguageTrack(language, tracks) {
return !!findTrackByLanguage(language, tracks);
}
/**
* Check if a specific language is audio described.
*
* @param {String} language language code
* @param {Array} tracks array of audio tracks
*
* @returns {Boolean} true if and audio described track exists false otherwise
*/
function hasAudioDescriptionLanguageTrack(language, tracks) {
return !!findAudioDescriptionTrackByLanguage(language, tracks);
}
/**
* Check if the track list contains only the audio description for a given language.
*
* @param {String} language language code
* @param {Array} tracks array of audio tracks
*
* @returns {Boolean} true if it only contains audio description, false otherwise
*/
function isLanguageOnlyAudioDescription(language, tracks) {
const hasDescription = hasAudioDescriptionLanguageTrack(language, tracks);
const onlyHasDescription = findAllTracksByLanguage(language, tracks)
.filter(track => isRegularTrack(track.kind)).length === 0;
return hasDescription && onlyHasDescription;
}
/**
* Format an object or AudioTrack to .
*
* @param {Object|AudioTrack} obj
* @property {String} obj.kind indicates the category of the audio
* @property {String} obj.language language code
*
* @returns {Object|undefined} returns an object containing the language and description properties, undefined otherwise
*/
function format(
{
language, kind,
} = {},
) {
if (language) {
return {
language,
description: isAudioDescription(kind),
};
}
return undefined;
}
/**
* Sanitize the parameter.
*
* @param {Object} value
*
* @returns {Object}
*/
function sanitizeParameter(value) {
if (typeof value !== 'object' && value !== undefined) {
const language = value;
return format({ language });
}
return value;
}
/**
* Tries to activate the audio track according to the language and description properties.
* - Do nothing if the language does not exist in the list of audio tracks.
* - If the description property is true but no audio matches, the language is used to enable audio as default behavior.
* - If the description property is false but no regular audio matches, the audio described language is used as default behavior.
*
* @param {Object} obj contains a language and a description property
* @property {String} obj.language language code
* @property {Boolean} obj.description true if audio described false otherwise
* @param {AudioTrackList} tracks audio track list
*/
function enableTrack({ language, description = false }, tracks) {
if (!hasLanguageTrack(language, tracks)) return;
if (!hasAudioDescriptionLanguageTrack(language, tracks)
|| isLanguageOnlyAudioDescription(language, tracks)) {
tracks.forEach((track) => {
// eslint-disable-next-line no-param-reassign
track.enabled = track.language === language;
});
return;
}
tracks.forEach((track) => {
// eslint-disable-next-line no-param-reassign
track.enabled = track.language === language
&& typeof description === 'boolean'
&& description === isAudioDescription(track.kind);
});
}
export default {
enableTrack,
findActiveTrack,
findAudioDescriptionTrackByLanguage,
findTrackByLanguage,
format,
hasAudioDescriptionLanguageTrack,
hasLanguageTrack,
isAudioDescription,
isRegularTrack,
sanitizeParameter,
};