diff options
26 files changed, 145 insertions, 83 deletions
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 51cbad360..fa32c1c0e 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -27,11 +27,11 @@ jobs: dotnet-version: '7.0.x' - name: Initialize CodeQL - uses: github/codeql-action/init@46ed16ded91731b2df79a2893d3aea8e9f03b5c4 # v2.20.3 + uses: github/codeql-action/init@0ba4244466797eb048eb91a6cd43d5c03ca8bd05 # v2.21.2 with: languages: ${{ matrix.language }} queries: +security-extended - name: Autobuild - uses: github/codeql-action/autobuild@46ed16ded91731b2df79a2893d3aea8e9f03b5c4 # v2.20.3 + uses: github/codeql-action/autobuild@0ba4244466797eb048eb91a6cd43d5c03ca8bd05 # v2.21.2 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@46ed16ded91731b2df79a2893d3aea8e9f03b5c4 # v2.20.3 + uses: github/codeql-action/analyze@0ba4244466797eb048eb91a6cd43d5c03ca8bd05 # v2.21.2 diff --git a/Directory.Packages.props b/Directory.Packages.props index 0bd7b6e9c..de347f3a0 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -10,8 +10,8 @@ <PackageVersion Include="AutoFixture.Xunit2" Version="4.18.0" /> <PackageVersion Include="AutoFixture" Version="4.18.0" /> <PackageVersion Include="BDInfo" Version="0.7.6.2" /> - <PackageVersion Include="BlurHashSharp.SkiaSharp" Version="1.2.0" /> - <PackageVersion Include="BlurHashSharp" Version="1.2.0" /> + <PackageVersion Include="BlurHashSharp.SkiaSharp" Version="1.3.0" /> + <PackageVersion Include="BlurHashSharp" Version="1.3.0" /> <PackageVersion Include="CommandLineParser" Version="2.9.1" /> <PackageVersion Include="coverlet.collector" Version="6.0.0" /> <PackageVersion Include="Diacritics" Version="3.3.18" /> @@ -23,14 +23,14 @@ <PackageVersion Include="libse" Version="3.6.13" /> <PackageVersion Include="LrcParser" Version="2023.524.0" /> <PackageVersion Include="MetaBrainz.MusicBrainz" Version="5.0.0" /> - <PackageVersion Include="Microsoft.AspNetCore.Authorization" Version="7.0.8" /> + <PackageVersion Include="Microsoft.AspNetCore.Authorization" Version="7.0.9" /> <PackageVersion Include="Microsoft.AspNetCore.HttpOverrides" Version="2.2.0" /> - <PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="7.0.8" /> + <PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="7.0.9" /> <PackageVersion Include="Microsoft.CodeAnalysis.BannedApiAnalyzers" Version="3.3.4" /> - <PackageVersion Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.8" /> - <PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="7.0.8" /> - <PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.8" /> - <PackageVersion Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.8" /> + <PackageVersion Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.9" /> + <PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="7.0.9" /> + <PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.9" /> + <PackageVersion Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.9" /> <PackageVersion Include="Microsoft.Extensions.Caching.Abstractions" Version="7.0.0" /> <PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="7.0.0" /> <PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="7.0.0" /> @@ -39,8 +39,8 @@ <PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" /> <PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="7.0.0" /> <PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" /> - <PackageVersion Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="7.0.8" /> - <PackageVersion Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="7.0.8" /> + <PackageVersion Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="7.0.9" /> + <PackageVersion Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="7.0.9" /> <PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="7.0.0" /> <PackageVersion Include="Microsoft.Extensions.Http" Version="7.0.0" /> <PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="7.0.1" /> @@ -54,16 +54,16 @@ <PackageVersion Include="NEbml" Version="0.11.0" /> <PackageVersion Include="Newtonsoft.Json" Version="13.0.3" /> <PackageVersion Include="PlaylistsNET" Version="1.4.0" /> - <PackageVersion Include="prometheus-net.AspNetCore" Version="8.0.0" /> + <PackageVersion Include="prometheus-net.AspNetCore" Version="8.0.1" /> <PackageVersion Include="prometheus-net.DotNetRuntime" Version="4.4.0" /> - <PackageVersion Include="prometheus-net" Version="8.0.0" /> + <PackageVersion Include="prometheus-net" Version="8.0.1" /> <PackageVersion Include="Serilog.AspNetCore" Version="7.0.0" /> <PackageVersion Include="Serilog.Enrichers.Thread" Version="3.1.0" /> <PackageVersion Include="Serilog.Settings.Configuration" Version="7.0.0" /> <PackageVersion Include="Serilog.Sinks.Async" Version="1.5.0" /> <PackageVersion Include="Serilog.Sinks.Console" Version="4.1.0" /> <PackageVersion Include="Serilog.Sinks.File" Version="5.0.0" /> - <PackageVersion Include="Serilog.Sinks.Graylog" Version="3.0.1" /> + <PackageVersion Include="Serilog.Sinks.Graylog" Version="3.0.2" /> <PackageVersion Include="SerilogAnalyzer" Version="0.15.0" /> <PackageVersion Include="SharpFuzz" Version="2.1.1" /> <PackageVersion Include="SkiaSharp.NativeAssets.Linux" Version="2.88.3" /> @@ -86,7 +86,7 @@ <PackageVersion Include="TMDbLib" Version="2.0.0" /> <PackageVersion Include="UTF.Unknown" Version="2.5.1" /> <PackageVersion Include="Xunit.Priority" Version="1.1.6" /> - <PackageVersion Include="xunit.runner.visualstudio" Version="2.4.5" /> + <PackageVersion Include="xunit.runner.visualstudio" Version="2.5.0" /> <PackageVersion Include="Xunit.SkippableFact" Version="1.4.13" /> <PackageVersion Include="xunit" Version="2.4.2" /> </ItemGroup> diff --git a/Emby.Dlna/PlayTo/DlnaHttpClient.cs b/Emby.Dlna/PlayTo/DlnaHttpClient.cs index 8454c1afd..220aa1a8d 100644 --- a/Emby.Dlna/PlayTo/DlnaHttpClient.cs +++ b/Emby.Dlna/PlayTo/DlnaHttpClient.cs @@ -57,6 +57,7 @@ namespace Emby.Dlna.PlayTo response.EnsureSuccessStatusCode(); await using MemoryStream ms = new MemoryStream(); await response.Content.CopyToAsync(ms, cancellationToken).ConfigureAwait(false); + ms.Position = 0; try { return await XDocument.LoadAsync( diff --git a/Emby.Server.Implementations/Localization/Core/ar.json b/Emby.Server.Implementations/Localization/Core/ar.json index 93d50e6e3..0e27dafe1 100644 --- a/Emby.Server.Implementations/Localization/Core/ar.json +++ b/Emby.Server.Implementations/Localization/Core/ar.json @@ -16,7 +16,7 @@ "Folders": "المجلدات", "Genres": "التصنيفات", "HeaderAlbumArtists": "فناني الألبوم", - "HeaderContinueWatching": "استئناف المشاهدة", + "HeaderContinueWatching": "أستئناف المشاهدة", "HeaderFavoriteAlbums": "الألبومات المفضلة", "HeaderFavoriteArtists": "الفنانون المفضلون", "HeaderFavoriteEpisodes": "الحلقات المفضلة", diff --git a/Emby.Server.Implementations/Localization/Core/he.json b/Emby.Server.Implementations/Localization/Core/he.json index 694a3d688..68e9fe833 100644 --- a/Emby.Server.Implementations/Localization/Core/he.json +++ b/Emby.Server.Implementations/Localization/Core/he.json @@ -5,18 +5,18 @@ "Artists": "אומנים", "AuthenticationSucceededWithUserName": "{0} אומת בהצלחה", "Books": "ספרים", - "CameraImageUploadedFrom": "תמונת מצלמה חדשה הועלתה מ {0}", + "CameraImageUploadedFrom": "תמונת מצלמה חדשה הועלתה מתוך {0}", "Channels": "ערוצים", "ChapterNameValue": "פרק {0}", "Collections": "אוספים", "DeviceOfflineWithName": "{0} התנתק", "DeviceOnlineWithName": "{0} מחובר", - "FailedLoginAttemptWithUserName": "ניסיון כניסה שגוי מ{0}", + "FailedLoginAttemptWithUserName": "ניסיון כניסה שגוי דרך {0}", "Favorites": "מועדפים", "Folders": "תיקיות", - "Genres": "ז'אנרים", + "Genres": "ז׳אנרים", "HeaderAlbumArtists": "אמני האלבום", - "HeaderContinueWatching": "המשך לצפות", + "HeaderContinueWatching": "להמשיך לצפות", "HeaderFavoriteAlbums": "אלבומים מועדפים", "HeaderFavoriteArtists": "אמנים מועדפים", "HeaderFavoriteEpisodes": "פרקים מועדפים", @@ -27,14 +27,14 @@ "HeaderRecordingGroups": "קבוצות הקלטה", "HomeVideos": "סרטונים בייתים", "Inherit": "הורש", - "ItemAddedWithName": "{0} הוסף לספרייה", + "ItemAddedWithName": "{0} נוסף לספרייה", "ItemRemovedWithName": "{0} נמחק מהספרייה", "LabelIpAddressValue": "Ip כתובת: {0}", "LabelRunningTimeValue": "משך צפייה: {0}", "Latest": "אחרון", "MessageApplicationUpdated": "שרת הJellyfin עודכן", - "MessageApplicationUpdatedTo": "שרת הJellyfin עודכן לגרסא {0}", - "MessageNamedServerConfigurationUpdatedWithValue": "הגדרת השרת {0} שונתה", + "MessageApplicationUpdatedTo": "שרת ה־Jellyfin עודכן לגרסה {0}", + "MessageNamedServerConfigurationUpdatedWithValue": "סעיף הגדרת השרת {0} עודכן", "MessageServerConfigurationUpdated": "תצורת השרת עודכנה", "MixedContent": "תוכן מעורב", "Movies": "סרטים", @@ -50,7 +50,7 @@ "NotificationOptionAudioPlaybackStopped": "ניגון שמע הופסק", "NotificationOptionCameraImageUploaded": "תמונת מצלמה הועלתה", "NotificationOptionInstallationFailed": "התקנה נכשלה", - "NotificationOptionNewLibraryContent": "תוכן חדש הוסף", + "NotificationOptionNewLibraryContent": "תוכן חדש נוסף", "NotificationOptionPluginError": "כשלון בתוסף", "NotificationOptionPluginInstalled": "התוסף הותקן", "NotificationOptionPluginUninstalled": "התוסף הוסר", @@ -61,41 +61,41 @@ "NotificationOptionVideoPlayback": "ניגון וידאו החל", "NotificationOptionVideoPlaybackStopped": "ניגון וידאו הופסק", "Photos": "תמונות", - "Playlists": "רשימות הפעלה", - "Plugin": "Plugin", + "Playlists": "רשימות נגינה", + "Plugin": "תוסף", "PluginInstalledWithName": "{0} הותקן", "PluginUninstalledWithName": "{0} הוסר", "PluginUpdatedWithName": "{0} עודכן", - "ProviderValue": "Provider: {0}", + "ProviderValue": "ספק: {0}", "ScheduledTaskFailedWithName": "{0} נכשל", "ScheduledTaskStartedWithName": "{0} החל", "ServerNameNeedsToBeRestarted": "{0} דורש הפעלה מחדש", "Shows": "סדרות", "Songs": "שירים", - "StartupEmbyServerIsLoading": "שרת Jellyfin בהליכי טעינה. אנא נסה שנית בעוד זמן קצר.", + "StartupEmbyServerIsLoading": "שרת Jellyfin בהליכי טעינה. נא לנסות שנית בהקדם.", "SubtitleDownloadFailureForItem": "Subtitles failed to download for {0}", - "SubtitleDownloadFailureFromForItem": "הורדת כתוביות נכשלה מ-{0} עבור {1}", - "Sync": "סנכרן", - "System": "System", + "SubtitleDownloadFailureFromForItem": "הורדת כתוביות מ־{0} עבור {1} נכשלה", + "Sync": "סנכרון", + "System": "מערכת", "TvShows": "סדרות טלוויזיה", - "User": "User", + "User": "משתמש", "UserCreatedWithName": "המשתמש {0} נוצר", "UserDeletedWithName": "המשתמש {0} הוסר", "UserDownloadingItemWithValues": "{0} מוריד את {1}", "UserLockedOutWithName": "המשתמש {0} ננעל", - "UserOfflineFromDevice": "{0} התנתק מ-{1}", - "UserOnlineFromDevice": "{0} מחובר מ-{1}", + "UserOfflineFromDevice": "{0} התנתק מ־{1}", + "UserOnlineFromDevice": "{0} מחובר מ־{1}", "UserPasswordChangedWithName": "הסיסמה שונתה עבור המשתמש {0}", "UserPolicyUpdatedWithName": "מדיניות המשתמש {0} עודכנה", "UserStartedPlayingItemWithValues": "{0} מנגן את {1} על {2}", "UserStoppedPlayingItemWithValues": "{0} סיים לנגן את {1} על {2}", "ValueHasBeenAddedToLibrary": "{0} התווסף לספריית המדיה שלך", "ValueSpecialEpisodeName": "מיוחד- {0}", - "VersionNumber": "Version {0}", + "VersionNumber": "גרסה {0}", "TaskRefreshLibrary": "סרוק ספריית מדיה", "TaskRefreshChapterImages": "חלץ תמונות פרקים", "TaskCleanCacheDescription": "מחק קבצי מטמון שלא בשימוש המערכת.", - "TaskCleanCache": "נקה תיקיית מטמון", + "TaskCleanCache": "ניקוי תיקיית מטמון", "TasksApplicationCategory": "יישום", "TasksLibraryCategory": "ספרייה", "TasksMaintenanceCategory": "תחזוקה", @@ -103,7 +103,7 @@ "TaskRefreshPeopleDescription": "מעדכן מטא נתונים עבור שחקנים ובמאים בספריית המדיה שלך.", "TaskRefreshPeople": "רענן אנשים", "TaskCleanLogsDescription": "מוחק קבצי יומן בני יותר מ- {0} ימים.", - "TaskCleanLogs": "נקה תיקיית יומן", + "TaskCleanLogs": "ניקוי תיקיית יומן", "TaskRefreshLibraryDescription": "סורק את ספריית המדיה שלך אחר קבצים חדשים ומרענן מטא נתונים.", "TaskRefreshChapterImagesDescription": "יוצר תמונות ממוזערות לסרטונים שיש להם פרקים.", "TasksChannelsCategory": "ערוצי אינטרנט", diff --git a/Emby.Server.Implementations/Localization/Core/ta.json b/Emby.Server.Implementations/Localization/Core/ta.json index dfce6bd25..770624a8d 100644 --- a/Emby.Server.Implementations/Localization/Core/ta.json +++ b/Emby.Server.Implementations/Localization/Core/ta.json @@ -122,5 +122,6 @@ "TaskOptimizeDatabase": "தரவுத்தளத்தை மேம்படுத்தவும்", "TaskKeyframeExtractorDescription": "மிகவும் துல்லியமான HLS பிளேலிஸ்ட்களை உருவாக்க வீடியோ கோப்புகளிலிருந்து கீஃப்ரேம்களைப் பிரித்தெடுக்கிறது. இந்த பணி நீண்ட காலமாக இருக்கலாம்.", "TaskKeyframeExtractor": "கீஃப்ரேம் எக்ஸ்ட்ராக்டர்", - "External": "வெளி" + "External": "வெளி", + "HearingImpaired": "செவித்திறன் குறைபாடுடையவர்" } diff --git a/Emby.Server.Implementations/Localization/Core/th.json b/Emby.Server.Implementations/Localization/Core/th.json index 1a4fef64e..3cdf743d5 100644 --- a/Emby.Server.Implementations/Localization/Core/th.json +++ b/Emby.Server.Implementations/Localization/Core/th.json @@ -121,5 +121,7 @@ "TaskOptimizeDatabase": "ปรับปรุงประสิทธิภาพฐานข้อมูล", "TaskOptimizeDatabaseDescription": "ลดขนาดการจัดเก็บฐานข้อมูล ใช้งานคำสั่งนี้หลังจากสแกนไลบรารีหรือหลังจากการเปลี่ยนแปลงฐานข้อมูล อาจจะทำให้ระบบทำงานเร็วขึ้น", "External": "ภายนอก", - "HearingImpaired": "บกพร่องทางการได้ยิน" + "HearingImpaired": "บกพร่องทางการได้ยิน", + "TaskKeyframeExtractor": "ตัวแยกคีย์เฟรม", + "TaskKeyframeExtractorDescription": "แยกคีย์เฟรมจากไฟล์วีดีโอเพื่อสร้างรายการ HLS ให้ถูกต้อง. กระบวนการนี้อาจใช้ระยะเวลานาน" } diff --git a/Emby.Server.Implementations/Localization/Ratings/au.csv b/Emby.Server.Implementations/Localization/Ratings/au.csv index 4ab808ae9..688125917 100644 --- a/Emby.Server.Implementations/Localization/Ratings/au.csv +++ b/Emby.Server.Implementations/Localization/Ratings/au.csv @@ -4,10 +4,14 @@ G,0 M,15 MA,15 MA15+,15 +MA 15+,15 PG,16 16+,16 R,18 R18+,18 -X18+,18 +R 18+,18 18+,18 +X18+,1000 +X 18+,1000 X,1000 +RC,1001 diff --git a/Emby.Server.Implementations/Localization/Ratings/de.csv b/Emby.Server.Implementations/Localization/Ratings/de.csv index d633a5dab..f6181575e 100644 --- a/Emby.Server.Implementations/Localization/Ratings/de.csv +++ b/Emby.Server.Implementations/Localization/Ratings/de.csv @@ -1,12 +1,17 @@ Educational,0 Infoprogramm,0 FSK-0,0 +FSK 0,0 0,0 FSK-6,6 +FSK 6,6 6,6 FSK-12,12 +FSK 12,12 12,12 FSK-16,16 +FSK 16,16 16,16 FSK-18,18 +FSK 18,18 18,18 diff --git a/Jellyfin.Api/Controllers/SubtitleController.cs b/Jellyfin.Api/Controllers/SubtitleController.cs index b3e9d6297..7d02550b6 100644 --- a/Jellyfin.Api/Controllers/SubtitleController.cs +++ b/Jellyfin.Api/Controllers/SubtitleController.cs @@ -90,7 +90,7 @@ public class SubtitleController : BaseJellyfinApiController [Authorize(Policy = Policies.RequiresElevation)] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public ActionResult<Task> DeleteSubtitle( + public async Task<ActionResult> DeleteSubtitle( [FromRoute, Required] Guid itemId, [FromRoute, Required] int index) { @@ -101,7 +101,7 @@ public class SubtitleController : BaseJellyfinApiController return NotFound(); } - _subtitleManager.DeleteSubtitles(item, index); + await _subtitleManager.DeleteSubtitles(item, index).ConfigureAwait(false); return NoContent(); } @@ -416,6 +416,7 @@ public class SubtitleController : BaseJellyfinApiController Format = body.Format, Language = body.Language, IsForced = body.IsForced, + IsHearingImpaired = body.IsHearingImpaired, Stream = memoryStream }).ConfigureAwait(false); _providerManager.QueueRefresh(video.Id, new MetadataRefreshOptions(new DirectoryService(_fileSystem)), RefreshPriority.High); diff --git a/Jellyfin.Api/Controllers/UserController.cs b/Jellyfin.Api/Controllers/UserController.cs index 4f61af35e..1be40111d 100644 --- a/Jellyfin.Api/Controllers/UserController.cs +++ b/Jellyfin.Api/Controllers/UserController.cs @@ -494,7 +494,7 @@ public class UserController : BaseJellyfinApiController var isLocal = HttpContext.IsLocal() || _networkManager.IsInLocalNetwork(ip); - if (isLocal) + if (!isLocal) { _logger.LogWarning("Password reset process initiated from outside the local network with IP: {IP}", ip); } diff --git a/Jellyfin.Api/Models/SubtitleDtos/UploadSubtitleDto.cs b/Jellyfin.Api/Models/SubtitleDtos/UploadSubtitleDto.cs index 3c903ea6b..2c45e704b 100644 --- a/Jellyfin.Api/Models/SubtitleDtos/UploadSubtitleDto.cs +++ b/Jellyfin.Api/Models/SubtitleDtos/UploadSubtitleDto.cs @@ -26,6 +26,12 @@ public class UploadSubtitleDto public bool IsForced { get; set; } /// <summary> + /// Gets or sets a value indicating whether the subtitle is for hearing impaired. + /// </summary> + [Required] + public bool IsHearingImpaired { get; set; } + + /// <summary> /// Gets or sets the subtitle data. /// </summary> [Required] diff --git a/Jellyfin.Server/Migrations/MigrationRunner.cs b/Jellyfin.Server/Migrations/MigrationRunner.cs index 33c02f41c..2db0b77cd 100644 --- a/Jellyfin.Server/Migrations/MigrationRunner.cs +++ b/Jellyfin.Server/Migrations/MigrationRunner.cs @@ -93,7 +93,7 @@ namespace Jellyfin.Server.Migrations private static void HandleStartupWizardCondition(IEnumerable<IMigrationRoutine> migrations, MigrationOptions migrationOptions, bool isStartWizardCompleted, ILogger logger) { - if (isStartWizardCompleted || migrationOptions.Applied.Count != 0) + if (isStartWizardCompleted) { return; } @@ -106,6 +106,8 @@ namespace Jellyfin.Server.Migrations private static void PerformMigrations(IMigrationRoutine[] migrations, MigrationOptions migrationOptions, Action<MigrationOptions> saveConfiguration, ILogger logger) { + // save already applied migrations, and skip them thereafter + saveConfiguration(migrationOptions); var appliedMigrationIds = migrationOptions.Applied.Select(m => m.Id).ToHashSet(); for (var i = 0; i < migrations.Length; i++) diff --git a/Jellyfin.Server/Migrations/PreStartupRoutines/MigrateNetworkConfiguration.cs b/Jellyfin.Server/Migrations/PreStartupRoutines/MigrateNetworkConfiguration.cs index 3b32e6043..a4379197c 100644 --- a/Jellyfin.Server/Migrations/PreStartupRoutines/MigrateNetworkConfiguration.cs +++ b/Jellyfin.Server/Migrations/PreStartupRoutines/MigrateNetworkConfiguration.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; using System.Xml; using System.Xml.Serialization; @@ -39,8 +39,23 @@ public class MigrateNetworkConfiguration : IMigrationRoutine { string path = Path.Combine(_applicationPaths.ConfigurationDirectoryPath, "network.xml"); var oldNetworkConfigSerializer = new XmlSerializer(typeof(OldNetworkConfiguration), new XmlRootAttribute("NetworkConfiguration")); - using var xmlReader = XmlReader.Create(path); - var oldNetworkConfiguration = (OldNetworkConfiguration?)oldNetworkConfigSerializer.Deserialize(xmlReader); + OldNetworkConfiguration? oldNetworkConfiguration = null; + + try + { + using (var xmlReader = XmlReader.Create(path)) + { + oldNetworkConfiguration = (OldNetworkConfiguration?)oldNetworkConfigSerializer.Deserialize(xmlReader); + } + } + catch (InvalidOperationException ex) + { + _logger.LogError(ex, "Migrate NetworkConfiguration deserialize Invalid Operation error"); + } + catch (Exception ex) + { + _logger.LogError(ex, "Migrate NetworkConfiguration deserialize error"); + } if (oldNetworkConfiguration is not null) { @@ -82,8 +97,10 @@ public class MigrateNetworkConfiguration : IMigrationRoutine var networkConfigSerializer = new XmlSerializer(typeof(NetworkConfiguration)); var xmlWriterSettings = new XmlWriterSettings { Indent = true }; - using var xmlWriter = XmlWriter.Create(path, xmlWriterSettings); - networkConfigSerializer.Serialize(xmlWriter, networkConfiguration); + using (var xmlWriter = XmlWriter.Create(path, xmlWriterSettings)) + { + networkConfigSerializer.Serialize(xmlWriter, networkConfiguration); + } } } diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 750713694..a702e1003 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -1457,8 +1457,8 @@ namespace MediaBrowser.Controller.MediaEncoding args += keyFrameArg + gopArg; } - // global_header produced by AMD VA-API encoder causes non-playable fMP4 on iOS - if (codec.Contains("vaapi", StringComparison.OrdinalIgnoreCase) + // global_header produced by AMD HEVC VA-API encoder causes non-playable fMP4 on iOS + if (string.Equals(codec, "hevc_vaapi", StringComparison.OrdinalIgnoreCase) && _mediaEncoder.IsVaapiDeviceAmd) { args += " -flags:v -global_header"; diff --git a/MediaBrowser.Controller/Subtitles/SubtitleResponse.cs b/MediaBrowser.Controller/Subtitles/SubtitleResponse.cs index 85b3e6fbd..51c29c7a2 100644 --- a/MediaBrowser.Controller/Subtitles/SubtitleResponse.cs +++ b/MediaBrowser.Controller/Subtitles/SubtitleResponse.cs @@ -14,6 +14,8 @@ namespace MediaBrowser.Controller.Subtitles public bool IsForced { get; set; } + public bool IsHearingImpaired { get; set; } + public Stream Stream { get; set; } } } diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs index 7d655240b..aeb08cea3 100644 --- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs +++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs @@ -1,5 +1,4 @@ #nullable disable -#pragma warning disable CS1591 using System; using System.Collections.Generic; @@ -20,6 +19,9 @@ using Microsoft.Extensions.Logging; namespace MediaBrowser.MediaEncoding.Probing { + /// <summary> + /// Class responsible for normalizing FFprobe output. + /// </summary> public class ProbeResultNormalizer { // When extracting subtitles, the maximum length to consider (to avoid invalid filenames) @@ -36,6 +38,11 @@ namespace MediaBrowser.MediaEncoding.Probing private string[] _splitWhiteList; + /// <summary> + /// Initializes a new instance of the <see cref="ProbeResultNormalizer"/> class. + /// </summary> + /// <param name="logger">The <see cref="ILogger{ProbeResultNormalizer}"/> for use with the <see cref="ProbeResultNormalizer"/> instance.</param> + /// <param name="localization">The <see cref="ILocalizationManager"/> for use with the <see cref="ProbeResultNormalizer"/> instance.</param> public ProbeResultNormalizer(ILogger logger, ILocalizationManager localization) { _logger = logger; @@ -73,6 +80,15 @@ namespace MediaBrowser.MediaEncoding.Probing "Smith/Kotzen", }; + /// <summary> + /// Transforms a FFprobe response into its <see cref="MediaInfo"/> equivalent. + /// </summary> + /// <param name="data">The <see cref="InternalMediaInfoResult"/>.</param> + /// <param name="videoType">The <see cref="VideoType"/>.</param> + /// <param name="isAudio">A boolean indicating whether the media is audio.</param> + /// <param name="path">Path to media file.</param> + /// <param name="protocol">Path media protocol.</param> + /// <returns>The <see cref="MediaInfo"/>.</returns> public MediaInfo GetMediaInfo(InternalMediaInfoResult data, VideoType? videoType, bool isAudio, string path, MediaProtocol protocol) { var info = new MediaInfo @@ -252,25 +268,30 @@ namespace MediaBrowser.MediaEncoding.Probing return null; } - // Handle MPEG-1 container - if (string.Equals(format, "mpegvideo", StringComparison.OrdinalIgnoreCase)) + // Input can be a list of multiple, comma-delimited formats - each of them needs to be checked + var splitFormat = format.Split(','); + for (var i = 0; i < splitFormat.Length; i++) { - return "mpeg"; - } + // Handle MPEG-1 container + if (string.Equals(splitFormat[i], "mpegvideo", StringComparison.OrdinalIgnoreCase)) + { + splitFormat[i] = "mpeg"; + } - // Handle MPEG-2 container - if (string.Equals(format, "mpeg", StringComparison.OrdinalIgnoreCase)) - { - return "ts"; - } + // Handle MPEG-2 container + else if (string.Equals(splitFormat[i], "mpeg", StringComparison.OrdinalIgnoreCase)) + { + splitFormat[i] = "ts"; + } - // Handle matroska container - if (string.Equals(format, "matroska", StringComparison.OrdinalIgnoreCase)) - { - return "mkv"; + // Handle matroska container + else if (string.Equals(splitFormat[i], "matroska", StringComparison.OrdinalIgnoreCase)) + { + splitFormat[i] = "mkv"; + } } - return format; + return string.Join(',', splitFormat); } private int? GetEstimatedAudioBitrate(string codec, int? channels) diff --git a/MediaBrowser.Providers/Subtitles/SubtitleManager.cs b/MediaBrowser.Providers/Subtitles/SubtitleManager.cs index 0c01c5031..87fd2a3cd 100644 --- a/MediaBrowser.Providers/Subtitles/SubtitleManager.cs +++ b/MediaBrowser.Providers/Subtitles/SubtitleManager.cs @@ -200,6 +200,11 @@ namespace MediaBrowser.Providers.Subtitles saveFileName += ".forced"; } + if (response.IsHearingImpaired) + { + saveFileName += ".sdh"; + } + saveFileName += "." + response.Format.ToLowerInvariant(); if (saveInMediaFolder) diff --git a/deployment/Dockerfile.centos.amd64 b/deployment/Dockerfile.centos.amd64 index 771675519..da986a07e 100644 --- a/deployment/Dockerfile.centos.amd64 +++ b/deployment/Dockerfile.centos.amd64 @@ -13,7 +13,7 @@ RUN yum update -yq \ && yum install -yq @buildsys-build rpmdevtools yum-plugins-core libcurl-devel fontconfig-devel freetype-devel openssl-devel glibc-devel libicu-devel git wget # Install DotNET SDK -RUN wget -q https://download.visualstudio.microsoft.com/download/pr/87a55ae3-917d-449e-a4e8-776f82976e91/03380e598c326c2f9465d262c6a88c45/dotnet-sdk-7.0.305-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ +RUN wget -q https://download.visualstudio.microsoft.com/download/pr/0be7a87e-3a3f-4500-8301-49ccd6f24887/e9e36f35dbaf6625fec3e18f5c2b613f/dotnet-sdk-7.0.306-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ && mkdir -p dotnet-sdk \ && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet diff --git a/deployment/Dockerfile.fedora.amd64 b/deployment/Dockerfile.fedora.amd64 index c552f06b0..09f93d41b 100644 --- a/deployment/Dockerfile.fedora.amd64 +++ b/deployment/Dockerfile.fedora.amd64 @@ -12,7 +12,7 @@ RUN dnf update -yq \ && dnf install -yq @buildsys-build rpmdevtools git dnf-plugins-core libcurl-devel fontconfig-devel freetype-devel openssl-devel glibc-devel libicu-devel systemd wget make # Install DotNET SDK -RUN wget -q https://download.visualstudio.microsoft.com/download/pr/87a55ae3-917d-449e-a4e8-776f82976e91/03380e598c326c2f9465d262c6a88c45/dotnet-sdk-7.0.305-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ +RUN wget -q https://download.visualstudio.microsoft.com/download/pr/0be7a87e-3a3f-4500-8301-49ccd6f24887/e9e36f35dbaf6625fec3e18f5c2b613f/dotnet-sdk-7.0.306-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ && mkdir -p dotnet-sdk \ && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet diff --git a/deployment/Dockerfile.ubuntu.amd64 b/deployment/Dockerfile.ubuntu.amd64 index 30100d20d..9910773da 100644 --- a/deployment/Dockerfile.ubuntu.amd64 +++ b/deployment/Dockerfile.ubuntu.amd64 @@ -17,7 +17,7 @@ RUN apt-get update -yqq \ libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0 # Install dotnet repository -RUN wget -q https://download.visualstudio.microsoft.com/download/pr/87a55ae3-917d-449e-a4e8-776f82976e91/03380e598c326c2f9465d262c6a88c45/dotnet-sdk-7.0.305-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ +RUN wget -q https://download.visualstudio.microsoft.com/download/pr/0be7a87e-3a3f-4500-8301-49ccd6f24887/e9e36f35dbaf6625fec3e18f5c2b613f/dotnet-sdk-7.0.306-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ && mkdir -p dotnet-sdk \ && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet diff --git a/deployment/Dockerfile.ubuntu.arm64 b/deployment/Dockerfile.ubuntu.arm64 index bac2adfaf..aa69b27f4 100644 --- a/deployment/Dockerfile.ubuntu.arm64 +++ b/deployment/Dockerfile.ubuntu.arm64 @@ -16,7 +16,7 @@ RUN apt-get update -yqq \ mmv build-essential lsb-release # Install dotnet repository -RUN wget -q https://download.visualstudio.microsoft.com/download/pr/87a55ae3-917d-449e-a4e8-776f82976e91/03380e598c326c2f9465d262c6a88c45/dotnet-sdk-7.0.305-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ +RUN wget -q https://download.visualstudio.microsoft.com/download/pr/0be7a87e-3a3f-4500-8301-49ccd6f24887/e9e36f35dbaf6625fec3e18f5c2b613f/dotnet-sdk-7.0.306-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ && mkdir -p dotnet-sdk \ && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet diff --git a/deployment/Dockerfile.ubuntu.armhf b/deployment/Dockerfile.ubuntu.armhf index 37a1ed5ff..bb8597b41 100644 --- a/deployment/Dockerfile.ubuntu.armhf +++ b/deployment/Dockerfile.ubuntu.armhf @@ -16,7 +16,7 @@ RUN apt-get update -yqq \ mmv build-essential lsb-release # Install dotnet repository -RUN wget -q https://download.visualstudio.microsoft.com/download/pr/87a55ae3-917d-449e-a4e8-776f82976e91/03380e598c326c2f9465d262c6a88c45/dotnet-sdk-7.0.305-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ +RUN wget -q https://download.visualstudio.microsoft.com/download/pr/0be7a87e-3a3f-4500-8301-49ccd6f24887/e9e36f35dbaf6625fec3e18f5c2b613f/dotnet-sdk-7.0.306-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ && mkdir -p dotnet-sdk \ && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet diff --git a/tests/Jellyfin.Networking.Tests/Jellyfin.Networking.Tests.csproj b/tests/Jellyfin.Networking.Tests/Jellyfin.Networking.Tests.csproj index 4b4bdd2a5..3747db3bb 100644 --- a/tests/Jellyfin.Networking.Tests/Jellyfin.Networking.Tests.csproj +++ b/tests/Jellyfin.Networking.Tests/Jellyfin.Networking.Tests.csproj @@ -18,12 +18,7 @@ </ItemGroup> <ItemGroup> - <ProjectReference Include="../../Emby.Server.Implementations/Emby.Server.Implementations.csproj" /> - <ProjectReference Include="../../MediaBrowser.Common/MediaBrowser.Common.csproj" /> + <ProjectReference Include="../../Jellyfin.Networking/Jellyfin.Networking.csproj" /> </ItemGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> - <DefineConstants>DEBUG</DefineConstants> - </PropertyGroup> - </Project> diff --git a/tests/Jellyfin.Networking.Tests/NetworkParseTests.cs b/tests/Jellyfin.Networking.Tests/NetworkParseTests.cs index cb8092ae9..731cbbafb 100644 --- a/tests/Jellyfin.Networking.Tests/NetworkParseTests.cs +++ b/tests/Jellyfin.Networking.Tests/NetworkParseTests.cs @@ -97,7 +97,7 @@ namespace Jellyfin.Networking.Tests /// Checks if IPv4 address is within a defined subnet. /// </summary> /// <param name="netMask">Network mask.</param> - /// <param name="IPAddress">IP Address.</param> + /// <param name="ipAddress">IP Address.</param> [Theory] [InlineData("192.168.5.85/24", "192.168.5.1")] [InlineData("192.168.5.85/24", "192.168.5.254")] @@ -211,7 +211,7 @@ namespace Jellyfin.Networking.Tests if (nm.TryParseInterface(result, out var resultObj)) { - result = resultObj.First().Address.ToString(); + result = resultObj[0].Address.ToString(); var intf = nm.GetBindAddress(source, out _); Assert.Equal(intf, result); @@ -270,7 +270,7 @@ namespace Jellyfin.Networking.Tests if (nm.TryParseInterface(result, out IReadOnlyList<IPData>? resultObj) && resultObj is not null) { // Parse out IPAddresses so we can do a string comparison (ignore subnet masks). - result = resultObj.First().Address.ToString(); + result = resultObj[0].Address.ToString(); } var intf = nm.GetBindAddress(source, out int? _); diff --git a/tests/Jellyfin.Server.Implementations.Tests/Localization/LocalizationManagerTests.cs b/tests/Jellyfin.Server.Implementations.Tests/Localization/LocalizationManagerTests.cs index 7fabe9904..09e4709da 100644 --- a/tests/Jellyfin.Server.Implementations.Tests/Localization/LocalizationManagerTests.cs +++ b/tests/Jellyfin.Server.Implementations.Tests/Localization/LocalizationManagerTests.cs @@ -100,7 +100,7 @@ namespace Jellyfin.Server.Implementations.Tests.Localization await localizationManager.LoadAll(); var ratings = localizationManager.GetParentalRatings().ToList(); - Assert.Equal(19, ratings.Count); + Assert.Equal(24, ratings.Count); var fsk = ratings.FirstOrDefault(x => x.Name.Equals("FSK-12", StringComparison.Ordinal)); Assert.NotNull(fsk); |
