mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-01-23 23:20:51 +01:00
Fix zh-CN subtitle language display
The DisplayTitle property was using .NET's CultureInfo.GetCultures(NeutralCultures) to resolve language display names. Since zh-CN is a specific culture (not neutral), it would fall back to the base 'zh' code, resulting in generic 'Chinese' instead of 'Chinese (Simplified)'. This change adds a LocalizedLanguage property to MediaStream that gets populated via LocalizationManager.FindLanguageInfo() when streams are retrieved from the database. This leverages Jellyfin's existing iso6392.txt mappings which correctly map zh-CN to 'Chinese (Simplified)'. The same pattern is already used for other localized strings like LocalizedDefault and LocalizedExternal.
This commit is contained in:
parent
706a8d2850
commit
9039077286
3 changed files with 55 additions and 46 deletions
|
|
@ -158,6 +158,12 @@ public class MediaStreamRepository : IMediaStreamRepository
|
|||
dto.LocalizedDefault = _localization.GetLocalizedString("Default");
|
||||
dto.LocalizedExternal = _localization.GetLocalizedString("External");
|
||||
|
||||
if (!string.IsNullOrEmpty(dto.Language))
|
||||
{
|
||||
var culture = _localization.FindLanguageInfo(dto.Language);
|
||||
dto.LocalizedLanguage = culture?.DisplayName;
|
||||
}
|
||||
|
||||
if (dto.Type is MediaStreamType.Subtitle)
|
||||
{
|
||||
dto.LocalizedUndefined = _localization.GetLocalizedString("Undefined");
|
||||
|
|
|
|||
|
|
@ -260,6 +260,8 @@ namespace MediaBrowser.Model.Entities
|
|||
|
||||
public string LocalizedHearingImpaired { get; set; }
|
||||
|
||||
public string LocalizedLanguage { get; set; }
|
||||
|
||||
public string DisplayTitle
|
||||
{
|
||||
get
|
||||
|
|
@ -273,29 +275,8 @@ namespace MediaBrowser.Model.Entities
|
|||
// Do not display the language code in display titles if unset or set to a special code. Show it in all other cases (possibly expanded).
|
||||
if (!string.IsNullOrEmpty(Language) && !_specialCodes.Contains(Language, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// Get full language string i.e. eng -> English, zh-Hans -> Chinese (Simplified).
|
||||
var cultures = CultureInfo.GetCultures(CultureTypes.NeutralCultures);
|
||||
CultureInfo match = null;
|
||||
if (Language.Contains('-', StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
match = cultures.FirstOrDefault(r =>
|
||||
r.Name.Equals(Language, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (match is null)
|
||||
{
|
||||
string baseLang = Language.AsSpan().LeftPart('-').ToString();
|
||||
match = cultures.FirstOrDefault(r =>
|
||||
r.TwoLetterISOLanguageName.Equals(baseLang, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
match = cultures.FirstOrDefault(r =>
|
||||
r.ThreeLetterISOLanguageName.Equals(Language, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
string fullLanguage = match?.DisplayName;
|
||||
attributes.Add(StringHelper.FirstToUpper(fullLanguage ?? Language));
|
||||
// Use pre-resolved localized language name, falling back to raw language code.
|
||||
attributes.Add(StringHelper.FirstToUpper(LocalizedLanguage ?? Language));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(Profile) && !string.Equals(Profile, "lc", StringComparison.OrdinalIgnoreCase))
|
||||
|
|
@ -393,29 +374,8 @@ namespace MediaBrowser.Model.Entities
|
|||
|
||||
if (!string.IsNullOrEmpty(Language))
|
||||
{
|
||||
// Get full language string i.e. eng -> English, zh-Hans -> Chinese (Simplified).
|
||||
var cultures = CultureInfo.GetCultures(CultureTypes.NeutralCultures);
|
||||
CultureInfo match = null;
|
||||
if (Language.Contains('-', StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
match = cultures.FirstOrDefault(r =>
|
||||
r.Name.Equals(Language, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (match is null)
|
||||
{
|
||||
string baseLang = Language.AsSpan().LeftPart('-').ToString();
|
||||
match = cultures.FirstOrDefault(r =>
|
||||
r.TwoLetterISOLanguageName.Equals(baseLang, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
match = cultures.FirstOrDefault(r =>
|
||||
r.ThreeLetterISOLanguageName.Equals(Language, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
string fullLanguage = match?.DisplayName;
|
||||
attributes.Add(StringHelper.FirstToUpper(fullLanguage ?? Language));
|
||||
// Use pre-resolved localized language name, falling back to raw language code.
|
||||
attributes.Add(StringHelper.FirstToUpper(LocalizedLanguage ?? Language));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -108,6 +108,49 @@ namespace Jellyfin.Model.Tests.Entities
|
|||
IsExternal = true
|
||||
});
|
||||
|
||||
// Test LocalizedLanguage is used when set (fixes zh-CN display issue #15935)
|
||||
data.Add(
|
||||
"Chinese (Simplified) - SRT",
|
||||
new MediaStream
|
||||
{
|
||||
Type = MediaStreamType.Subtitle,
|
||||
Title = null,
|
||||
Language = "zh-CN",
|
||||
LocalizedLanguage = "Chinese (Simplified)",
|
||||
IsForced = false,
|
||||
IsDefault = false,
|
||||
Codec = "SRT"
|
||||
});
|
||||
|
||||
// Test LocalizedLanguage for audio streams
|
||||
data.Add(
|
||||
"Japanese - AAC - Stereo",
|
||||
new MediaStream
|
||||
{
|
||||
Type = MediaStreamType.Audio,
|
||||
Title = null,
|
||||
Language = "jpn",
|
||||
LocalizedLanguage = "Japanese",
|
||||
IsForced = false,
|
||||
IsDefault = false,
|
||||
Codec = "AAC",
|
||||
ChannelLayout = "stereo"
|
||||
});
|
||||
|
||||
// Test fallback to Language when LocalizedLanguage is null
|
||||
data.Add(
|
||||
"Eng - ASS",
|
||||
new MediaStream
|
||||
{
|
||||
Type = MediaStreamType.Subtitle,
|
||||
Title = null,
|
||||
Language = "eng",
|
||||
LocalizedLanguage = null,
|
||||
IsForced = false,
|
||||
IsDefault = false,
|
||||
Codec = "ASS"
|
||||
});
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue