2023-11-11 13:41:20 +00:00
|
|
|
<!DOCTYPE html><html lang="en" style="font-size:16px"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Source: source/utils/Subtitles.bs</title><!--[if lt IE 9]>
|
|
|
|
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
|
|
|
|
<![endif]--><script src="scripts/third-party/hljs.js" defer="defer"></script><script src="scripts/third-party/hljs-line-num.js" defer="defer"></script><script src="scripts/third-party/popper.js" defer="defer"></script><script src="scripts/third-party/tippy.js" defer="defer"></script><script src="scripts/third-party/tocbot.min.js"></script><script>var baseURL="/",locationPathname="";baseURL=(baseURL=(baseURL="https://jellyfin.github.io/jellyfin-roku/").replace(/https?:\/\//i,"")).substr(baseURL.indexOf("/"))</script><link rel="stylesheet" href="styles/clean-jsdoc-theme.min.css"><svg aria-hidden="true" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="display:none"><defs><symbol id="copy-icon" viewbox="0 0 488.3 488.3"><g><path d="M314.25,85.4h-227c-21.3,0-38.6,17.3-38.6,38.6v325.7c0,21.3,17.3,38.6,38.6,38.6h227c21.3,0,38.6-17.3,38.6-38.6V124 C352.75,102.7,335.45,85.4,314.25,85.4z M325.75,449.6c0,6.4-5.2,11.6-11.6,11.6h-227c-6.4,0-11.6-5.2-11.6-11.6V124 c0-6.4,5.2-11.6,11.6-11.6h227c6.4,0,11.6,5.2,11.6,11.6V449.6z"/><path d="M401.05,0h-227c-21.3,0-38.6,17.3-38.6,38.6c0,7.5,6,13.5,13.5,13.5s13.5-6,13.5-13.5c0-6.4,5.2-11.6,11.6-11.6h227 c6.4,0,11.6,5.2,11.6,11.6v325.7c0,6.4-5.2,11.6-11.6,11.6c-7.5,0-13.5,6-13.5,13.5s6,13.5,13.5,13.5c21.3,0,38.6-17.3,38.6-38.6 V38.6C439.65,17.3,422.35,0,401.05,0z"/></g></symbol><symbol id="search-icon" viewBox="0 0 512 512"><g><g><path d="M225.474,0C101.151,0,0,101.151,0,225.474c0,124.33,101.151,225.474,225.474,225.474 c124.33,0,225.474-101.144,225.474-225.474C450.948,101.151,349.804,0,225.474,0z M225.474,409.323 c-101.373,0-183.848-82.475-183.848-183.848S124.101,41.626,225.474,41.626s183.848,82.475,183.848,183.848 S326.847,409.323,225.474,409.323z"/></g></g><g><g><path d="M505.902,476.472L386.574,357.144c-8.131-8.131-21.299-8.131-29.43,0c-8.131,8.124-8.131,21.306,0,29.43l119.328,119.328 c4.065,4.065,9.387,6.098,14.715,6.098c5.321,0,10.649-2.033,14.715-6.098C514.033,497.778,514.033,484.596,505.902,476.472z"/></g></g></symbol><symbol id="font-size-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M11.246 15H4.754l-2 5H.6L7 4h2l6.4 16h-2.154l-2-5zm-.8-2L8 6.885 5.554 13h4.892zM21 12.535V12h2v8h-2v-.535a4 4 0 1 1 0-6.93zM19 18a2 2 0 1 0 0-4 2 2 0 0 0 0 4z"/></symbol><symbol id="add-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M11 11V5h2v6h6v2h-6v6h-2v-6H5v-2z"/></symbol><symbol id="minus-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M5 11h14v2H5z"/></symbol><symbol id="dark-theme-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M10 7a7 7 0 0 0 12 4.9v.1c0 5.523-4.477 10-10 10S2 17.523 2 12 6.477 2 12 2h.1A6.979 6.979 0 0 0 10 7zm-6 5a8 8 0 0 0 15.062 3.762A9 9 0 0 1 8.238 4.938 7.999 7.999 0 0 0 4 12z"/></symbol><symbol id="light-theme-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 18a6 6 0 1 1 0-12 6 6 0 0 1 0 12zm0-2a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM11 1h2v3h-2V1zm0 19h2v3h-2v-3zM3.515 4.929l1.414-1.414L7.05 5.636 5.636 7.05 3.515 4.93zM16.95 18.364l1.414-1.414 2.121 2.121-1.414 1.414-2.121-2.121zm2.121-14.85l1.414 1.415-2.121 2.121-1.414-1.414 2.121-2.121zM5.636 16.95l1.414 1.414-2.121 2.121-1.414-1.414 2.121-2.121zM23 11v2h-3v-2h3zM4 11v2H1v-2h3z"/></symbol><symbol id="reset-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M18.537 19.567A9.961 9.961 0 0 1 12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10c0 2.136-.67 4.116-1.81 5.74L17 12h3a8 8 0 1 0-2.46 5.772l.997 1.795z"/></symbol><symbol id="down-icon" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M12.7803 6.21967C13.0732 6.51256 13.0732 6.98744 12.7803 7.28033L8.53033 11.5303C8.23744 11.8232 7.76256 11.8232 7.46967 11.5303L3.21967 7.28033C2.92678 6.98744 2.92678 6.51256 3.21967 6.21967C3.51256 5.92678 3.98744 5.92678 4.28033 6.21967L8 9.93934L11.7197 6.21967C12.0126 5.92678 12.4874 5.92678 12.7803 6.21967Z"></path></symbol><symbol id="codepen-icon" viewBox="0 0 24 24"><path fill="none" d=
|
2023-10-06 03:18:36 +00:00
|
|
|
' Including ignoring tracks, if they are not understood, thus making indexing unpredictable.
|
|
|
|
' This function translates between our internel selected subtitle index
|
|
|
|
' and the corresponding index in availableSubtitleTracks.
|
|
|
|
function availSubtitleTrackIdx(video, sub_idx) as integer
|
|
|
|
url = video.Subtitles[sub_idx].Track.TrackName
|
|
|
|
idx = 0
|
|
|
|
for each availTrack in video.availableSubtitleTracks
|
|
|
|
' The TrackName must contain the URL we supplied originally, though
|
|
|
|
' Roku mangles the name a bit, so we check if the URL is a substring, rather
|
|
|
|
' than strict equality
|
|
|
|
if Instr(1, availTrack.TrackName, url)
|
|
|
|
return idx
|
|
|
|
end if
|
|
|
|
idx = idx + 1
|
|
|
|
end for
|
|
|
|
return -1
|
|
|
|
end function
|
|
|
|
|
|
|
|
' Identify the default subtitle track for a given video id
|
|
|
|
' returns the server-side track index for the appriate subtitle
|
|
|
|
function defaultSubtitleTrackFromVid(video_id) as integer
|
|
|
|
meta = ItemMetaData(video_id)
|
|
|
|
if isValid(meta) and isValid(meta.json) and isValid(meta.json.mediaSources)
|
|
|
|
subtitles = sortSubtitles(meta.id, meta.json.MediaSources[0].MediaStreams)
|
|
|
|
default_text_subs = defaultSubtitleTrack(subtitles["all"], true) ' Find correct subtitle track (forced text)
|
|
|
|
if default_text_subs <> -1
|
|
|
|
return default_text_subs
|
|
|
|
else
|
|
|
|
if m.global.session.user.settings["playback.subs.onlytext"] = false
|
|
|
|
return defaultSubtitleTrack(subtitles["all"]) ' if no appropriate text subs exist, allow non-text
|
|
|
|
else
|
|
|
|
return -1
|
|
|
|
end if
|
|
|
|
end if
|
|
|
|
end if
|
|
|
|
' No valid mediaSources (i.e. LiveTV)
|
|
|
|
return -1
|
|
|
|
end function
|
|
|
|
|
|
|
|
|
|
|
|
' Identify the default subtitle track
|
|
|
|
' if "requires_text" is true, only return a track if it is textual
|
|
|
|
' This allows forcing text subs, since roku requires transcoding of non-text subs
|
|
|
|
' returns the server-side track index for the appriate subtitle
|
|
|
|
function defaultSubtitleTrack(sorted_subtitles, require_text = false) as integer
|
|
|
|
if m.global.session.user.configuration.SubtitleMode = "None"
|
|
|
|
return -1 ' No subtitles desired: select none
|
|
|
|
end if
|
|
|
|
|
|
|
|
for each item in sorted_subtitles
|
|
|
|
' Only auto-select subtitle if language matches preference
|
|
|
|
languageMatch = (m.global.session.user.configuration.SubtitleLanguagePreference = item.Track.Language)
|
|
|
|
' Ensure textuality of subtitle matches preferenced passed as arg
|
|
|
|
matchTextReq = ((require_text and item.IsTextSubtitleStream) or not require_text)
|
|
|
|
if languageMatch and matchTextReq
|
|
|
|
if m.global.session.user.configuration.SubtitleMode = "Default" and (item.isForced or item.IsDefault or item.IsExternal)
|
|
|
|
return item.Index ' Finds first forced, or default, or external subs in sorted list
|
|
|
|
else if m.global.session.user.configuration.SubtitleMode = "Always" and not item.IsForced
|
|
|
|
return item.Index ' Select the first non-forced subtitle option in the sorted list
|
|
|
|
else if m.global.session.user.configuration.SubtitleMode = "OnlyForced" and item.IsForced
|
|
|
|
return item.Index ' Select the first forced subtitle option in the sorted list
|
|
|
|
else if m.global.session.user.configuration.SubtitlePlaybackMode = "Smart" and (item.isForced or item.IsDefault or item.IsExternal)
|
|
|
|
' Simplified "Smart" logic here mimics Default (as that is fallback behavior normally)
|
|
|
|
' Avoids detecting preferred audio language (as is utilized in main client)
|
|
|
|
return item.Index
|
|
|
|
end if
|
|
|
|
end if
|
|
|
|
end for
|
|
|
|
return -1 ' Keep current default behavior of "None", if no correct subtitle is identified
|
|
|
|
end function
|
|
|
|
|
|
|
|
' Given a set of subtitles, and a subtitle index (the index on the server, not in the list provided)
|
|
|
|
' this will set all relevant settings for roku (mainly closed captions) and return the index of the
|
|
|
|
' subtitle track specified, but indexed based on the provided list of subtitles
|
|
|
|
function setupSubtitle(video, subtitles, subtitle_idx = -1) as integer
|
|
|
|
if subtitle_idx = -1
|
|
|
|
' If we are not using text-based subtitles, turn them off
|
|
|
|
return -1
|
|
|
|
end if
|
|
|
|
|
|
|
|
' Translate the raw index to one relative to the provided list
|
|
|
|
subtitleSelIdx = getSubtitleSelIdxFromSubIdx(subtitles, subtitle_idx)
|
|
|
|
|
|
|
|
selectedSubtitle = subtitles[subtitleSelIdx]
|
|
|
|
|
|
|
|
if isValid(selectedSubtitle) and isValid(selectedSubtitle.IsEncoded)
|
|
|
|
if selectedSubtitle.IsEncoded
|
|
|
|
' With encoded subtitles, turn off captions
|
|
|
|
video.globalCaptionMode = "Off"
|
|
|
|
else
|
|
|
|
' If this is a text-based subtitle, set relevant settings for roku captions
|
|
|
|
video.globalCaptionMode = "On"
|
|
|
|
video.subtitleTrack = video.availableSubtitleTracks[availSubtitleTrackIdx(video, subtitleSelIdx)].TrackName
|
|
|
|
end if
|
|
|
|
end if
|
|
|
|
|
|
|
|
return subtitleSelIdx
|
|
|
|
end function
|
|
|
|
|
|
|
|
' The subtitle index on the server differs from the index we track locally
|
|
|
|
' This function converts the former into the latter
|
|
|
|
function getSubtitleSelIdxFromSubIdx(subtitles, sub_idx) as integer
|
|
|
|
selIdx = 0
|
|
|
|
if sub_idx = -1 then return -1
|
|
|
|
for each item in subtitles
|
|
|
|
if item.Index = sub_idx
|
|
|
|
return selIdx
|
|
|
|
end if
|
|
|
|
selIdx = selIdx + 1
|
|
|
|
end for
|
|
|
|
return -1
|
|
|
|
end function
|
|
|
|
|
|
|
|
function selectSubtitleTrack(tracks, current = -1) as integer
|
|
|
|
video = m.scene.focusedChild.focusedChild
|
|
|
|
trackSelected = selectSubtitleTrackDialog(video.Subtitles, video.SelectedSubtitle)
|
|
|
|
if trackSelected = invalid or trackSelected = -1 ' back pressed in Dialog - no selection made
|
|
|
|
return -2
|
|
|
|
else
|
|
|
|
return trackSelected - 1
|
|
|
|
end if
|
|
|
|
end function
|
|
|
|
|
|
|
|
' Present Dialog to user to select subtitle track
|
|
|
|
function selectSubtitleTrackDialog(tracks, currentTrack = -1)
|
|
|
|
iso6392 = getSubtitleLanguages()
|
|
|
|
options = ["None"]
|
|
|
|
for each item in tracks
|
|
|
|
forced = ""
|
|
|
|
default = ""
|
|
|
|
if item.IsForced then forced = " [Forced]"
|
|
|
|
if item.IsDefault then default = " - Default"
|
|
|
|
if isValid(item.Track.Language)
|
|
|
|
language = iso6392.lookup(item.Track.Language)
|
|
|
|
if language = invalid then language = item.Track.Language
|
|
|
|
else
|
|
|
|
language = "Undefined"
|
|
|
|
end if
|
|
|
|
options.push(language + forced + default)
|
|
|
|
end for
|
|
|
|
return option_dialog(options, "Select a subtitle track", currentTrack + 1)
|
|
|
|
end function
|
|
|
|
|
|
|
|
sub changeSubtitleDuringPlayback(newid)
|
|
|
|
|
|
|
|
' If no subtitles set
|
|
|
|
if newid = invalid or newid = -1
|
|
|
|
turnoffSubtitles()
|
|
|
|
return
|
|
|
|
end if
|
|
|
|
|
|
|
|
video = m.scene.focusedChild.focusedChild
|
|
|
|
|
|
|
|
' If no change of subtitle track, return
|
|
|
|
if newid = video.SelectedSubtitle then return
|
|
|
|
|
|
|
|
currentSubtitles = video.Subtitles[video.SelectedSubtitle]
|
|
|
|
newSubtitles = video.Subtitles[newid]
|
|
|
|
|
|
|
|
if newSubtitles.IsEncoded or (isValid(currentSubtitles) and currentSubtitles.IsEncoded)
|
|
|
|
' With encoded subtitles we need to stop/start playback
|
|
|
|
video.control = "stop"
|
|
|
|
AddVideoContent(video, video.mediaSourceId, video.audioIndex, newSubtitles.Index, video.position * 10000000)
|
|
|
|
video.control = "play"
|
|
|
|
else
|
|
|
|
' Switching from text to text (or none to text) does not require stopping playback
|
|
|
|
video.globalCaptionMode = "On"
|
|
|
|
video.subtitleTrack = video.availableSubtitleTracks[availSubtitleTrackIdx(video, newid)].TrackName
|
|
|
|
end if
|
|
|
|
|
|
|
|
video.SelectedSubtitle = newid
|
|
|
|
|
|
|
|
end sub
|
|
|
|
|
|
|
|
sub turnoffSubtitles()
|
|
|
|
video = m.scene.focusedChild.focusedChild
|
|
|
|
current = video.SelectedSubtitle
|
|
|
|
video.SelectedSubtitle = -1
|
|
|
|
video.globalCaptionMode = "Off"
|
|
|
|
device = CreateObject("roDeviceInfo")
|
|
|
|
device.EnableAppFocusEvent(false)
|
|
|
|
' Check if Enoded subtitles are being displayed, and turn off
|
|
|
|
if current > -1 and video.Subtitles[current].IsEncoded
|
|
|
|
video.control = "stop"
|
|
|
|
AddVideoContent(video, video.mediaSourceId, video.audioIndex, -1, video.position * 10000000)
|
|
|
|
video.control = "play"
|
|
|
|
end if
|
|
|
|
end sub
|
|
|
|
|
|
|
|
'Checks available subtitle tracks and puts subtitles in forced, default, and non-default/forced but preferred language at the top
|
|
|
|
function sortSubtitles(id as string, MediaStreams)
|
|
|
|
tracks = { "forced": [], "default": [], "normal": [] }
|
|
|
|
'Too many args for using substitute
|
|
|
|
prefered_lang = m.global.session.user.configuration.SubtitleLanguagePreference
|
|
|
|
for each stream in MediaStreams
|
|
|
|
if stream.type = "Subtitle"
|
|
|
|
|
|
|
|
url = ""
|
|
|
|
if isValid(stream.DeliveryUrl)
|
|
|
|
url = buildURL(stream.DeliveryUrl)
|
|
|
|
end if
|
|
|
|
|
|
|
|
stream = {
|
|
|
|
"Track": { "Language": stream.language, "Description": stream.displaytitle, "TrackName": url },
|
|
|
|
"IsTextSubtitleStream": stream.IsTextSubtitleStream,
|
|
|
|
"Index": stream.index,
|
|
|
|
"IsDefault": stream.IsDefault,
|
|
|
|
"IsForced": stream.IsForced,
|
|
|
|
"IsExternal": stream.IsExternal,
|
|
|
|
"IsEncoded": stream.DeliveryMethod = "Encode"
|
|
|
|
}
|
|
|
|
if stream.isForced
|
|
|
|
trackType = "forced"
|
|
|
|
else if stream.IsDefault
|
|
|
|
trackType = "default"
|
|
|
|
else
|
|
|
|
trackType = "normal"
|
|
|
|
end if
|
|
|
|
if prefered_lang <> "" and prefered_lang = stream.Track.Language
|
|
|
|
tracks[trackType].unshift(stream)
|
|
|
|
else
|
|
|
|
tracks[trackType].push(stream)
|
|
|
|
end if
|
|
|
|
end if
|
|
|
|
end for
|
|
|
|
|
|
|
|
tracks["default"].append(tracks["normal"])
|
|
|
|
tracks["forced"].append(tracks["default"])
|
|
|
|
|
|
|
|
textTracks = []
|
|
|
|
for i = 0 to tracks["forced"].count() - 1
|
|
|
|
if tracks["forced"][i].IsTextSubtitleStream
|
|
|
|
textTracks.push(tracks["forced"][i].Track)
|
|
|
|
end if
|
|
|
|
end for
|
|
|
|
return { "all": tracks["forced"], "text": textTracks }
|
|
|
|
end function
|
|
|
|
|
|
|
|
function getSubtitleLanguages()
|
|
|
|
return {
|
|
|
|
"aar": "Afar",
|
|
|
|
"abk": "Abkhazian",
|
|
|
|
"ace": "Achinese",
|
|
|
|
"ach": "Acoli",
|
|
|
|
"ada": "Adangme",
|
|
|
|
"ady": "Adyghe; Adygei",
|
|
|
|
"afa": "Afro-Asiatic languages",
|
|
|
|
"afh": "Afrihili",
|
|
|
|
"afr": "Afrikaans",
|
|
|
|
"ain": "Ainu",
|
|
|
|
"aka": "Akan",
|
|
|
|
"akk": "Akkadian",
|
|
|
|
"alb": "Albanian",
|
|
|
|
"ale": "Aleut",
|
|
|
|
"alg": "Algonquian languages",
|
|
|
|
"alt": "Southern Altai",
|
|
|
|
"amh": "Amharic",
|
|
|
|
"ang": "English, Old (ca.450-1100)",
|
|
|
|
"anp": "Angika",
|
|
|
|
"apa": "Apache languages",
|
|
|
|
"ara": "Arabic",
|
|
|
|
"arc": "Official Aramaic (700-300 BCE); Imperial Aramaic (700-300 BCE)",
|
|
|
|
"arg": "Aragonese",
|
|
|
|
"arm": "Armenian",
|
|
|
|
"arn": "Mapudungun; Mapuche",
|
|
|
|
"arp": "Arapaho",
|
|
|
|
"art": "Artificial languages",
|
|
|
|
"arw": "Arawak",
|
|
|
|
"asm": "Assamese",
|
|
|
|
"ast": "Asturian; Bable; Leonese; Asturleonese",
|
|
|
|
"ath": "Athapascan languages",
|
|
|
|
"aus": "Australian languages",
|
|
|
|
"ava": "Avaric",
|
|
|
|
"ave": "Avestan",
|
|
|
|
"awa": "Awadhi",
|
|
|
|
"aym": "Aymara",
|
|
|
|
"aze": "Azerbaijani",
|
|
|
|
"bad": "Banda languages",
|
|
|
|
"bai": "Bamileke languages",
|
|
|
|
"bak": "Bashkir",
|
|
|
|
"bal": "Baluchi",
|
|
|
|
"bam": "Bambara",
|
|
|
|
"ban": "Balinese",
|
|
|
|
"baq": "Basque",
|
|
|
|
"bas": "Basa",
|
|
|
|
"bat": "Baltic languages",
|
|
|
|
"bej": "Beja; Bedawiyet",
|
|
|
|
"bel": "Belarusian",
|
|
|
|
"bem": "Bemba",
|
|
|
|
"ben": "Bengali",
|
|
|
|
"ber": "Berber languages",
|
|
|
|
"bho": "Bhojpuri",
|
|
|
|
"bih": "Bihari languages",
|
|
|
|
"bik": "Bikol",
|
|
|
|
"bin": "Bini; Edo",
|
|
|
|
"bis": "Bislama",
|
|
|
|
"bla": "Siksika",
|
|
|
|
"bnt": "Bantu (Other)",
|
|
|
|
"bos": "Bosnian",
|
|
|
|
"bra": "Braj",
|
|
|
|
"bre": "Breton",
|
|
|
|
"btk": "Batak languages",
|
|
|
|
"bua": "Buriat",
|
|
|
|
"bug": "Buginese",
|
|
|
|
"bul": "Bulgarian",
|
|
|
|
"bur": "Burmese",
|
|
|
|
"byn": "Blin; Bilin",
|
|
|
|
"cad": "Caddo",
|
|
|
|
"cai": "Central American Indian languages",
|
|
|
|
"car": "Galibi Carib",
|
|
|
|
"cat": "Catalan; Valencian",
|
|
|
|
"cau": "Caucasian languages",
|
|
|
|
"ceb": "Cebuano",
|
|
|
|
"cel": "Celtic languages",
|
|
|
|
"cha": "Chamorro",
|
|
|
|
"chb": "Chibcha",
|
|
|
|
"che": "Chechen",
|
|
|
|
"chg": "Chagatai",
|
|
|
|
"chi": "Chinese",
|
|
|
|
"chk": "Chuukese",
|
|
|
|
"chm": "Mari",
|
|
|
|
"chn": "Chinook jargon",
|
|
|
|
"cho": "Choctaw",
|
|
|
|
"chp": "Chipewyan; Dene Suline",
|
|
|
|
"chr": "Cherokee",
|
|
|
|
"chu": "Church Slavic; Old Slavonic; Church Slavonic; Old Bulgarian; Old Church Slavonic",
|
|
|
|
"chv": "Chuvash",
|
|
|
|
"chy": "Cheyenne",
|
|
|
|
"cmc": "Chamic languages",
|
|
|
|
"cop": "Coptic",
|
|
|
|
"cor": "Cornish",
|
|
|
|
"cos": "Corsican",
|
|
|
|
"cpe": "Creoles and pidgins, English based",
|
|
|
|
"cpf": "Creoles and pidgins, French-based ",
|
|
|
|
"cpp": "Creoles and pidgins, Portuguese-based ",
|
|
|
|
"cre": "Cree",
|
|
|
|
"crh": "Crimean Tatar; Crimean Turkish",
|
|
|
|
"crp": "Creoles and pidgins ",
|
|
|
|
"csb": "Kashubian",
|
|
|
|
"cus": "Cushitic languages",
|
|
|
|
"cze": "Czech",
|
|
|
|
"dak": "Dakota",
|
|
|
|
"dan": "Danish",
|
|
|
|
"dar": "Dargwa",
|
|
|
|
"day": "Land Dayak languages",
|
|
|
|
"del": "Delaware",
|
|
|
|
"den": "Slave (Athapascan)",
|
|
|
|
"dgr": "Dogrib",
|
|
|
|
"din": "Dinka",
|
|
|
|
"div": "Divehi; Dhivehi; Maldivian",
|
|
|
|
"doi": "Dogri",
|
|
|
|
"dra": "Dravidian languages",
|
|
|
|
"dsb": "Lower Sorbian",
|
|
|
|
"dua": "Duala",
|
|
|
|
"dum": "Dutch, Middle (ca.1050-1350)",
|
|
|
|
"dut": "Dutch; Flemish",
|
|
|
|
"dyu": "Dyula",
|
|
|
|
"dzo": "Dzongkha",
|
|
|
|
"efi": "Efik",
|
|
|
|
"egy": "Egyptian (Ancient)",
|
|
|
|
"eka": "Ekajuk",
|
|
|
|
"elx": "Elamite",
|
|
|
|
"eng": "English",
|
|
|
|
"enm": "English, Middle (1100-1500)",
|
|
|
|
"epo": "Esperanto",
|
|
|
|
"est": "Estonian",
|
|
|
|
"ewe": "Ewe",
|
|
|
|
"ewo": "Ewondo",
|
|
|
|
"fan": "Fang",
|
|
|
|
"fao": "Faroese",
|
|
|
|
"fat": "Fanti",
|
|
|
|
"fij": "Fijian",
|
|
|
|
"fil": "Filipino; Pilipino",
|
|
|
|
"fin": "Finnish",
|
|
|
|
"fiu": "Finno-Ugrian languages",
|
|
|
|
"fon": "Fon",
|
|
|
|
"fre": "French",
|
|
|
|
"frm": "French, Middle (ca.1400-1600)",
|
|
|
|
"fro": "French, Old (842-ca.1400)",
|
|
|
|
"frc": "French (Canada)",
|
|
|
|
"frr": "Northern Frisian",
|
|
|
|
"frs": "Eastern Frisian",
|
|
|
|
"fry": "Western Frisian",
|
|
|
|
"ful": "Fulah",
|
|
|
|
"fur": "Friulian",
|
|
|
|
"gaa": "Ga",
|
|
|
|
"gay": "Gayo",
|
|
|
|
"gba": "Gbaya",
|
|
|
|
"gem": "Germanic languages",
|
|
|
|
"geo": "Georgian",
|
|
|
|
"ger": "German",
|
|
|
|
"gez": "Geez",
|
|
|
|
"gil": "Gilbertese",
|
|
|
|
"gla": "Gaelic; Scottish Gaelic",
|
|
|
|
"gle": "Irish",
|
|
|
|
"glg": "Galician",
|
|
|
|
"glv": "Manx",
|
|
|
|
"gmh": "German, Middle High (ca.1050-1500)",
|
|
|
|
"goh": "German, Old High (ca.750-1050)",
|
|
|
|
"gon": "Gondi",
|
|
|
|
"gor": "Gorontalo",
|
|
|
|
"got": "Gothic",
|
|
|
|
"grb": "Grebo",
|
|
|
|
"grc": "Greek, Ancient (to 1453)",
|
|
|
|
"gre": "Greek, Modern (1453-)",
|
|
|
|
"grn": "Guarani",
|
|
|
|
"gsw": "Swiss German; Alemannic; Alsatian",
|
|
|
|
"guj": "Gujarati",
|
|
|
|
"gwi": "Gwich'in",
|
|
|
|
"hai": "Haida",
|
|
|
|
"hat": "Haitian; Haitian Creole",
|
|
|
|
"hau": "Hausa",
|
|
|
|
"haw": "Hawaiian",
|
|
|
|
"heb": "Hebrew",
|
|
|
|
"her": "Herero",
|
|
|
|
"hil": "Hiligaynon",
|
|
|
|
"him": "Himachali languages; Western Pahari languages",
|
|
|
|
"hin": "Hindi",
|
|
|
|
"hit": "Hittite",
|
|
|
|
"hmn": "Hmong; Mong",
|
|
|
|
"hmo": "Hiri Motu",
|
|
|
|
"hrv": "Croatian",
|
|
|
|
"hsb": "Upper Sorbian",
|
|
|
|
"hun": "Hungarian",
|
|
|
|
"hup": "Hupa",
|
|
|
|
"iba": "Iban",
|
|
|
|
"ibo": "Igbo",
|
|
|
|
"ice": "Icelandic",
|
|
|
|
"ido": "Ido",
|
|
|
|
"iii": "Sichuan Yi; Nuosu",
|
|
|
|
"ijo": "Ijo languages",
|
|
|
|
"iku": "Inuktitut",
|
|
|
|
"ile": "Interlingue; Occidental",
|
|
|
|
"ilo": "Iloko",
|
|
|
|
"ina": "Interlingua (International Auxiliary Language Association)",
|
|
|
|
"inc": "Indic languages",
|
|
|
|
"ind": "Indonesian",
|
|
|
|
"ine": "Indo-European languages",
|
|
|
|
"inh": "Ingush",
|
|
|
|
"ipk": "Inupiaq",
|
|
|
|
"ira": "Iranian languages",
|
|
|
|
"iro": "Iroquoian languages",
|
|
|
|
"ita": "Italian",
|
|
|
|
"jav": "Javanese",
|
|
|
|
"jbo": "Lojban",
|
|
|
|
"jpn": "Japanese",
|
|
|
|
"jpr": "Judeo-Persian",
|
|
|
|
"jrb": "Judeo-Arabic",
|
|
|
|
"kaa": "Kara-Kalpak",
|
|
|
|
"kab": "Kabyle",
|
|
|
|
"kac": "Kachin; Jingpho",
|
|
|
|
"kal": "Kalaallisut; Greenlandic",
|
|
|
|
"kam": "Kamba",
|
|
|
|
"kan": "Kannada",
|
|
|
|
"kar": "Karen languages",
|
|
|
|
"kas": "Kashmiri",
|
|
|
|
"kau": "Kanuri",
|
|
|
|
"kaw": "Kawi",
|
|
|
|
"kaz": "Kazakh",
|
|
|
|
"kbd": "Kabardian",
|
|
|
|
"kha": "Khasi",
|
|
|
|
"khi": "Khoisan languages",
|
|
|
|
"khm": "Central Khmer",
|
|
|
|
"kho": "Khotanese; Sakan",
|
|
|
|
"kik": "Kikuyu; Gikuyu",
|
|
|
|
"kin": "Kinyarwanda",
|
|
|
|
"kir": "Kirghiz; Kyrgyz",
|
|
|
|
"kmb": "Kimbundu",
|
|
|
|
"kok": "Konkani",
|
|
|
|
"kom": "Komi",
|
|
|
|
"kon": "Kongo",
|
|
|
|
"kor": "Korean",
|
|
|
|
"kos": "Kosraean",
|
|
|
|
"kpe": "Kpelle",
|
|
|
|
"krc": "Karachay-Balkar",
|
|
|
|
"krl": "Karelian",
|
|
|
|
"kro": "Kru languages",
|
|
|
|
"kru": "Kurukh",
|
|
|
|
"kua": "Kuanyama; Kwanyama",
|
|
|
|
"kum": "Kumyk",
|
|
|
|
"kur": "Kurdish",
|
|
|
|
"kut": "Kutenai",
|
|
|
|
"lad": "Ladino",
|
|
|
|
"lah": "Lahnda",
|
|
|
|
"lam": "Lamba",
|
|
|
|
"lao": "Lao",
|
|
|
|
"lat": "Latin",
|
|
|
|
"lav": "Latvian",
|
|
|
|
"lez": "Lezghian",
|
|
|
|
"lim": "Limburgan; Limburger; Limburgish",
|
|
|
|
"lin": "Lingala",
|
|
|
|
"lit": "Lithuanian",
|
|
|
|
"lol": "Mongo",
|
|
|
|
"loz": "Lozi",
|
|
|
|
"ltz": "Luxembourgish; Letzeburgesch",
|
|
|
|
"lua": "Luba-Lulua",
|
|
|
|
"lub": "Luba-Katanga",
|
|
|
|
"lug": "Ganda",
|
|
|
|
"lui": "Luiseno",
|
|
|
|
"lun": "Lunda",
|
|
|
|
"luo": "Luo (Kenya and Tanzania)",
|
|
|
|
"lus": "Lushai",
|
|
|
|
"mac": "Macedonian",
|
|
|
|
"mad": "Madurese",
|
|
|
|
"mag": "Magahi",
|
|
|
|
"mah": "Marshallese",
|
|
|
|
"mai": "Maithili",
|
|
|
|
"mak": "Makasar",
|
|
|
|
"mal": "Malayalam",
|
|
|
|
"man": "Mandingo",
|
|
|
|
"mao": "Maori",
|
|
|
|
"map": "Austronesian languages",
|
|
|
|
"mar": "Marathi",
|
|
|
|
"mas": "Masai",
|
|
|
|
"may": "Malay",
|
|
|
|
"mdf": "Moksha",
|
|
|
|
"mdr": "Mandar",
|
|
|
|
"men": "Mende",
|
|
|
|
"mga": "Irish, Middle (900-1200)",
|
|
|
|
"mic": "Mi'kmaq; Micmac",
|
|
|
|
"min": "Minangkabau",
|
|
|
|
"mis": "Uncoded languages",
|
|
|
|
"mkh": "Mon-Khmer languages",
|
|
|
|
"mlg": "Malagasy",
|
|
|
|
"mlt": "Maltese",
|
|
|
|
"mnc": "Manchu",
|
|
|
|
"mni": "Manipuri",
|
|
|
|
"mno": "Manobo languages",
|
|
|
|
"moh": "Mohawk",
|
|
|
|
"mon": "Mongolian",
|
|
|
|
"mos": "Mossi",
|
|
|
|
"mul": "Multiple languages",
|
|
|
|
"mun": "Munda languages",
|
|
|
|
"mus": "Creek",
|
|
|
|
"mwl": "Mirandese",
|
|
|
|
"mwr": "Marwari",
|
|
|
|
"myn": "Mayan languages",
|
|
|
|
"myv": "Erzya",
|
|
|
|
"nah": "Nahuatl languages",
|
|
|
|
"nai": "North American Indian languages",
|
|
|
|
"nap": "Neapolitan",
|
|
|
|
"nau": "Nauru",
|
|
|
|
"nav": "Navajo; Navaho",
|
|
|
|
"nbl": "Ndebele, South; South Ndebele",
|
|
|
|
"nde": "Ndebele, North; North Ndebele",
|
|
|
|
"ndo": "Ndonga",
|
|
|
|
"nds": "Low German; Low Saxon; German, Low; Saxon, Low",
|
|
|
|
"nep": "Nepali",
|
|
|
|
"new": "Nepal Bhasa; Newari",
|
|
|
|
"nia": "Nias",
|
|
|
|
"nic": "Niger-Kordofanian languages",
|
|
|
|
"niu": "Niuean",
|
|
|
|
"nno": "Norwegian Nynorsk; Nynorsk, Norwegian",
|
|
|
|
"nob": "Bokmål, Norwegian; Norwegian Bokmål",
|
|
|
|
"nog": "Nogai",
|
|
|
|
"non": "Norse, Old",
|
|
|
|
"nor": "Norwegian",
|
|
|
|
"nqo": "N'Ko",
|
|
|
|
"nso": "Pedi; Sepedi; Northern Sotho",
|
|
|
|
"nub": "Nubian languages",
|
|
|
|
"nwc": "Classical Newari; Old Newari; Classical Nepal Bhasa",
|
|
|
|
"nya": "Chichewa; Chewa; Nyanja",
|
|
|
|
"nym": "Nyamwezi",
|
|
|
|
"nyn": "Nyankole",
|
|
|
|
"nyo": "Nyoro",
|
|
|
|
"nzi": "Nzima",
|
|
|
|
"oci": "Occitan (post 1500); Provençal",
|
|
|
|
"oji": "Ojibwa",
|
|
|
|
"ori": "Oriya",
|
|
|
|
"orm": "Oromo",
|
|
|
|
"osa": "Osage",
|
|
|
|
"oss": "Ossetian; Ossetic",
|
|
|
|
"ota": "Turkish, Ottoman (1500-1928)",
|
|
|
|
"oto": "Otomian languages",
|
|
|
|
"paa": "Papuan languages",
|
|
|
|
"pag": "Pangasinan",
|
|
|
|
"pal": "Pahlavi",
|
|
|
|
"pam": "Pampanga; Kapampangan",
|
|
|
|
"pan": "Panjabi; Punjabi",
|
|
|
|
"pap": "Papiamento",
|
|
|
|
"pau": "Palauan",
|
|
|
|
"peo": "Persian, Old (ca.600-400 B.C.)",
|
|
|
|
"per": "Persian",
|
|
|
|
"phi": "Philippine languages",
|
|
|
|
"phn": "Phoenician",
|
|
|
|
"pli": "Pali",
|
|
|
|
"pol": "Polish",
|
|
|
|
"pon": "Pohnpeian",
|
|
|
|
"por": "Portuguese",
|
|
|
|
"pob": "Portuguese (Brazil)",
|
|
|
|
"pra": "Prakrit languages",
|
|
|
|
"pro": "Provençal, Old (to 1500)",
|
|
|
|
"pus": "Pushto; Pashto",
|
|
|
|
"qaa-qtz": "Reserved for local use",
|
|
|
|
"que": "Quechua",
|
|
|
|
"raj": "Rajasthani",
|
|
|
|
"rap": "Rapanui",
|
|
|
|
"rar": "Rarotongan; Cook Islands Maori",
|
|
|
|
"roa": "Romance languages",
|
|
|
|
"roh": "Romansh",
|
|
|
|
"rom": "Romany",
|
|
|
|
"rum": "Romanian; Moldavian; Moldovan",
|
|
|
|
"run": "Rundi",
|
|
|
|
"rup": "Aromanian; Arumanian; Macedo-Romanian",
|
|
|
|
"rus": "Russian",
|
|
|
|
"sad": "Sandawe",
|
|
|
|
"sag": "Sango",
|
|
|
|
"sah": "Yakut",
|
|
|
|
"sai": "South American Indian (Other)",
|
|
|
|
"sal": "Salishan languages",
|
|
|
|
"sam": "Samaritan Aramaic",
|
|
|
|
"san": "Sanskrit",
|
|
|
|
"sas": "Sasak",
|
|
|
|
"sat": "Santali",
|
|
|
|
"scn": "Sicilian",
|
|
|
|
"sco": "Scots",
|
|
|
|
"sel": "Selkup",
|
|
|
|
"sem": "Semitic languages",
|
|
|
|
"sga": "Irish, Old (to 900)",
|
|
|
|
"sgn": "Sign Languages",
|
|
|
|
"shn": "Shan",
|
|
|
|
"sid": "Sidamo",
|
|
|
|
"sin": "Sinhala; Sinhalese",
|
|
|
|
"sio": "Siouan languages",
|
|
|
|
"sit": "Sino-Tibetan languages",
|
|
|
|
"sla": "Slavic languages",
|
|
|
|
"slo": "Slovak",
|
|
|
|
"slv": "Slovenian",
|
|
|
|
"sma": "Southern Sami",
|
|
|
|
"sme": "Northern Sami",
|
|
|
|
"smi": "Sami languages",
|
|
|
|
"smj": "Lule Sami",
|
|
|
|
"smn": "Inari Sami",
|
|
|
|
"smo": "Samoan",
|
|
|
|
"sms": "Skolt Sami",
|
|
|
|
"sna": "Shona",
|
|
|
|
"snd": "Sindhi",
|
|
|
|
"snk": "Soninke",
|
|
|
|
"sog": "Sogdian",
|
|
|
|
"som": "Somali",
|
|
|
|
"son": "Songhai languages",
|
|
|
|
"sot": "Sotho, Southern",
|
|
|
|
"spa": "Spanish; Latin",
|
|
|
|
"spa": "Spanish; Castilian",
|
|
|
|
"srd": "Sardinian",
|
|
|
|
"srn": "Sranan Tongo",
|
|
|
|
"srp": "Serbian",
|
|
|
|
"srr": "Serer",
|
|
|
|
"ssa": "Nilo-Saharan languages",
|
|
|
|
"ssw": "Swati",
|
|
|
|
"suk": "Sukuma",
|
|
|
|
"sun": "Sundanese",
|
|
|
|
"sus": "Susu",
|
|
|
|
"sux": "Sumerian",
|
|
|
|
"swa": "Swahili",
|
|
|
|
"swe": "Swedish",
|
|
|
|
"syc": "Classical Syriac",
|
|
|
|
"syr": "Syriac",
|
|
|
|
"tah": "Tahitian",
|
|
|
|
"tai": "Tai languages",
|
|
|
|
"tam": "Tamil",
|
|
|
|
"tat": "Tatar",
|
|
|
|
"tel": "Telugu",
|
|
|
|
"tem": "Timne",
|
|
|
|
"ter": "Tereno",
|
|
|
|
"tet": "Tetum",
|
|
|
|
"tgk": "Tajik",
|
|
|
|
"tgl": "Tagalog",
|
|
|
|
"tha": "Thai",
|
|
|
|
"tib": "Tibetan",
|
|
|
|
"tig": "Tigre",
|
|
|
|
"tir": "Tigrinya",
|
|
|
|
"tiv": "Tiv",
|
|
|
|
"tkl": "Tokelau",
|
|
|
|
"tlh": "Klingon; tlhIngan-Hol",
|
|
|
|
"tli": "Tlingit",
|
|
|
|
"tmh": "Tamashek",
|
|
|
|
"tog": "Tonga (Nyasa)",
|
|
|
|
"ton": "Tonga (Tonga Islands)",
|
|
|
|
"tpi": "Tok Pisin",
|
|
|
|
"tsi": "Tsimshian",
|
|
|
|
"tsn": "Tswana",
|
|
|
|
"tso": "Tsonga",
|
|
|
|
"tuk": "Turkmen",
|
|
|
|
"tum": "Tumbuka",
|
|
|
|
"tup": "Tupi languages",
|
|
|
|
"tur": "Turkish",
|
|
|
|
"tut": "Altaic languages",
|
|
|
|
"tvl": "Tuvalu",
|
|
|
|
"twi": "Twi",
|
|
|
|
"tyv": "Tuvinian",
|
|
|
|
"udm": "Udmurt",
|
|
|
|
"uga": "Ugaritic",
|
|
|
|
"uig": "Uighur; Uyghur",
|
|
|
|
"ukr": "Ukrainian",
|
|
|
|
"umb": "Umbundu",
|
|
|
|
"und": "Undetermined",
|
|
|
|
"urd": "Urdu",
|
|
|
|
"uzb": "Uzbek",
|
|
|
|
"vai": "Vai",
|
|
|
|
"ven": "Venda",
|
|
|
|
"vie": "Vietnamese",
|
|
|
|
"vol": "Volapük",
|
|
|
|
"vot": "Votic",
|
|
|
|
"wak": "Wakashan languages",
|
|
|
|
"wal": "Walamo",
|
|
|
|
"war": "Waray",
|
|
|
|
"was": "Washo",
|
|
|
|
"wel": "Welsh",
|
|
|
|
"wen": "Sorbian languages",
|
|
|
|
"wln": "Walloon",
|
|
|
|
"wol": "Wolof",
|
|
|
|
"xal": "Kalmyk; Oirat",
|
|
|
|
"xho": "Xhosa",
|
|
|
|
"yao": "Yao",
|
|
|
|
"yap": "Yapese",
|
|
|
|
"yid": "Yiddish",
|
|
|
|
"yor": "Yoruba",
|
|
|
|
"ypk": "Yupik languages",
|
|
|
|
"zap": "Zapotec",
|
|
|
|
"zbl": "Blissymbols; Blissymbolics; Bliss",
|
|
|
|
"zen": "Zenaga",
|
|
|
|
"zgh": "Standard Moroccan Tamazight",
|
|
|
|
"zha": "Zhuang; Chuang",
|
|
|
|
"znd": "Zande languages",
|
|
|
|
"zul": "Zulu",
|
|
|
|
"zun": "Zuni",
|
|
|
|
"zxx": "No linguistic content; Not applicable",
|
|
|
|
"zza": "Zaza; Dimili; Dimli; Kirdki; Kirmanjki; Zazaki"
|
|
|
|
}
|
|
|
|
end function
|
2023-11-11 13:41:20 +00:00
|
|
|
</code></pre></article></section><footer class="footer" id="PeOAagUepe"><div class="wrapper"><span class="jsdoc-message">Automatically generated using <a href="https://github.com/jsdoc/jsdoc" target="_blank">JSDoc</a> and the <a href="https://github.com/ankitskvmdam/clean-jsdoc-theme" target="_blank">clean-jsdoc-theme</a>.</span></div></footer></div></div></div><div class="search-container" id="PkfLWpAbet" style="display:none"><div class="wrapper" id="iCxFxjkHbP"><button class="icon-button search-close-button" id="VjLlGakifb" aria-label="close search"><svg><use xlink:href="#close-icon"></use></svg></button><div class="search-box-c"><svg><use xlink:href="#search-icon"></use></svg> <input type="text" id="vpcKVYIppa" class="search-input" placeholder="Search..." autofocus></div><div class="search-result-c" id="fWwVHRuDuN"><span class="search-result-c-text">Type anything to view search result</span></div></div></div><div class="mobile-menu-icon-container"><button class="icon-button" id="mobile-menu" data-isopen="false" aria-label="menu"><svg><use xlink:href="#menu-icon"></use></svg></button></div><div id="mobile-sidebar" class="mobile-sidebar-container"><div class="mobile-sidebar-wrapper"><a href="/" class="sidebar-title sidebar-title-anchor">jellyfin-roku Code Documentation</a><div class="mobile-nav-links"><div class="external-link navbar-item"><a id="jellyfin-link-mobile" href="https://jellyfin.org/" target="_blank">Jellyfin</a></div><div class="external-link navbar-item"><a id="github-link-mobile" href="https://github.com/jellyfin/jellyfin-roku" target="_blank">GitHub</a></div><div class="external-link navbar-item"><a id="forum-link-mobile" href="https://forum.jellyfin.org/f-roku-development" target="_blank">Forum</a></div><div class="external-link navbar-item"><a id="matrix-link-mobile" href="https://matrix.to/#/#jellyfin-dev-roku:matrix.org" target="_blank">Matrix</a></div></div><div class="mobile-sidebar-items-c"><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-modules"><div>Modules</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="module-AlbumData.html">AlbumData</a></div><div class="sidebar-section-children"><a href="module-AlbumGrid.html">AlbumGrid</a></div><div class="sidebar-section-children"><a href="module-AlbumTrackList.html">AlbumTrackList</a></div><div class="sidebar-section-children"><a href="module-AlbumView.html">AlbumView</a></div><div class="sidebar-section-children"><a href="module-Alpha.html">Alpha</a></div><div class="sidebar-section-children"><a href="module-ArtistView.html">ArtistView</a></div><div class="sidebar-section-children"><a href="module-AudioPlayer.html">AudioPlayer</a></div><div class="sidebar-section-children"><a href="module-AudioPlayerView.html">AudioPlayerView</a></div><div class="sidebar-section-children"><a href="module-AudioTrackListItem.html">AudioTrackListItem</a></div><div class="sidebar-section-children"><a href="module-ButtonGroupHoriz.html">ButtonGroupHoriz</a></div><div class="sidebar-section-children"><a href="module-ButtonGroupVert.html">ButtonGroupVert</a></div><div class="sidebar-section-children"><a href="module-ChannelData.html">ChannelData</a></div><div class="sidebar-section-children"><a href="module-Clock.html">Clock</a></div><div class="sidebar-section-children"><a href="module-CollectionData.html">CollectionData</a></div><div class="sidebar-section-children"><a href="module-ConfigData.html">ConfigData</a></div><div class="sidebar-section-children"><a href="module-ConfigItem.html">ConfigItem</a></div><div class="sidebar-section-children"><a href="module-ConfigList.html">ConfigList</a></div><div class="sidebar-section-children"><a href="module-ExtrasItem.html">ExtrasItem</a></div><div class="sidebar-section-children"><a href="module-ExtrasRowList.html">ExtrasRowList</a></div><div class="sidebar-section-children"><a href="module-FavoriteItemsTask.html">FavoriteItemsTask</a></div><div class="sidebar-section-children"><a href="module-Folder
|