diff --git a/src/renderer/views/Watch/Watch.js b/src/renderer/views/Watch/Watch.js index b7fd1bb0..cbe1e48f 100644 --- a/src/renderer/views/Watch/Watch.js +++ b/src/renderer/views/Watch/Watch.js @@ -382,6 +382,16 @@ export default Vue.extend({ .captionTracks if (typeof captionTracks !== 'undefined') { + const standardLocale = localStorage.getItem('locale').replace('_', '-') + const noLocaleCaption = !captionTracks.some(track => + track.languageCode === standardLocale && track.kind !== 'asr' + ) + + if (!standardLocale.startsWith('en') && noLocaleCaption) { + const baseUrl = result.player_response.captions.playerCaptionsRenderer.baseUrl + this.tryAddingAutoGeneratedLocaleCaption(captionTracks, standardLocale, baseUrl) + } + this.captionHybridList = this.createCaptionPromiseList(captionTracks) const captionLinks = captionTracks.map((caption) => { @@ -1041,14 +1051,51 @@ export default Vue.extend({ }) }, + tryAddingAutoGeneratedLocaleCaption: function (captionTracks, locale, baseUrl) { + const enCaptionIdx = captionTracks.findIndex(track => + track.languageCode === 'en' && track.kind !== 'asr' + ) + + const enCaptionExists = enCaptionIdx !== -1 + const asrEnabled = captionTracks.some(track => track.kind === 'asr') + + if (enCaptionExists || asrEnabled) { + let label + let url + + if (this.$te('Video.translated from English') && this.$t('Video.translated from English') !== '') { + label = `${this.$t('Locale Name')} (${this.$t('Video.translated from English')})` + } else { + label = `${this.$t('Locale Name')} (translated from English)` + } + + if (enCaptionExists) { + url = new URL(captionTracks[enCaptionIdx].baseUrl) + } else { + url = new URL(baseUrl) + url.searchParams.set('lang', 'en') + url.searchParams.set('kind', 'asr') + } + + url.searchParams.set('tlang', locale) + captionTracks.unshift({ + baseUrl: url.toString(), + name: { simpleText: label }, + languageCode: locale + }) + } + }, + createCaptionPromiseList: function (captionTracks) { return captionTracks.map(caption => new Promise((resolve, reject) => { caption.type = 'text/vtt' caption.charset = 'charset=utf-8' caption.dataSource = 'local' - caption.baseUrl += '&fmt=vtt' - $.get(caption.baseUrl, response => { + const url = new URL(caption.baseUrl) + url.searchParams.set('fmt', 'vtt') + + $.get(url.toString(), response => { // The character '#' needs to be percent-encoded in a (data) URI // because it signals an identifier, which means anything after it // is automatically removed when the URI is used as a source diff --git a/static/locales/en-US.yaml b/static/locales/en-US.yaml index 4b969536..7dcf4bee 100644 --- a/static/locales/en-US.yaml +++ b/static/locales/en-US.yaml @@ -466,6 +466,7 @@ Video: Published on: Published on Streamed on: Streamed on Started streaming on: Started streaming on + translated from English: translated from English # $ is replaced with the number and % with the unit (days, hours, minutes...) Publicationtemplate: $ % ago #& Videos