mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-04-22 10:04:44 +01:00
Merge remote-tracking branch 'upstream/master' into client-logger
This commit is contained in:
@@ -38,14 +38,11 @@ namespace Emby.Server.Implementations.Library
|
||||
}
|
||||
|
||||
public static int? GetDefaultSubtitleStreamIndex(
|
||||
List<MediaStream> streams,
|
||||
IEnumerable<MediaStream> streams,
|
||||
string[] preferredLanguages,
|
||||
SubtitlePlaybackMode mode,
|
||||
string audioTrackLanguage)
|
||||
{
|
||||
streams = GetSortedStreams(streams, MediaStreamType.Subtitle, preferredLanguages)
|
||||
.ToList();
|
||||
|
||||
MediaStream stream = null;
|
||||
|
||||
if (mode == SubtitlePlaybackMode.None)
|
||||
@@ -53,52 +50,48 @@ namespace Emby.Server.Implementations.Library
|
||||
return null;
|
||||
}
|
||||
|
||||
var sortedStreams = streams
|
||||
.Where(i => i.Type == MediaStreamType.Subtitle)
|
||||
.OrderByDescending(x => x.IsExternal)
|
||||
.ThenByDescending(x => x.IsForced && string.Equals(x.Language, audioTrackLanguage, StringComparison.OrdinalIgnoreCase))
|
||||
.ThenByDescending(x => x.IsForced)
|
||||
.ThenByDescending(x => x.IsDefault)
|
||||
.ToList();
|
||||
|
||||
if (mode == SubtitlePlaybackMode.Default)
|
||||
{
|
||||
// Prefer embedded metadata over smart logic
|
||||
|
||||
stream = streams.FirstOrDefault(s => s.IsForced && string.Equals(s.Language, audioTrackLanguage, StringComparison.OrdinalIgnoreCase)) ??
|
||||
streams.FirstOrDefault(s => s.IsForced) ??
|
||||
streams.FirstOrDefault(s => s.IsDefault);
|
||||
stream = sortedStreams.FirstOrDefault(s => s.IsExternal || s.IsForced || s.IsDefault);
|
||||
|
||||
// if the audio language is not understood by the user, load their preferred subs, if there are any
|
||||
if (stream == null && !preferredLanguages.Contains(audioTrackLanguage, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
stream = streams.Where(s => !s.IsForced).FirstOrDefault(s => preferredLanguages.Contains(s.Language, StringComparer.OrdinalIgnoreCase));
|
||||
stream = sortedStreams.FirstOrDefault(s => !s.IsForced && preferredLanguages.Contains(s.Language, StringComparer.OrdinalIgnoreCase));
|
||||
}
|
||||
}
|
||||
else if (mode == SubtitlePlaybackMode.Smart)
|
||||
{
|
||||
// Prefer smart logic over embedded metadata
|
||||
|
||||
// if the audio language is not understood by the user, load their preferred subs, if there are any
|
||||
if (!preferredLanguages.Contains(audioTrackLanguage, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
stream = streams.Where(s => !s.IsForced).FirstOrDefault(s => preferredLanguages.Contains(s.Language, StringComparer.OrdinalIgnoreCase)) ??
|
||||
stream = streams.FirstOrDefault(s => !s.IsForced && preferredLanguages.Contains(s.Language, StringComparer.OrdinalIgnoreCase)) ??
|
||||
streams.FirstOrDefault(s => preferredLanguages.Contains(s.Language, StringComparer.OrdinalIgnoreCase));
|
||||
}
|
||||
}
|
||||
else if (mode == SubtitlePlaybackMode.Always)
|
||||
{
|
||||
// always load the most suitable full subtitles
|
||||
stream = streams.FirstOrDefault(s => !s.IsForced);
|
||||
stream = sortedStreams.FirstOrDefault(s => !s.IsForced);
|
||||
}
|
||||
else if (mode == SubtitlePlaybackMode.OnlyForced)
|
||||
{
|
||||
// always load the most suitable full subtitles
|
||||
stream = streams.FirstOrDefault(s => s.IsForced && string.Equals(s.Language, audioTrackLanguage, StringComparison.OrdinalIgnoreCase)) ??
|
||||
streams.FirstOrDefault(s => s.IsForced);
|
||||
stream = sortedStreams.FirstOrDefault(x => x.IsForced);
|
||||
}
|
||||
|
||||
// load forced subs if we have found no suitable full subtitles
|
||||
stream ??= streams.FirstOrDefault(s => s.IsForced && string.Equals(s.Language, audioTrackLanguage, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (stream != null)
|
||||
{
|
||||
return stream.Index;
|
||||
}
|
||||
|
||||
return null;
|
||||
stream ??= sortedStreams.FirstOrDefault(s => s.IsForced && string.Equals(s.Language, audioTrackLanguage, StringComparison.OrdinalIgnoreCase));
|
||||
return stream?.Index;
|
||||
}
|
||||
|
||||
private static IEnumerable<MediaStream> GetSortedStreams(IEnumerable<MediaStream> streams, MediaStreamType type, string[] languagePreferences)
|
||||
|
||||
@@ -54,6 +54,8 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV
|
||||
return null;
|
||||
}
|
||||
|
||||
var seriesInfo = Naming.TV.SeriesResolver.Resolve(_libraryManager.GetNamingOptions(), args.Path);
|
||||
|
||||
var collectionType = args.GetCollectionType();
|
||||
if (string.Equals(collectionType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
@@ -63,7 +65,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV
|
||||
return new Series
|
||||
{
|
||||
Path = args.Path,
|
||||
Name = Path.GetFileName(args.Path)
|
||||
Name = seriesInfo.Name
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -80,7 +82,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV
|
||||
return new Series
|
||||
{
|
||||
Path = args.Path,
|
||||
Name = Path.GetFileName(args.Path)
|
||||
Name = seriesInfo.Name
|
||||
};
|
||||
}
|
||||
|
||||
@@ -94,7 +96,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV
|
||||
return new Series
|
||||
{
|
||||
Path = args.Path,
|
||||
Name = Path.GetFileName(args.Path)
|
||||
Name = seriesInfo.Name
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,11 +12,11 @@
|
||||
"DeviceOfflineWithName": "قُطِع الاتصال ب{0}",
|
||||
"DeviceOnlineWithName": "{0} متصل",
|
||||
"FailedLoginAttemptWithUserName": "عملية تسجيل الدخول فشلت من {0}",
|
||||
"Favorites": "المفضلة",
|
||||
"Favorites": "مفضلات",
|
||||
"Folders": "المجلدات",
|
||||
"Genres": "التضنيفات",
|
||||
"HeaderAlbumArtists": "ألبوم الفنان",
|
||||
"HeaderContinueWatching": "استئناف",
|
||||
"HeaderContinueWatching": "استمر بالمشاهدة",
|
||||
"HeaderFavoriteAlbums": "الألبومات المفضلة",
|
||||
"HeaderFavoriteArtists": "الفنانون المفضلون",
|
||||
"HeaderFavoriteEpisodes": "الحلقات المفضلة",
|
||||
@@ -33,7 +33,7 @@
|
||||
"LabelRunningTimeValue": "المدة: {0}",
|
||||
"Latest": "الأحدث",
|
||||
"MessageApplicationUpdated": "لقد تم تحديث خادم Jellyfin",
|
||||
"MessageApplicationUpdatedTo": "تم تحديث سيرفر Jellyfin الى {0}",
|
||||
"MessageApplicationUpdatedTo": "تم تحديث خادم Jellyfin الى {0}",
|
||||
"MessageNamedServerConfigurationUpdatedWithValue": "تم تحديث إعدادات الخادم في قسم {0}",
|
||||
"MessageServerConfigurationUpdated": "تم تحديث إعدادات الخادم",
|
||||
"MixedContent": "محتوى مختلط",
|
||||
@@ -43,7 +43,7 @@
|
||||
"NameInstallFailed": "فشل التثبيت {0}",
|
||||
"NameSeasonNumber": "الموسم {0}",
|
||||
"NameSeasonUnknown": "الموسم غير معروف",
|
||||
"NewVersionIsAvailable": "نسخة جديدة من سيرفر Jellyfin متوفرة للتحميل.",
|
||||
"NewVersionIsAvailable": "نسخة جديدة من خادم Jellyfin متوفرة للتحميل.",
|
||||
"NotificationOptionApplicationUpdateAvailable": "يوجد تحديث للتطبيق",
|
||||
"NotificationOptionApplicationUpdateInstalled": "تم تحديث التطبيق",
|
||||
"NotificationOptionAudioPlayback": "بدأ تشغيل المقطع الصوتي",
|
||||
@@ -55,7 +55,7 @@
|
||||
"NotificationOptionPluginInstalled": "تم تثبيت الملحق",
|
||||
"NotificationOptionPluginUninstalled": "تمت إزالة الملحق",
|
||||
"NotificationOptionPluginUpdateInstalled": "تم تثبيت تحديثات الملحق",
|
||||
"NotificationOptionServerRestartRequired": "يجب إعادة تشغيل السيرفر",
|
||||
"NotificationOptionServerRestartRequired": "يجب إعادة تشغيل الخادم",
|
||||
"NotificationOptionTaskFailed": "فشل في المهمة المجدولة",
|
||||
"NotificationOptionUserLockedOut": "تم إقفال حساب المستخدم",
|
||||
"NotificationOptionVideoPlayback": "بدأ تشغيل الفيديو",
|
||||
@@ -72,7 +72,7 @@
|
||||
"ServerNameNeedsToBeRestarted": "يحتاج لإعادة تشغيله {0}",
|
||||
"Shows": "الحلقات",
|
||||
"Songs": "الأغاني",
|
||||
"StartupEmbyServerIsLoading": "سيرفر Jellyfin قيد التشغيل . الرجاء المحاولة بعد قليل.",
|
||||
"StartupEmbyServerIsLoading": "خادم Jellyfin قيد التشغيل . الرجاء المحاولة بعد قليل.",
|
||||
"SubtitleDownloadFailureForItem": "عملية إنزال الترجمة فشلت لـ{0}",
|
||||
"SubtitleDownloadFailureFromForItem": "الترجمات فشلت في التحميل من {0} الى {1}",
|
||||
"Sync": "مزامنة",
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
"Favorites": "Favoritter",
|
||||
"Folders": "Mapper",
|
||||
"Genres": "Genrer",
|
||||
"HeaderAlbumArtists": "Albumkunstnere",
|
||||
"HeaderAlbumArtists": "Kunstnerens album",
|
||||
"HeaderContinueWatching": "Fortsæt Afspilning",
|
||||
"HeaderFavoriteAlbums": "Favoritalbummer",
|
||||
"HeaderFavoriteArtists": "Favoritkunstnere",
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
"NameInstallFailed": "{0} instalado fiaskis",
|
||||
"Music": "Muziko",
|
||||
"Movies": "Filmoj",
|
||||
"ItemRemovedWithName": "{0} forigis el la libraro",
|
||||
"ItemAddedWithName": "{0} aldonis al la libraro",
|
||||
"ItemRemovedWithName": "{0} forigis el la plurmediteko",
|
||||
"ItemAddedWithName": "{0} aldonis al la plurmediteko",
|
||||
"HeaderLiveTV": "TV-etero",
|
||||
"HeaderContinueWatching": "Daŭrigi Spektadon",
|
||||
"HeaderAlbumArtists": "Albumo de artisto",
|
||||
@@ -23,7 +23,7 @@
|
||||
"Application": "Aplikaĵo",
|
||||
"AppDeviceValues": "Aplikaĵo: {0}, Aparato: {1}",
|
||||
"Albums": "Albumoj",
|
||||
"TasksLibraryCategory": "Libraro",
|
||||
"TasksLibraryCategory": "Plurmediteko",
|
||||
"VersionNumber": "Versio {0}",
|
||||
"UserDownloadingItemWithValues": "{0} elŝutas {1}",
|
||||
"UserCreatedWithName": "Uzanto {0} kreiĝis",
|
||||
@@ -50,7 +50,7 @@
|
||||
"TvShows": "TV-serioj",
|
||||
"Favorites": "Favoratoj",
|
||||
"TaskCleanLogs": "Purigi Ĵurnalan Katalogon",
|
||||
"TaskRefreshLibrary": "Skanu Plurmedian Libraron",
|
||||
"TaskRefreshLibrary": "Skanu Plurmeditekon",
|
||||
"ValueSpecialEpisodeName": "Speciala - {0}",
|
||||
"TaskOptimizeDatabase": "Optimigi datumbazon",
|
||||
"TaskRefreshChannels": "Refreŝigi Kanalojn",
|
||||
@@ -75,17 +75,17 @@
|
||||
"ServerNameNeedsToBeRestarted": "{0} devas esti relanĉita",
|
||||
"NotificationOptionVideoPlayback": "La videoludado lanĉis",
|
||||
"NotificationOptionServerRestartRequired": "Servila relanĉigo bezonata",
|
||||
"TaskOptimizeDatabaseDescription": "Kompaktigas datenbazon kaj trunkas liberan lokon. Lanĉi ĉi tiun taskon post la librara skanado aŭ fari aliajn ŝanĝojn, kiuj implicas datenbazajn modifojn, povus plibonigi rendimenton.",
|
||||
"TaskOptimizeDatabaseDescription": "Kompaktigas datenbazon kaj trunkas liberan lokon. Lanĉi ĉi tiun taskon post la teka skanado aŭ fari aliajn ŝanĝojn, kiuj implicas datenbazajn modifojn, povus plibonigi rendimenton.",
|
||||
"TaskUpdatePluginsDescription": "Elŝutas kaj instalas ĝisdatigojn por kromprogramojn, kiuj estas agorditaj por ĝisdatigi aŭtomate.",
|
||||
"TaskDownloadMissingSubtitlesDescription": "Serĉas en interreto mankantajn subtekstojn surbaze de metadatena agordaro.",
|
||||
"TaskRefreshPeopleDescription": "Ĝisdatigas metadatenojn por aktoroj kaj reĵisoroj en via plurmedia libraro.",
|
||||
"TaskRefreshPeopleDescription": "Ĝisdatigas metadatenojn por aktoroj kaj reĵisoroj en via plurmediteko.",
|
||||
"TaskCleanLogsDescription": "Forigas ĵurnalajn dosierojn aĝajn pli ol {0} tagojn.",
|
||||
"TaskRefreshLibraryDescription": "Skanas vian plurmedian libraron por novaj dosieroj kaj refreŝigas metadatenaron.",
|
||||
"TaskRefreshLibraryDescription": "Skanas vian plurmeditekon por novaj dosieroj kaj refreŝigas metadatenaron.",
|
||||
"NewVersionIsAvailable": "Nova versio de Jellyfin Server estas elŝutebla.",
|
||||
"TaskCleanCacheDescription": "Forigas stapla dosierojn ne plu necesajn de la sistemo.",
|
||||
"TaskCleanActivityLogDescription": "Forigas aktivecan ĵurnalaĵojn pli malnovajn ol la agordita aĝo.",
|
||||
"TaskCleanTranscodeDescription": "Forigas transkodajn dosierojn aĝajn pli ol unu tagon.",
|
||||
"ValueHasBeenAddedToLibrary": "{0} estis aldonita al via plurmedia libraro",
|
||||
"ValueHasBeenAddedToLibrary": "{0} estis aldonita al via plurmediteko",
|
||||
"SubtitleDownloadFailureFromForItem": "Subtekstoj malsukcesis elŝuti de {0} por {1}",
|
||||
"StartupEmbyServerIsLoading": "Jellyfin Server ŝarĝas. Provi denove baldaŭ.",
|
||||
"TaskRefreshChapterImagesDescription": "Kreas bildetojn por videoj kiuj havas ĉapitrojn.",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"Albums": "Albums",
|
||||
"AppDeviceValues": "Application : {0}, Appareil : {1}",
|
||||
"Application": "Application",
|
||||
"Application": "Applications",
|
||||
"Artists": "Artistes",
|
||||
"AuthenticationSucceededWithUserName": "{0} authentifié avec succès",
|
||||
"Books": "Livres",
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
"MixedContent": "Conteúdo Misto",
|
||||
"Movies": "Filmes",
|
||||
"Music": "Música",
|
||||
"MusicVideos": "Videoclips",
|
||||
"MusicVideos": "Videoclipes",
|
||||
"NameInstallFailed": "{0} falha na instalação",
|
||||
"NameSeasonNumber": "Temporada {0}",
|
||||
"NameSeasonUnknown": "Temporada Desconhecida",
|
||||
@@ -118,5 +118,7 @@
|
||||
"TaskCleanActivityLog": "Limpar registo de atividade",
|
||||
"Undefined": "Indefinido",
|
||||
"Forced": "Forçado",
|
||||
"Default": "Padrão"
|
||||
"Default": "Padrão",
|
||||
"TaskOptimizeDatabaseDescription": "Base de dados compacta e corta espaço livre. A execução desta tarefa depois de digitalizar a biblioteca ou de fazer outras alterações que impliquem modificações na base de dados pode melhorar o desempenho.",
|
||||
"TaskOptimizeDatabase": "Otimizar base de dados"
|
||||
}
|
||||
|
||||
@@ -372,9 +372,11 @@ namespace Emby.Server.Implementations.Localization
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<LocalizationOption> GetLocalizationOptions()
|
||||
{
|
||||
yield return new LocalizationOption("Afrikaans", "af");
|
||||
yield return new LocalizationOption("Arabic", "ar");
|
||||
yield return new LocalizationOption("Bulgarian (Bulgaria)", "bg-BG");
|
||||
yield return new LocalizationOption("Catalan", "ca");
|
||||
yield return new LocalizationOption("Chinese (Hong Kong)", "zh-HK");
|
||||
yield return new LocalizationOption("Chinese Simplified", "zh-CN");
|
||||
yield return new LocalizationOption("Chinese Traditional", "zh-TW");
|
||||
yield return new LocalizationOption("Croatian", "hr");
|
||||
@@ -383,32 +385,48 @@ namespace Emby.Server.Implementations.Localization
|
||||
yield return new LocalizationOption("Dutch", "nl");
|
||||
yield return new LocalizationOption("English (United Kingdom)", "en-GB");
|
||||
yield return new LocalizationOption("English (United States)", "en-US");
|
||||
yield return new LocalizationOption("Esperanto", "eo");
|
||||
yield return new LocalizationOption("Estonian", "et");
|
||||
yield return new LocalizationOption("Finnish", "fi");
|
||||
yield return new LocalizationOption("French", "fr");
|
||||
yield return new LocalizationOption("French (Canada)", "fr-CA");
|
||||
yield return new LocalizationOption("German", "de");
|
||||
yield return new LocalizationOption("Greek", "el");
|
||||
yield return new LocalizationOption("Hebrew", "he");
|
||||
yield return new LocalizationOption("Hungarian", "hu");
|
||||
yield return new LocalizationOption("Icelandic", "is");
|
||||
yield return new LocalizationOption("Indonesian", "id");
|
||||
yield return new LocalizationOption("Italian", "it");
|
||||
yield return new LocalizationOption("Japanese", "ja");
|
||||
yield return new LocalizationOption("Kazakh", "kk");
|
||||
yield return new LocalizationOption("Korean", "ko");
|
||||
yield return new LocalizationOption("Latvian", "lv");
|
||||
yield return new LocalizationOption("Lithuanian", "lt-LT");
|
||||
yield return new LocalizationOption("Malay", "ms");
|
||||
yield return new LocalizationOption("Malayalam", "ml");
|
||||
yield return new LocalizationOption("Norwegian Bokmål", "nb");
|
||||
yield return new LocalizationOption("Norwegian Nynorsk", "nn");
|
||||
yield return new LocalizationOption("Persian", "fa");
|
||||
yield return new LocalizationOption("Polish", "pl");
|
||||
yield return new LocalizationOption("Portuguese", "pt");
|
||||
yield return new LocalizationOption("Portuguese (Brazil)", "pt-BR");
|
||||
yield return new LocalizationOption("Portuguese (Portugal)", "pt-PT");
|
||||
yield return new LocalizationOption("Romanian", "ro");
|
||||
yield return new LocalizationOption("Russian", "ru");
|
||||
yield return new LocalizationOption("Serbian", "sr");
|
||||
yield return new LocalizationOption("Slovak", "sk");
|
||||
yield return new LocalizationOption("Slovenian (Slovenia)", "sl-SI");
|
||||
yield return new LocalizationOption("Spanish", "es");
|
||||
yield return new LocalizationOption("Spanish (Argentina)", "es-AR");
|
||||
yield return new LocalizationOption("Spanish (Latin America)", "es-419");
|
||||
yield return new LocalizationOption("Spanish (Mexico)", "es-MX");
|
||||
yield return new LocalizationOption("Swedish", "sv");
|
||||
yield return new LocalizationOption("Swiss German", "gsw");
|
||||
yield return new LocalizationOption("Tamil", "ta");
|
||||
yield return new LocalizationOption("Telugu", "te");
|
||||
yield return new LocalizationOption("Turkish", "tr");
|
||||
yield return new LocalizationOption("Tiếng Việt", "vi");
|
||||
yield return new LocalizationOption("Ukrainian", "uk");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user