aboutsummaryrefslogtreecommitdiff
path: root/Jellyfin.Api
diff options
context:
space:
mode:
Diffstat (limited to 'Jellyfin.Api')
-rw-r--r--Jellyfin.Api/Controllers/DisplayPreferencesController.cs6
-rw-r--r--Jellyfin.Api/Controllers/DynamicHlsController.cs17
-rw-r--r--Jellyfin.Api/Controllers/HlsSegmentController.cs4
-rw-r--r--Jellyfin.Api/Controllers/ImageController.cs54
-rw-r--r--Jellyfin.Api/Controllers/PluginsController.cs71
-rw-r--r--Jellyfin.Api/Controllers/TvShowsController.cs6
-rw-r--r--Jellyfin.Api/Controllers/VideosController.cs6
-rw-r--r--Jellyfin.Api/Helpers/AudioHelper.cs6
-rw-r--r--Jellyfin.Api/Helpers/FileStreamResponseHelpers.cs22
-rw-r--r--Jellyfin.Api/Helpers/TranscodingJobHelper.cs25
-rw-r--r--Jellyfin.Api/Jellyfin.Api.csproj2
-rw-r--r--Jellyfin.Api/Models/PluginDtos/MBRegistrationRecord.cs40
-rw-r--r--Jellyfin.Api/Models/PluginDtos/PluginSecurityInfo.cs18
13 files changed, 62 insertions, 215 deletions
diff --git a/Jellyfin.Api/Controllers/DisplayPreferencesController.cs b/Jellyfin.Api/Controllers/DisplayPreferencesController.cs
index 0b2604640..27eb22339 100644
--- a/Jellyfin.Api/Controllers/DisplayPreferencesController.cs
+++ b/Jellyfin.Api/Controllers/DisplayPreferencesController.cs
@@ -126,9 +126,11 @@ namespace Jellyfin.Api.Controllers
HomeSectionType.SmallLibraryTiles,
HomeSectionType.Resume,
HomeSectionType.ResumeAudio,
+ HomeSectionType.ResumeBook,
HomeSectionType.LiveTv,
HomeSectionType.NextUp,
- HomeSectionType.LatestMedia, HomeSectionType.None,
+ HomeSectionType.LatestMedia,
+ HomeSectionType.None,
};
if (!Guid.TryParse(displayPreferencesId, out var itemId))
@@ -182,7 +184,7 @@ namespace Jellyfin.Api.Controllers
var order = int.Parse(key.AsSpan().Slice("homesection".Length));
if (!Enum.TryParse<HomeSectionType>(displayPreferences.CustomPrefs[key], true, out var type))
{
- type = order < 7 ? defaults[order] : HomeSectionType.None;
+ type = order < 8 ? defaults[order] : HomeSectionType.None;
}
displayPreferences.CustomPrefs.Remove(key);
diff --git a/Jellyfin.Api/Controllers/DynamicHlsController.cs b/Jellyfin.Api/Controllers/DynamicHlsController.cs
index f2fdeeea5..f8e8d975c 100644
--- a/Jellyfin.Api/Controllers/DynamicHlsController.cs
+++ b/Jellyfin.Api/Controllers/DynamicHlsController.cs
@@ -1599,7 +1599,6 @@ namespace Jellyfin.Api.Controllers
state.BaseRequest.BreakOnNonKeyFrames = false;
}
- var inputModifier = _encodingHelper.GetInputModifier(state, _encodingOptions);
var mapArgs = state.IsOutputVideo ? _encodingHelper.GetMapArgs(state) : string.Empty;
var directory = Path.GetDirectoryName(outputPath) ?? throw new ArgumentException($"Provided path ({outputPath}) is not valid.", nameof(outputPath));
@@ -1608,12 +1607,15 @@ namespace Jellyfin.Api.Controllers
var outputExtension = EncodingHelper.GetSegmentFileExtension(state.Request.SegmentContainer);
var outputTsArg = outputPrefix + "%d" + outputExtension;
- var segmentFormat = outputExtension.TrimStart('.');
- if (string.Equals(segmentFormat, "ts", StringComparison.OrdinalIgnoreCase))
+ var segmentFormat = string.Empty;
+ var segmentContainer = outputExtension.TrimStart('.');
+ var inputModifier = _encodingHelper.GetInputModifier(state, _encodingOptions, segmentContainer);
+
+ if (string.Equals(segmentContainer, "ts", StringComparison.OrdinalIgnoreCase))
{
segmentFormat = "mpegts";
}
- else if (string.Equals(segmentFormat, "mp4", StringComparison.OrdinalIgnoreCase))
+ else if (string.Equals(segmentContainer, "mp4", StringComparison.OrdinalIgnoreCase))
{
var outputFmp4HeaderArg = OperatingSystem.IsWindows() switch
{
@@ -1627,7 +1629,8 @@ namespace Jellyfin.Api.Controllers
}
else
{
- _logger.LogError("Invalid HLS segment container: {SegmentFormat}", segmentFormat);
+ _logger.LogError("Invalid HLS segment container: {SegmentContainer}, default to mpegts", segmentContainer);
+ segmentFormat = "mpegts";
}
var maxMuxingQueueSize = _encodingOptions.MaxMuxingQueueSize > 128
@@ -1647,7 +1650,7 @@ namespace Jellyfin.Api.Controllers
CultureInfo.InvariantCulture,
"{0} {1} -map_metadata -1 -map_chapters -1 -threads {2} {3} {4} {5} -copyts -avoid_negative_ts disabled -max_muxing_queue_size {6} -f hls -max_delay 5000000 -hls_time {7} -hls_segment_type {8} -start_number {9}{10} -hls_segment_filename \"{12}\" -hls_playlist_type {11} -hls_list_size 0 -y \"{13}\"",
inputModifier,
- _encodingHelper.GetInputArgument(state, _encodingOptions),
+ _encodingHelper.GetInputArgument(state, _encodingOptions, segmentContainer),
threads,
mapArgs,
GetVideoArguments(state, startNumber, isEventPlaylist),
@@ -1944,7 +1947,7 @@ namespace Jellyfin.Api.Controllers
return Task.CompletedTask;
});
- return FileStreamResponseHelpers.GetStaticFileResult(segmentPath, MimeTypes.GetMimeType(segmentPath), false, HttpContext);
+ return FileStreamResponseHelpers.GetStaticFileResult(segmentPath, MimeTypes.GetMimeType(segmentPath));
}
private int? GetCurrentTranscodingIndex(string playlist, string segmentExtension)
diff --git a/Jellyfin.Api/Controllers/HlsSegmentController.cs b/Jellyfin.Api/Controllers/HlsSegmentController.cs
index 7325dca0a..78634f0bf 100644
--- a/Jellyfin.Api/Controllers/HlsSegmentController.cs
+++ b/Jellyfin.Api/Controllers/HlsSegmentController.cs
@@ -69,7 +69,7 @@ namespace Jellyfin.Api.Controllers
return BadRequest("Invalid segment.");
}
- return FileStreamResponseHelpers.GetStaticFileResult(file, MimeTypes.GetMimeType(file), false, HttpContext);
+ return FileStreamResponseHelpers.GetStaticFileResult(file, MimeTypes.GetMimeType(file));
}
/// <summary>
@@ -186,7 +186,7 @@ namespace Jellyfin.Api.Controllers
return Task.CompletedTask;
});
- return FileStreamResponseHelpers.GetStaticFileResult(path, MimeTypes.GetMimeType(path), false, HttpContext);
+ return FileStreamResponseHelpers.GetStaticFileResult(path, MimeTypes.GetMimeType(path));
}
}
}
diff --git a/Jellyfin.Api/Controllers/ImageController.cs b/Jellyfin.Api/Controllers/ImageController.cs
index aafffc2a1..05d80ba35 100644
--- a/Jellyfin.Api/Controllers/ImageController.cs
+++ b/Jellyfin.Api/Controllers/ImageController.cs
@@ -570,8 +570,7 @@ namespace Jellyfin.Api.Controllers
blur,
backgroundColor,
foregroundLayer,
- item,
- Request.Method.Equals(HttpMethods.Head, StringComparison.OrdinalIgnoreCase))
+ item)
.ConfigureAwait(false);
}
@@ -654,8 +653,7 @@ namespace Jellyfin.Api.Controllers
blur,
backgroundColor,
foregroundLayer,
- item,
- Request.Method.Equals(HttpMethods.Head, StringComparison.OrdinalIgnoreCase))
+ item)
.ConfigureAwait(false);
}
@@ -738,8 +736,7 @@ namespace Jellyfin.Api.Controllers
blur,
backgroundColor,
foregroundLayer,
- item,
- Request.Method.Equals(HttpMethods.Head, StringComparison.OrdinalIgnoreCase))
+ item)
.ConfigureAwait(false);
}
@@ -822,8 +819,7 @@ namespace Jellyfin.Api.Controllers
blur,
backgroundColor,
foregroundLayer,
- item,
- Request.Method.Equals(HttpMethods.Head, StringComparison.OrdinalIgnoreCase))
+ item)
.ConfigureAwait(false);
}
@@ -906,8 +902,7 @@ namespace Jellyfin.Api.Controllers
blur,
backgroundColor,
foregroundLayer,
- item,
- Request.Method.Equals(HttpMethods.Head, StringComparison.OrdinalIgnoreCase))
+ item)
.ConfigureAwait(false);
}
@@ -990,8 +985,7 @@ namespace Jellyfin.Api.Controllers
blur,
backgroundColor,
foregroundLayer,
- item,
- Request.Method.Equals(HttpMethods.Head, StringComparison.OrdinalIgnoreCase))
+ item)
.ConfigureAwait(false);
}
@@ -1074,8 +1068,7 @@ namespace Jellyfin.Api.Controllers
blur,
backgroundColor,
foregroundLayer,
- item,
- Request.Method.Equals(HttpMethods.Head, StringComparison.OrdinalIgnoreCase))
+ item)
.ConfigureAwait(false);
}
@@ -1158,8 +1151,7 @@ namespace Jellyfin.Api.Controllers
blur,
backgroundColor,
foregroundLayer,
- item,
- Request.Method.Equals(HttpMethods.Head, StringComparison.OrdinalIgnoreCase))
+ item)
.ConfigureAwait(false);
}
@@ -1242,8 +1234,7 @@ namespace Jellyfin.Api.Controllers
blur,
backgroundColor,
foregroundLayer,
- item,
- Request.Method.Equals(HttpMethods.Head, StringComparison.OrdinalIgnoreCase))
+ item)
.ConfigureAwait(false);
}
@@ -1326,8 +1317,7 @@ namespace Jellyfin.Api.Controllers
blur,
backgroundColor,
foregroundLayer,
- item,
- Request.Method.Equals(HttpMethods.Head, StringComparison.OrdinalIgnoreCase))
+ item)
.ConfigureAwait(false);
}
@@ -1410,8 +1400,7 @@ namespace Jellyfin.Api.Controllers
blur,
backgroundColor,
foregroundLayer,
- item,
- Request.Method.Equals(HttpMethods.Head, StringComparison.OrdinalIgnoreCase))
+ item)
.ConfigureAwait(false);
}
@@ -1494,8 +1483,7 @@ namespace Jellyfin.Api.Controllers
blur,
backgroundColor,
foregroundLayer,
- item,
- Request.Method.Equals(HttpMethods.Head, StringComparison.OrdinalIgnoreCase))
+ item)
.ConfigureAwait(false);
}
@@ -1596,7 +1584,6 @@ namespace Jellyfin.Api.Controllers
backgroundColor,
foregroundLayer,
null,
- Request.Method.Equals(HttpMethods.Head, StringComparison.OrdinalIgnoreCase),
info)
.ConfigureAwait(false);
}
@@ -1698,7 +1685,6 @@ namespace Jellyfin.Api.Controllers
backgroundColor,
foregroundLayer,
null,
- Request.Method.Equals(HttpMethods.Head, StringComparison.OrdinalIgnoreCase),
info)
.ConfigureAwait(false);
}
@@ -1784,8 +1770,7 @@ namespace Jellyfin.Api.Controllers
return await GetImageResult(
options,
cacheDuration,
- ImmutableDictionary<string, string>.Empty,
- Request.Method.Equals(HttpMethods.Head, StringComparison.OrdinalIgnoreCase))
+ ImmutableDictionary<string, string>.Empty)
.ConfigureAwait(false);
}
@@ -1907,7 +1892,6 @@ namespace Jellyfin.Api.Controllers
string? backgroundColor,
string? foregroundLayer,
BaseItem? item,
- bool isHeadRequest,
ItemImageInfo? imageInfo = null)
{
if (percentPlayed.HasValue)
@@ -1988,8 +1972,7 @@ namespace Jellyfin.Api.Controllers
return await GetImageResult(
options,
cacheDuration,
- responseHeaders,
- isHeadRequest).ConfigureAwait(false);
+ responseHeaders).ConfigureAwait(false);
}
private ImageFormat[] GetOutputFormats(ImageFormat? format)
@@ -2068,8 +2051,7 @@ namespace Jellyfin.Api.Controllers
private async Task<ActionResult> GetImageResult(
ImageProcessingOptions imageProcessingOptions,
TimeSpan? cacheDuration,
- IDictionary<string, string> headers,
- bool isHeadRequest)
+ IDictionary<string, string> headers)
{
var (imagePath, imageContentType, dateImageModified) = await _imageProcessor.ProcessImage(imageProcessingOptions).ConfigureAwait(false);
@@ -2120,12 +2102,6 @@ namespace Jellyfin.Api.Controllers
}
}
- // if the request is a head request, return a NoContent result with the same headers as it would with a GET request
- if (isHeadRequest)
- {
- return NoContent();
- }
-
return PhysicalFile(imagePath, imageContentType ?? MediaTypeNames.Text.Plain);
}
}
diff --git a/Jellyfin.Api/Controllers/PluginsController.cs b/Jellyfin.Api/Controllers/PluginsController.cs
index b41df1abb..b227dba2d 100644
--- a/Jellyfin.Api/Controllers/PluginsController.cs
+++ b/Jellyfin.Api/Controllers/PluginsController.cs
@@ -7,7 +7,6 @@ using System.Text.Json;
using System.Threading.Tasks;
using Jellyfin.Api.Attributes;
using Jellyfin.Api.Constants;
-using Jellyfin.Api.Models.PluginDtos;
using Jellyfin.Extensions.Json;
using MediaBrowser.Common.Plugins;
using MediaBrowser.Common.Updates;
@@ -44,61 +43,6 @@ namespace Jellyfin.Api.Controllers
}
/// <summary>
- /// Get plugin security info.
- /// </summary>
- /// <response code="200">Plugin security info returned.</response>
- /// <returns>Plugin security info.</returns>
- [Obsolete("This endpoint should not be used.")]
- [HttpGet("SecurityInfo")]
- [ProducesResponseType(StatusCodes.Status200OK)]
- public static ActionResult<PluginSecurityInfo> GetPluginSecurityInfo()
- {
- return new PluginSecurityInfo
- {
- IsMbSupporter = true,
- SupporterKey = "IAmTotallyLegit"
- };
- }
-
- /// <summary>
- /// Gets registration status for a feature.
- /// </summary>
- /// <param name="name">Feature name.</param>
- /// <response code="200">Registration status returned.</response>
- /// <returns>Mb registration record.</returns>
- [Obsolete("This endpoint should not be used.")]
- [HttpPost("RegistrationRecords/{name}")]
- [ProducesResponseType(StatusCodes.Status200OK)]
- public static ActionResult<MBRegistrationRecord> GetRegistrationStatus([FromRoute, Required] string name)
- {
- return new MBRegistrationRecord
- {
- IsRegistered = true,
- RegChecked = true,
- TrialVersion = false,
- IsValid = true,
- RegError = false
- };
- }
-
- /// <summary>
- /// Gets registration status for a feature.
- /// </summary>
- /// <param name="name">Feature name.</param>
- /// <response code="501">Not implemented.</response>
- /// <returns>Not Implemented.</returns>
- /// <exception cref="NotImplementedException">This endpoint is not implemented.</exception>
- [Obsolete("Paid plugins are not supported")]
- [HttpGet("Registrations/{name}")]
- [ProducesResponseType(StatusCodes.Status501NotImplemented)]
- public static ActionResult GetRegistration([FromRoute, Required] string name)
- {
- // TODO Once we have proper apps and plugins and decide to break compatibility with paid plugins,
- // delete all these registration endpoints. They are only kept for compatibility.
- throw new NotImplementedException();
- }
-
- /// <summary>
/// Gets a list of currently installed plugins.
/// </summary>
/// <response code="200">Installed plugins returned.</response>
@@ -317,20 +261,5 @@ namespace Jellyfin.Api.Controllers
return NotFound();
}
-
- /// <summary>
- /// Updates plugin security info.
- /// </summary>
- /// <param name="pluginSecurityInfo">Plugin security info.</param>
- /// <response code="204">Plugin security info updated.</response>
- /// <returns>An <see cref="NoContentResult"/>.</returns>
- [Obsolete("This endpoint should not be used.")]
- [HttpPost("SecurityInfo")]
- [Authorize(Policy = Policies.RequiresElevation)]
- [ProducesResponseType(StatusCodes.Status204NoContent)]
- public ActionResult UpdatePluginSecurityInfo([FromBody, Required] PluginSecurityInfo pluginSecurityInfo)
- {
- return NoContent();
- }
}
}
diff --git a/Jellyfin.Api/Controllers/TvShowsController.cs b/Jellyfin.Api/Controllers/TvShowsController.cs
index 2572ba63b..179a53fd5 100644
--- a/Jellyfin.Api/Controllers/TvShowsController.cs
+++ b/Jellyfin.Api/Controllers/TvShowsController.cs
@@ -68,7 +68,7 @@ namespace Jellyfin.Api.Controllers
/// <param name="nextUpDateCutoff">Optional. Starting date of shows to show in Next Up section.</param>
/// <param name="enableTotalRecordCount">Whether to enable the total records count. Defaults to true.</param>
/// <param name="disableFirstEpisode">Whether to disable sending the first episode in a series as next up.</param>
- /// <param name="rewatching">Whether to get a rewatching next up instead of standard next up.</param>
+ /// <param name="enableRewatching">Whether to include watched episode in next up results.</param>
/// <returns>A <see cref="QueryResult{BaseItemDto}"/> with the next up episodes.</returns>
[HttpGet("NextUp")]
[ProducesResponseType(StatusCodes.Status200OK)]
@@ -86,7 +86,7 @@ namespace Jellyfin.Api.Controllers
[FromQuery] DateTime? nextUpDateCutoff,
[FromQuery] bool enableTotalRecordCount = true,
[FromQuery] bool disableFirstEpisode = false,
- [FromQuery] bool rewatching = false)
+ [FromQuery] bool enableRewatching = false)
{
var options = new DtoOptions { Fields = fields }
.AddClientFields(Request)
@@ -103,7 +103,7 @@ namespace Jellyfin.Api.Controllers
EnableTotalRecordCount = enableTotalRecordCount,
DisableFirstEpisode = disableFirstEpisode,
NextUpDateCutoff = nextUpDateCutoff ?? DateTime.MinValue,
- Rewatching = rewatching
+ EnableRewatching = enableRewatching
},
options);
diff --git a/Jellyfin.Api/Controllers/VideosController.cs b/Jellyfin.Api/Controllers/VideosController.cs
index 74b4f084f..62c05331e 100644
--- a/Jellyfin.Api/Controllers/VideosController.cs
+++ b/Jellyfin.Api/Controllers/VideosController.cs
@@ -465,7 +465,7 @@ namespace Jellyfin.Api.Controllers
StreamingHelpers.AddDlnaHeaders(state, Response.Headers, true, state.Request.StartTimeTicks, Request, _dlnaManager);
var httpClient = _httpClientFactory.CreateClient(NamedClient.Default);
- return await FileStreamResponseHelpers.GetStaticRemoteStreamResult(state, isHeadRequest, httpClient, HttpContext).ConfigureAwait(false);
+ return await FileStreamResponseHelpers.GetStaticRemoteStreamResult(state, httpClient, HttpContext).ConfigureAwait(false);
}
if (@static.HasValue && @static.Value && state.InputProtocol != MediaProtocol.File)
@@ -494,9 +494,7 @@ namespace Jellyfin.Api.Controllers
return FileStreamResponseHelpers.GetStaticFileResult(
state.MediaPath,
- contentType,
- isHeadRequest,
- HttpContext);
+ contentType);
}
// Need to start ffmpeg (because media can't be returned directly)
diff --git a/Jellyfin.Api/Helpers/AudioHelper.cs b/Jellyfin.Api/Helpers/AudioHelper.cs
index bec961dad..27497cd59 100644
--- a/Jellyfin.Api/Helpers/AudioHelper.cs
+++ b/Jellyfin.Api/Helpers/AudioHelper.cs
@@ -138,7 +138,7 @@ namespace Jellyfin.Api.Helpers
StreamingHelpers.AddDlnaHeaders(state, _httpContextAccessor.HttpContext.Response.Headers, true, streamingRequest.StartTimeTicks, _httpContextAccessor.HttpContext.Request, _dlnaManager);
var httpClient = _httpClientFactory.CreateClient(NamedClient.Default);
- return await FileStreamResponseHelpers.GetStaticRemoteStreamResult(state, isHeadRequest, httpClient, _httpContextAccessor.HttpContext).ConfigureAwait(false);
+ return await FileStreamResponseHelpers.GetStaticRemoteStreamResult(state, httpClient, _httpContextAccessor.HttpContext).ConfigureAwait(false);
}
if (streamingRequest.Static && state.InputProtocol != MediaProtocol.File)
@@ -167,9 +167,7 @@ namespace Jellyfin.Api.Helpers
return FileStreamResponseHelpers.GetStaticFileResult(
state.MediaPath,
- contentType,
- isHeadRequest,
- _httpContextAccessor.HttpContext);
+ contentType);
}
// Need to start ffmpeg (because media can't be returned directly)
diff --git a/Jellyfin.Api/Helpers/FileStreamResponseHelpers.cs b/Jellyfin.Api/Helpers/FileStreamResponseHelpers.cs
index 6385b62c9..5bdd3fe2e 100644
--- a/Jellyfin.Api/Helpers/FileStreamResponseHelpers.cs
+++ b/Jellyfin.Api/Helpers/FileStreamResponseHelpers.cs
@@ -22,14 +22,12 @@ namespace Jellyfin.Api.Helpers
/// Returns a static file from a remote source.
/// </summary>
/// <param name="state">The current <see cref="StreamState"/>.</param>
- /// <param name="isHeadRequest">Whether the current request is a HTTP HEAD request so only the headers get returned.</param>
/// <param name="httpClient">The <see cref="HttpClient"/> making the remote request.</param>
/// <param name="httpContext">The current http context.</param>
/// <param name="cancellationToken">A cancellation token that can be used to cancel the operation.</param>
/// <returns>A <see cref="Task{ActionResult}"/> containing the API response.</returns>
public static async Task<ActionResult> GetStaticRemoteStreamResult(
StreamState state,
- bool isHeadRequest,
HttpClient httpClient,
HttpContext httpContext,
CancellationToken cancellationToken = default)
@@ -45,12 +43,6 @@ namespace Jellyfin.Api.Helpers
httpContext.Response.Headers[HeaderNames.AcceptRanges] = "none";
- if (isHeadRequest)
- {
- httpContext.Response.Headers[HeaderNames.ContentType] = contentType;
- return new OkResult();
- }
-
return new FileStreamResult(await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false), contentType);
}
@@ -59,23 +51,11 @@ namespace Jellyfin.Api.Helpers
/// </summary>
/// <param name="path">The path to the file.</param>
/// <param name="contentType">The content type of the file.</param>
- /// <param name="isHeadRequest">Whether the current request is a HTTP HEAD request so only the headers get returned.</param>
- /// <param name="httpContext">The current http context.</param>
/// <returns>An <see cref="ActionResult"/> the file.</returns>
public static ActionResult GetStaticFileResult(
string path,
- string contentType,
- bool isHeadRequest,
- HttpContext httpContext)
+ string contentType)
{
- httpContext.Response.ContentType = contentType;
-
- // if the request is a head request, return an OkResult (200) with the same headers as it would with a GET request
- if (isHeadRequest)
- {
- return new OkResult();
- }
-
return new PhysicalFileResult(path, contentType) { EnableRangeProcessing = true };
}
diff --git a/Jellyfin.Api/Helpers/TranscodingJobHelper.cs b/Jellyfin.Api/Helpers/TranscodingJobHelper.cs
index 56a54fb1d..c8762b7c5 100644
--- a/Jellyfin.Api/Helpers/TranscodingJobHelper.cs
+++ b/Jellyfin.Api/Helpers/TranscodingJobHelper.cs
@@ -18,6 +18,7 @@ using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Session;
+using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.MediaInfo;
@@ -42,6 +43,8 @@ namespace Jellyfin.Api.Helpers
/// </summary>
private static readonly Dictionary<string, SemaphoreSlim> _transcodingLocks = new Dictionary<string, SemaphoreSlim>();
+ private readonly IAttachmentExtractor _attachmentExtractor;
+ private readonly IApplicationPaths _appPaths;
private readonly IAuthorizationContext _authorizationContext;
private readonly EncodingHelper _encodingHelper;
private readonly IFileSystem _fileSystem;
@@ -55,6 +58,8 @@ namespace Jellyfin.Api.Helpers
/// <summary>
/// Initializes a new instance of the <see cref="TranscodingJobHelper"/> class.
/// </summary>
+ /// <param name="attachmentExtractor">Instance of the <see cref="IAttachmentExtractor"/> interface.</param>
+ /// <param name="appPaths">Instance of the <see cref="IApplicationPaths"/> interface.</param>
/// <param name="logger">Instance of the <see cref="ILogger{TranscodingJobHelpers}"/> interface.</param>
/// <param name="mediaSourceManager">Instance of the <see cref="IMediaSourceManager"/> interface.</param>
/// <param name="fileSystem">Instance of the <see cref="IFileSystem"/> interface.</param>
@@ -65,6 +70,8 @@ namespace Jellyfin.Api.Helpers
/// <param name="encodingHelper">Instance of <see cref="EncodingHelper"/>.</param>
/// <param name="loggerFactory">Instance of the <see cref="ILoggerFactory"/> interface.</param>
public TranscodingJobHelper(
+ IAttachmentExtractor attachmentExtractor,
+ IApplicationPaths appPaths,
ILogger<TranscodingJobHelper> logger,
IMediaSourceManager mediaSourceManager,
IFileSystem fileSystem,
@@ -75,6 +82,8 @@ namespace Jellyfin.Api.Helpers
EncodingHelper encodingHelper,
ILoggerFactory loggerFactory)
{
+ _attachmentExtractor = attachmentExtractor;
+ _appPaths = appPaths;
_logger = logger;
_mediaSourceManager = mediaSourceManager;
_fileSystem = fileSystem;
@@ -449,9 +458,12 @@ namespace Jellyfin.Api.Helpers
var audioCodec = state.ActualOutputAudioCodec;
var videoCodec = state.ActualOutputVideoCodec;
var hardwareAccelerationTypeString = _serverConfigurationManager.GetEncodingOptions().HardwareAccelerationType;
- HardwareEncodingType? hardwareAccelerationType = string.IsNullOrEmpty(hardwareAccelerationTypeString)
- ? null
- : (HardwareEncodingType)Enum.Parse(typeof(HardwareEncodingType), hardwareAccelerationTypeString, true);
+ HardwareEncodingType? hardwareAccelerationType = null;
+ if (!string.IsNullOrEmpty(hardwareAccelerationTypeString)
+ && Enum.TryParse<HardwareEncodingType>(hardwareAccelerationTypeString, out var parsedHardwareAccelerationType))
+ {
+ hardwareAccelerationType = parsedHardwareAccelerationType;
+ }
_sessionManager.ReportTranscodingInfo(deviceId, new TranscodingInfo
{
@@ -513,6 +525,13 @@ namespace Jellyfin.Api.Helpers
throw new ArgumentException("FFmpeg path not set.");
}
+ // If subtitles get burned in fonts may need to be extracted from the media file
+ if (state.SubtitleStream != null && state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode)
+ {
+ var attachmentPath = Path.Combine(_appPaths.CachePath, "attachments", state.MediaSource.Id);
+ await _attachmentExtractor.ExtractAllAttachments(state.MediaPath, state.MediaSource, attachmentPath, CancellationToken.None).ConfigureAwait(false);
+ }
+
var process = new Process
{
StartInfo = new ProcessStartInfo
diff --git a/Jellyfin.Api/Jellyfin.Api.csproj b/Jellyfin.Api/Jellyfin.Api.csproj
index c5b240e92..b0b74e7ed 100644
--- a/Jellyfin.Api/Jellyfin.Api.csproj
+++ b/Jellyfin.Api/Jellyfin.Api.csproj
@@ -17,7 +17,7 @@
</PropertyGroup>
<ItemGroup>
- <PackageReference Include="Microsoft.AspNetCore.Authorization" Version="6.0.2" />
+ <PackageReference Include="Microsoft.AspNetCore.Authorization" Version="6.0.3" />
<PackageReference Include="Microsoft.Extensions.Http" Version="6.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
<PackageReference Include="Swashbuckle.AspNetCore.ReDoc" Version="6.2.3" />
diff --git a/Jellyfin.Api/Models/PluginDtos/MBRegistrationRecord.cs b/Jellyfin.Api/Models/PluginDtos/MBRegistrationRecord.cs
deleted file mode 100644
index 7f1255f4b..000000000
--- a/Jellyfin.Api/Models/PluginDtos/MBRegistrationRecord.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-using System;
-
-namespace Jellyfin.Api.Models.PluginDtos
-{
- /// <summary>
- /// MB Registration Record.
- /// </summary>
- public class MBRegistrationRecord
- {
- /// <summary>
- /// Gets or sets expiration date.
- /// </summary>
- public DateTime ExpirationDate { get; set; }
-
- /// <summary>
- /// Gets or sets a value indicating whether is registered.
- /// </summary>
- public bool IsRegistered { get; set; }
-
- /// <summary>
- /// Gets or sets a value indicating whether reg checked.
- /// </summary>
- public bool RegChecked { get; set; }
-
- /// <summary>
- /// Gets or sets a value indicating whether reg error.
- /// </summary>
- public bool RegError { get; set; }
-
- /// <summary>
- /// Gets or sets a value indicating whether trial version.
- /// </summary>
- public bool TrialVersion { get; set; }
-
- /// <summary>
- /// Gets or sets a value indicating whether is valid.
- /// </summary>
- public bool IsValid { get; set; }
- }
-}
diff --git a/Jellyfin.Api/Models/PluginDtos/PluginSecurityInfo.cs b/Jellyfin.Api/Models/PluginDtos/PluginSecurityInfo.cs
deleted file mode 100644
index a90398425..000000000
--- a/Jellyfin.Api/Models/PluginDtos/PluginSecurityInfo.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-namespace Jellyfin.Api.Models.PluginDtos
-{
- /// <summary>
- /// Plugin security info.
- /// </summary>
- public class PluginSecurityInfo
- {
- /// <summary>
- /// Gets or sets the supporter key.
- /// </summary>
- public string? SupporterKey { get; set; }
-
- /// <summary>
- /// Gets or sets a value indicating whether is mb supporter.
- /// </summary>
- public bool IsMbSupporter { get; set; }
- }
-}