aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/codeql-analysis.yml6
-rw-r--r--Directory.Packages.props28
-rw-r--r--Emby.Dlna/PlayTo/DlnaHttpClient.cs1
-rw-r--r--Emby.Server.Implementations/Localization/Core/ar.json2
-rw-r--r--Emby.Server.Implementations/Localization/Core/he.json42
-rw-r--r--Emby.Server.Implementations/Localization/Core/ta.json3
-rw-r--r--Emby.Server.Implementations/Localization/Core/th.json4
-rw-r--r--Emby.Server.Implementations/Localization/Ratings/au.csv6
-rw-r--r--Emby.Server.Implementations/Localization/Ratings/de.csv5
-rw-r--r--Jellyfin.Api/Controllers/SubtitleController.cs5
-rw-r--r--Jellyfin.Api/Controllers/UserController.cs2
-rw-r--r--Jellyfin.Api/Models/SubtitleDtos/UploadSubtitleDto.cs6
-rw-r--r--Jellyfin.Server/Migrations/MigrationRunner.cs4
-rw-r--r--Jellyfin.Server/Migrations/PreStartupRoutines/MigrateNetworkConfiguration.cs27
-rw-r--r--MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs4
-rw-r--r--MediaBrowser.Controller/Subtitles/SubtitleResponse.cs2
-rw-r--r--MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs51
-rw-r--r--MediaBrowser.Providers/Subtitles/SubtitleManager.cs5
-rw-r--r--deployment/Dockerfile.centos.amd642
-rw-r--r--deployment/Dockerfile.fedora.amd642
-rw-r--r--deployment/Dockerfile.ubuntu.amd642
-rw-r--r--deployment/Dockerfile.ubuntu.arm642
-rw-r--r--deployment/Dockerfile.ubuntu.armhf2
-rw-r--r--tests/Jellyfin.Networking.Tests/Jellyfin.Networking.Tests.csproj7
-rw-r--r--tests/Jellyfin.Networking.Tests/NetworkParseTests.cs6
-rw-r--r--tests/Jellyfin.Server.Implementations.Tests/Localization/LocalizationManagerTests.cs2
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);