diff options
4 files changed, 18 insertions, 15 deletions
diff --git a/Emby.Server.Implementations/Localization/Core/pl.json b/Emby.Server.Implementations/Localization/Core/pl.json index 275bdec6e..e8a32a13e 100644 --- a/Emby.Server.Implementations/Localization/Core/pl.json +++ b/Emby.Server.Implementations/Localization/Core/pl.json @@ -15,7 +15,7 @@ "Favorites": "Ulubione", "Folders": "Foldery", "Genres": "Gatunki", - "HeaderAlbumArtists": "Wykonawcy albumów", + "HeaderAlbumArtists": "Album artysty", "HeaderContinueWatching": "Kontynuuj odtwarzanie", "HeaderFavoriteAlbums": "Ulubione albumy", "HeaderFavoriteArtists": "Ulubieni wykonawcy", @@ -25,7 +25,7 @@ "HeaderLiveTV": "Telewizja", "HeaderNextUp": "Do obejrzenia", "HeaderRecordingGroups": "Grupy nagrań", - "HomeVideos": "Nagrania prywatne", + "HomeVideos": "Nagrania domowe", "Inherit": "Dziedzicz", "ItemAddedWithName": "{0} zostało dodane do biblioteki", "ItemRemovedWithName": "{0} zostało usunięte z biblioteki", @@ -119,5 +119,6 @@ "Undefined": "Nieustalony", "Forced": "Wymuszony", "Default": "Domyślne", - "TaskOptimizeDatabase": "Optymalizuj bazę danych" + "TaskOptimizeDatabase": "Optymalizuj bazę danych", + "TaskOptimizeDatabaseDescription": "Kompaktuje bazę danych i obcina wolne miejsce. Uruchomienie tego zadania po przeskanowaniu biblioteki lub dokonaniu innych zmian, które pociągają za sobą modyfikacje bazy danych, może poprawić wydajność." } diff --git a/Emby.Server.Implementations/Localization/Core/zh-CN.json b/Emby.Server.Implementations/Localization/Core/zh-CN.json index faa9c40e2..71adc0f6e 100644 --- a/Emby.Server.Implementations/Localization/Core/zh-CN.json +++ b/Emby.Server.Implementations/Localization/Core/zh-CN.json @@ -7,7 +7,7 @@ "Books": "书籍", "CameraImageUploadedFrom": "新的相机图像已从 {0} 上传", "Channels": "频道", - "ChapterNameValue": "第 {0} 集", + "ChapterNameValue": "章节 {0}", "Collections": "合集", "DeviceOfflineWithName": "{0} 已断开", "DeviceOnlineWithName": "{0} 已连接", @@ -108,8 +108,8 @@ "TaskCleanLogs": "清理日志目录", "TaskRefreshLibraryDescription": "扫描你的媒体库以获取新文件并刷新元数据。", "TaskRefreshLibrary": "扫描媒体库", - "TaskRefreshChapterImagesDescription": "为包含剧集的视频提取缩略图。", - "TaskRefreshChapterImages": "提取剧集图片", + "TaskRefreshChapterImagesDescription": "为包含章节的视频提取缩略图。", + "TaskRefreshChapterImages": "提取章节图片", "TaskCleanCacheDescription": "删除系统不再需要的缓存文件。", "TaskCleanCache": "清理缓存目录", "TasksApplicationCategory": "应用程序", diff --git a/Jellyfin.Api/Controllers/LiveTvController.cs b/Jellyfin.Api/Controllers/LiveTvController.cs index 24ee833ef..47ebe9f57 100644 --- a/Jellyfin.Api/Controllers/LiveTvController.cs +++ b/Jellyfin.Api/Controllers/LiveTvController.cs @@ -1172,7 +1172,7 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesVideoFile] - public async Task<ActionResult> GetLiveRecordingFile([FromRoute, Required] string recordingId) + public ActionResult GetLiveRecordingFile([FromRoute, Required] string recordingId) { var path = _liveTvManager.GetEmbyTvActiveRecordingPath(recordingId); @@ -1181,11 +1181,8 @@ namespace Jellyfin.Api.Controllers return NotFound(); } - await using var memoryStream = new MemoryStream(); - await new ProgressiveFileCopier(path, null, _transcodingJobHelper, CancellationToken.None) - .WriteToAsync(memoryStream, CancellationToken.None) - .ConfigureAwait(false); - return File(memoryStream, MimeTypes.GetMimeType(path)); + var stream = new ProgressiveFileStream(path, null, _transcodingJobHelper); + return new FileStreamResult(stream, MimeTypes.GetMimeType(path)); } /// <summary> diff --git a/Jellyfin.Api/Helpers/ProgressiveFileStream.cs b/Jellyfin.Api/Helpers/ProgressiveFileStream.cs index 824870c7e..499dbe84d 100644 --- a/Jellyfin.Api/Helpers/ProgressiveFileStream.cs +++ b/Jellyfin.Api/Helpers/ProgressiveFileStream.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; using System.Threading; @@ -16,6 +17,7 @@ namespace Jellyfin.Api.Helpers private readonly FileStream _fileStream; private readonly TranscodingJobDto? _job; private readonly TranscodingJobHelper _transcodingJobHelper; + private readonly int _timeoutMs; private readonly bool _allowAsyncFileRead; private int _bytesWritten; private bool _disposed; @@ -26,10 +28,12 @@ namespace Jellyfin.Api.Helpers /// <param name="filePath">The path to the transcoded file.</param> /// <param name="job">The transcoding job information.</param> /// <param name="transcodingJobHelper">The transcoding job helper.</param> - public ProgressiveFileStream(string filePath, TranscodingJobDto? job, TranscodingJobHelper transcodingJobHelper) + /// <param name="timeoutMs">The timeout duration in milliseconds.</param> + public ProgressiveFileStream(string filePath, TranscodingJobDto? job, TranscodingJobHelper transcodingJobHelper, int timeoutMs = 30000) { _job = job; _transcodingJobHelper = transcodingJobHelper; + _timeoutMs = timeoutMs; _bytesWritten = 0; var fileOptions = FileOptions.SequentialScan; @@ -81,6 +85,7 @@ namespace Jellyfin.Api.Helpers { int totalBytesRead = 0; int remainingBytesToRead = count; + var stopwatch = Stopwatch.StartNew(); int newOffset = offset; while (remainingBytesToRead > 0) @@ -111,8 +116,8 @@ namespace Jellyfin.Api.Helpers } else { - // If the job is null it's a live stream and will require user action to close - if (_job?.HasExited ?? false) + // If the job is null it's a live stream and will require user action to close, but don't keep it open indefinitely + if (_job?.HasExited ?? stopwatch.ElapsedMilliseconds > _timeoutMs) { break; } |
