Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 115 additions & 0 deletions src/renderer/components/PlayerSettings/PlayerSettings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,14 @@
:icon="['fas', 'photo-film']"
@change="updateDefaultQuality"
/>
<FtSelect
:placeholder="t('Settings.Player Settings.Default Language.Default Language')"
:value="defaultAudioLanguage"
:select-names="AUDIO_LANGUAGE_NAMES"
:select-values="AUDIO_LANGUAGE_VALUES"
:icon="['fas', 'language']"
@change="updateDefaultAudioLanguage"
/>
<FtSelect
:placeholder="t('Settings.Player Settings.Video Playback Rate Interval')"
:value="videoPlaybackRateIntervalString"
Expand Down Expand Up @@ -509,6 +517,113 @@ function updateDefaultQuality(value) {
store.dispatch('updateDefaultQuality', value)
}

const AUDIO_LANGUAGE_VALUES = [
'system',
'af',
'am',
'ar',
'as',
'az',
'be',
'bg',
'bn',
'bs',
'ca',
'cs',
'da',
'de',
'el',
'en',
'en-GB',
'en-IN',
'es',
'es-419',
'es-US',
'et',
'eu',
'fa',
'fi',
'fil',
'fr',
'fr-CA',
'gl',
'gu',
'hi',
'hr',
'hu',
'hy',
'id',
'is',
'it',
'iw',
'ja',
'ka',
'kk',
'km',
'kn',
'ko',
'ky',
'lo',
'lt',
'lv',
'mk',
'ml',
'mn',
'mr',
'ms',
'my',
'ne',
'nl',
'no',
'or',
'pa',
'pl',
'pt',
'pt-PT',
'ro',
'ru',
'si',
'sk',
'sl',
'sq',
'sr',
'sr-Latn',
'sv',
'sw',
'ta',
'te',
'th',
'tr',
'uk',
'ur',
'uz',
'vi',
'zh-CN',
'zh-HK',
'zh-Hans',
'zh-Hant',
'zh-TW',
'zu'
]

const AUDIO_LANGUAGE_NAMES = AUDIO_LANGUAGE_VALUES.map((language, index) => {
if (index === 0) {
return t('Settings.Player Settings.Default Language.System Language')
}

return new Intl.DisplayNames('en', { type: 'language', languageDisplay: 'standard' }).of(language) ?? language
})

/** @type {import('vue').ComputedRef<string>} */
const defaultAudioLanguage = computed(() => store.getters.getDefaultAudioLanguage)

/**
* @param {string} value
*/
function updateDefaultAudioLanguage(value) {
store.dispatch('updateDefaultAudioLanguage', value)
}

const PLAYBACK_RATE_INTERVAL_VALUES = ['0.1', '0.25', '0.5', '1']

/** @type {import('vue').ComputedRef<number>} */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,33 @@ export default defineComponent({
return parseInt(value)
})

/** @type {import('vue').ComputedRef<string>} */
const defaultAudioLanguage = computed(() => store.getters.getDefaultAudioLanguage)

/** @type {import('vue').ComputedRef<string>} */
const preferredAudioLanguage = computed(() => {
return defaultAudioLanguage.value === 'system' ? locale.value : defaultAudioLanguage.value
})

/**
* Filters the given variants to the user's preferred audio language, falling back to the main audio track.
* @param {shaka.extern.Variant[]} variants
* @returns {shaka.extern.Variant[]}
*/
function filterVariantsByPreferredLanguage(variants) {
const languageVariants = variants.filter((variant) => {
return shaka.util.LanguageUtils.areLanguageCompatible(preferredAudioLanguage.value, variant.language)
})

if (languageVariants.length > 0) {
const mainVariants = languageVariants.filter(variant => variant.audioRoles.includes('main'))
return mainVariants.length > 0 ? mainVariants : languageVariants
}

const mainVariants = variants.filter(variant => variant.audioRoles.includes('main'))
return mainVariants.length > 0 ? mainVariants : variants
}

/** @type {import('vue').ComputedRef<boolean>} */
const enterFullscreenOnDisplayRotate = computed(() => {
return store.getters.getEnterFullscreenOnDisplayRotate
Expand Down Expand Up @@ -634,7 +661,11 @@ export default defineComponent({
// Electron doesn't like YouTube's vp9 VR video streams and throws:
// "CHUNK_DEMUXER_ERROR_APPEND_FAILED: Projection element is incomplete; ProjectionPoseYaw required."
// So use the AV1 and h264 codecs instead which it doesn't reject
preferredVideoCodecs: typeof props.vrProjection === 'string' ? ['av01', 'avc1'] : []
preferredVideoCodecs: typeof props.vrProjection === 'string' ? ['av01', 'avc1'] : [],

// The default language to prefer for the audio track.
// 'system' uses FreeTube's active locale, which shaka-player matches by prefix.
preferredAudioLanguage: preferredAudioLanguage.value
}
}

Expand Down Expand Up @@ -1462,12 +1493,7 @@ export default defineComponent({
if (label) {
variants = variants.filter(variant => variant.label === label)
} else if (hasMultipleAudioTracks.value) {
// default audio track
const filteredVariants = variants.filter(variant => variant.audioRoles.includes('main'))
// Sometimes there is nothing marked as main, don't filter in this case
if (filteredVariants.length > 0) {
variants = filteredVariants
}
variants = filterVariantsByPreferredLanguage(variants)
}

const isPortrait = variants[0].height > variants[0].width
Expand Down Expand Up @@ -2906,8 +2932,7 @@ export default defineComponent({
let variants = player.getVariantTracks()

if (hasMultipleAudioTracks.value) {
// default audio track
variants = variants.filter(variant => variant.audioRoles.includes('main'))
variants = filterVariantsByPreferredLanguage(variants)
}

const highestBandwidth = Math.max(...variants.map(variant => variant.audioBandwidth))
Expand Down Expand Up @@ -3164,12 +3189,7 @@ export default defineComponent({
if (label) {
variants = variants.filter(variant => variant.label === label)
} else if (variants.length > 1) {
// default audio track
const filteredVariants = variants.filter(variant => variant.audioRoles.includes('main'))
// Sometimes there is nothing marked as main, don't filter in this case
if (filteredVariants.length > 0) {
variants = filteredVariants
}
variants = filterVariantsByPreferredLanguage(variants)
}

let chosenVariant
Expand Down
1 change: 1 addition & 0 deletions src/renderer/store/modules/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ const state = {
mainColor: 'Red',
secColor: 'Blue',
defaultAutoplayInterruptionIntervalHours: 3,
defaultAudioLanguage: 'system',
defaultCaptionSettings: '{}',
defaultInterval: 5,
defaultPlayback: 1,
Expand Down
3 changes: 3 additions & 0 deletions static/locales/en-US.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,9 @@ Settings:
1440p: 1440p
4k: 4k
8k: 8k
Default Language:
Default Language: Default Audio Language
System Language: Use System Locale
Screenshot:
Enable: Enable Screenshot
Mode: Screenshot Mode
Expand Down