diff options
Diffstat (limited to 'Jellyfin.Api/Controllers')
| -rw-r--r-- | Jellyfin.Api/Controllers/ConfigurationController.cs | 2 | ||||
| -rw-r--r-- | Jellyfin.Api/Controllers/DynamicHlsController.cs | 4 | ||||
| -rw-r--r-- | Jellyfin.Api/Controllers/InstantMixController.cs | 57 | ||||
| -rw-r--r-- | Jellyfin.Api/Controllers/LiveTvController.cs | 9 | ||||
| -rw-r--r-- | Jellyfin.Api/Controllers/MediaInfoController.cs | 22 | ||||
| -rw-r--r-- | Jellyfin.Api/Controllers/PluginsController.cs | 2 | ||||
| -rw-r--r-- | Jellyfin.Api/Controllers/QuickConnectController.cs | 79 | ||||
| -rw-r--r-- | Jellyfin.Api/Controllers/TvShowsController.cs | 2 | ||||
| -rw-r--r-- | Jellyfin.Api/Controllers/UserLibraryController.cs | 2 | ||||
| -rw-r--r-- | Jellyfin.Api/Controllers/VideoHlsController.cs | 5 | ||||
| -rw-r--r-- | Jellyfin.Api/Controllers/VideosController.cs | 12 |
11 files changed, 60 insertions, 136 deletions
diff --git a/Jellyfin.Api/Controllers/ConfigurationController.cs b/Jellyfin.Api/Controllers/ConfigurationController.cs index b6309baab..60529e990 100644 --- a/Jellyfin.Api/Controllers/ConfigurationController.cs +++ b/Jellyfin.Api/Controllers/ConfigurationController.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; using Jellyfin.Api.Attributes; using Jellyfin.Api.Constants; using Jellyfin.Api.Models.ConfigurationDtos; -using MediaBrowser.Common.Json; +using Jellyfin.Extensions.Json; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Model.Configuration; diff --git a/Jellyfin.Api/Controllers/DynamicHlsController.cs b/Jellyfin.Api/Controllers/DynamicHlsController.cs index 62283d038..35435b007 100644 --- a/Jellyfin.Api/Controllers/DynamicHlsController.cs +++ b/Jellyfin.Api/Controllers/DynamicHlsController.cs @@ -1380,7 +1380,7 @@ namespace Jellyfin.Api.Controllers } else if (string.Equals(segmentFormat, "mp4", StringComparison.OrdinalIgnoreCase)) { - var outputFmp4HeaderArg = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) switch + var outputFmp4HeaderArg = OperatingSystem.IsWindows() switch { // on Windows, the path of fmp4 header file needs to be configured true => " -hls_fmp4_init_filename \"" + outputPrefix + "-1" + outputExtension + "\"", @@ -1496,7 +1496,7 @@ namespace Jellyfin.Api.Controllers args += " -ar " + state.OutputAudioSampleRate.Value.ToString(CultureInfo.InvariantCulture); } - args += _encodingHelper.GetAudioFilterParam(state, _encodingOptions, true); + args += _encodingHelper.GetAudioFilterParam(state, _encodingOptions); return args; } diff --git a/Jellyfin.Api/Controllers/InstantMixController.cs b/Jellyfin.Api/Controllers/InstantMixController.cs index f232dffaa..4774ed4ef 100644 --- a/Jellyfin.Api/Controllers/InstantMixController.cs +++ b/Jellyfin.Api/Controllers/InstantMixController.cs @@ -229,42 +229,6 @@ namespace Jellyfin.Api.Controllers } /// <summary> - /// Creates an instant playlist based on a given genre. - /// </summary> - /// <param name="id">The item id.</param> - /// <param name="userId">Optional. Filter by user id, and attach user data.</param> - /// <param name="limit">Optional. The maximum number of records to return.</param> - /// <param name="fields">Optional. Specify additional fields of information to return in the output.</param> - /// <param name="enableImages">Optional. Include image information in output.</param> - /// <param name="enableUserData">Optional. Include user data.</param> - /// <param name="imageTypeLimit">Optional. The max number of images to return, per image type.</param> - /// <param name="enableImageTypes">Optional. The image types to include in the output.</param> - /// <response code="200">Instant playlist returned.</response> - /// <returns>A <see cref="QueryResult{BaseItemDto}"/> with the playlist items.</returns> - [HttpGet("MusicGenres/{id}/InstantMix")] - [ProducesResponseType(StatusCodes.Status200OK)] - public ActionResult<QueryResult<BaseItemDto>> GetInstantMixFromMusicGenreById( - [FromRoute, Required] Guid id, - [FromQuery] Guid? userId, - [FromQuery] int? limit, - [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields, - [FromQuery] bool? enableImages, - [FromQuery] bool? enableUserData, - [FromQuery] int? imageTypeLimit, - [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ImageType[] enableImageTypes) - { - var item = _libraryManager.GetItemById(id); - var user = userId.HasValue && !userId.Equals(Guid.Empty) - ? _userManager.GetUserById(userId.Value) - : null; - var dtoOptions = new DtoOptions { Fields = fields } - .AddClientFields(Request) - .AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes!); - var items = _musicManager.GetInstantMixFromItem(item, user, dtoOptions); - return GetResult(items, user, limit, dtoOptions); - } - - /// <summary> /// Creates an instant playlist based on a given item. /// </summary> /// <param name="id">The item id.</param> @@ -352,8 +316,7 @@ namespace Jellyfin.Api.Controllers /// <returns>A <see cref="QueryResult{BaseItemDto}"/> with the playlist items.</returns> [HttpGet("MusicGenres/InstantMix")] [ProducesResponseType(StatusCodes.Status200OK)] - [Obsolete("Use GetInstantMixFromMusicGenres instead")] - public ActionResult<QueryResult<BaseItemDto>> GetInstantMixFromMusicGenreById2( + public ActionResult<QueryResult<BaseItemDto>> GetInstantMixFromMusicGenreById( [FromQuery, Required] Guid id, [FromQuery] Guid? userId, [FromQuery] int? limit, @@ -363,15 +326,15 @@ namespace Jellyfin.Api.Controllers [FromQuery] int? imageTypeLimit, [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ImageType[] enableImageTypes) { - return GetInstantMixFromMusicGenreById( - id, - userId, - limit, - fields, - enableImages, - enableUserData, - imageTypeLimit, - enableImageTypes); + var item = _libraryManager.GetItemById(id); + var user = userId.HasValue && !userId.Equals(Guid.Empty) + ? _userManager.GetUserById(userId.Value) + : null; + var dtoOptions = new DtoOptions { Fields = fields } + .AddClientFields(Request) + .AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes!); + var items = _musicManager.GetInstantMixFromItem(item, user, dtoOptions); + return GetResult(items, user, limit, dtoOptions); } private QueryResult<BaseItemDto> GetResult(List<BaseItem> items, User? user, int? limit, DtoOptions dtoOptions) 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/Controllers/MediaInfoController.cs b/Jellyfin.Api/Controllers/MediaInfoController.cs index e330f02b6..8903e0ce8 100644 --- a/Jellyfin.Api/Controllers/MediaInfoController.cs +++ b/Jellyfin.Api/Controllers/MediaInfoController.cs @@ -161,6 +161,11 @@ namespace Jellyfin.Api.Controllers liveStreamId) .ConfigureAwait(false); + if (info.ErrorCode != null) + { + return info; + } + if (profile != null) { // set device specific data @@ -302,27 +307,12 @@ namespace Jellyfin.Api.Controllers /// </summary> /// <param name="size">The bitrate. Defaults to 102400.</param> /// <response code="200">Test buffer returned.</response> - /// <response code="400">Size has to be a numer between 0 and 10,000,000.</response> /// <returns>A <see cref="FileResult"/> with specified bitrate.</returns> [HttpGet("Playback/BitrateTest")] [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [Produces(MediaTypeNames.Application.Octet)] [ProducesFile(MediaTypeNames.Application.Octet)] - public ActionResult GetBitrateTestBytes([FromQuery] int size = 102400) + public ActionResult GetBitrateTestBytes([FromQuery][Range(1, 100_000_000, ErrorMessage = "The requested size must be greater than or equal to {1} and less than or equal to {2}")] int size = 102400) { - const int MaxSize = 10_000_000; - - if (size <= 0) - { - return BadRequest($"The requested size ({size}) is equal to or smaller than 0."); - } - - if (size > MaxSize) - { - return BadRequest($"The requested size ({size}) is larger than the max allowed value ({MaxSize})."); - } - byte[] buffer = ArrayPool<byte>.Shared.Rent(size); try { diff --git a/Jellyfin.Api/Controllers/PluginsController.cs b/Jellyfin.Api/Controllers/PluginsController.cs index 7a6130719..0ae6109bc 100644 --- a/Jellyfin.Api/Controllers/PluginsController.cs +++ b/Jellyfin.Api/Controllers/PluginsController.cs @@ -8,8 +8,8 @@ using System.Threading.Tasks; using Jellyfin.Api.Attributes; using Jellyfin.Api.Constants; using Jellyfin.Api.Models.PluginDtos; +using Jellyfin.Extensions.Json; using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.Json; using MediaBrowser.Common.Plugins; using MediaBrowser.Common.Updates; using MediaBrowser.Model.Net; diff --git a/Jellyfin.Api/Controllers/QuickConnectController.cs b/Jellyfin.Api/Controllers/QuickConnectController.cs index 4ac849181..3cd1bc6d4 100644 --- a/Jellyfin.Api/Controllers/QuickConnectController.cs +++ b/Jellyfin.Api/Controllers/QuickConnectController.cs @@ -2,6 +2,7 @@ using System.ComponentModel.DataAnnotations; using Jellyfin.Api.Constants; using Jellyfin.Api.Helpers; using MediaBrowser.Common.Extensions; +using MediaBrowser.Controller.Authentication; using MediaBrowser.Controller.QuickConnect; using MediaBrowser.Model.QuickConnect; using Microsoft.AspNetCore.Authorization; @@ -30,13 +31,12 @@ namespace Jellyfin.Api.Controllers /// Gets the current quick connect state. /// </summary> /// <response code="200">Quick connect state returned.</response> - /// <returns>The current <see cref="QuickConnectState"/>.</returns> - [HttpGet("Status")] + /// <returns>Whether Quick Connect is enabled on the server or not.</returns> + [HttpGet("Enabled")] [ProducesResponseType(StatusCodes.Status200OK)] - public ActionResult<QuickConnectState> GetStatus() + public ActionResult<bool> GetEnabled() { - _quickConnect.ExpireRequests(); - return _quickConnect.State; + return _quickConnect.IsEnabled; } /// <summary> @@ -49,7 +49,14 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status200OK)] public ActionResult<QuickConnectResult> Initiate() { - return _quickConnect.TryConnect(); + try + { + return _quickConnect.TryConnect(); + } + catch (AuthenticationException) + { + return Unauthorized("Quick connect is disabled"); + } } /// <summary> @@ -72,42 +79,10 @@ namespace Jellyfin.Api.Controllers { return NotFound("Unknown secret"); } - } - - /// <summary> - /// Temporarily activates quick connect for five minutes. - /// </summary> - /// <response code="204">Quick connect has been temporarily activated.</response> - /// <response code="403">Quick connect is unavailable on this server.</response> - /// <returns>An <see cref="NoContentResult"/> on success.</returns> - [HttpPost("Activate")] - [Authorize(Policy = Policies.DefaultAuthorization)] - [ProducesResponseType(StatusCodes.Status204NoContent)] - [ProducesResponseType(StatusCodes.Status403Forbidden)] - public ActionResult Activate() - { - if (_quickConnect.State == QuickConnectState.Unavailable) + catch (AuthenticationException) { - return StatusCode(StatusCodes.Status403Forbidden, "Quick connect is unavailable"); + return Unauthorized("Quick connect is disabled"); } - - _quickConnect.Activate(); - return NoContent(); - } - - /// <summary> - /// Enables or disables quick connect. - /// </summary> - /// <param name="status">New <see cref="QuickConnectState"/>.</param> - /// <response code="204">Quick connect state set successfully.</response> - /// <returns>An <see cref="NoContentResult"/> on success.</returns> - [HttpPost("Available")] - [Authorize(Policy = Policies.RequiresElevation)] - [ProducesResponseType(StatusCodes.Status204NoContent)] - public ActionResult Available([FromQuery] QuickConnectState status = QuickConnectState.Available) - { - _quickConnect.SetState(status); - return NoContent(); } /// <summary> @@ -129,26 +104,14 @@ namespace Jellyfin.Api.Controllers return StatusCode(StatusCodes.Status403Forbidden, "Unknown user id"); } - return _quickConnect.AuthorizeRequest(userId.Value, code); - } - - /// <summary> - /// Deauthorize all quick connect devices for the current user. - /// </summary> - /// <response code="200">All quick connect devices were deleted.</response> - /// <returns>The number of devices that were deleted.</returns> - [HttpPost("Deauthorize")] - [Authorize(Policy = Policies.DefaultAuthorization)] - [ProducesResponseType(StatusCodes.Status200OK)] - public ActionResult<int> Deauthorize() - { - var userId = ClaimHelpers.GetUserId(Request.HttpContext.User); - if (!userId.HasValue) + try { - return 0; + return _quickConnect.AuthorizeRequest(userId.Value, code); + } + catch (AuthenticationException) + { + return Unauthorized("Quick connect is disabled"); } - - return _quickConnect.DeleteAllDevices(userId.Value); } } } diff --git a/Jellyfin.Api/Controllers/TvShowsController.cs b/Jellyfin.Api/Controllers/TvShowsController.cs index ffb726fab..51d40994e 100644 --- a/Jellyfin.Api/Controllers/TvShowsController.cs +++ b/Jellyfin.Api/Controllers/TvShowsController.cs @@ -6,7 +6,7 @@ using Jellyfin.Api.Constants; using Jellyfin.Api.Extensions; using Jellyfin.Api.ModelBinders; using Jellyfin.Data.Enums; -using MediaBrowser.Common.Extensions; +using Jellyfin.Extensions; using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.TV; diff --git a/Jellyfin.Api/Controllers/UserLibraryController.cs b/Jellyfin.Api/Controllers/UserLibraryController.cs index 1d70406ac..a33a0826c 100644 --- a/Jellyfin.Api/Controllers/UserLibraryController.cs +++ b/Jellyfin.Api/Controllers/UserLibraryController.cs @@ -9,7 +9,7 @@ using Jellyfin.Api.Extensions; using Jellyfin.Api.Helpers; using Jellyfin.Api.ModelBinders; using Jellyfin.Data.Enums; -using MediaBrowser.Common.Extensions; +using Jellyfin.Extensions; using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; diff --git a/Jellyfin.Api/Controllers/VideoHlsController.cs b/Jellyfin.Api/Controllers/VideoHlsController.cs index 6a720b1a4..5c941b276 100644 --- a/Jellyfin.Api/Controllers/VideoHlsController.cs +++ b/Jellyfin.Api/Controllers/VideoHlsController.cs @@ -366,8 +366,7 @@ namespace Jellyfin.Api.Controllers else if (string.Equals(segmentFormat, "mp4", StringComparison.OrdinalIgnoreCase)) { var outputFmp4HeaderArg = string.Empty; - var isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); - if (isWindows) + if (OperatingSystem.IsWindows()) { // on Windows, the path of fmp4 header file needs to be configured outputFmp4HeaderArg = " -hls_fmp4_init_filename \"" + outputPrefix + "-1" + outputExtension + "\""; @@ -485,7 +484,7 @@ namespace Jellyfin.Api.Controllers args += " -ar " + state.OutputAudioSampleRate.Value.ToString(CultureInfo.InvariantCulture); } - args += _encodingHelper.GetAudioFilterParam(state, _encodingOptions, true); + args += _encodingHelper.GetAudioFilterParam(state, _encodingOptions); return args; } diff --git a/Jellyfin.Api/Controllers/VideosController.cs b/Jellyfin.Api/Controllers/VideosController.cs index dc64a0f1b..29a25fa6a 100644 --- a/Jellyfin.Api/Controllers/VideosController.cs +++ b/Jellyfin.Api/Controllers/VideosController.cs @@ -296,6 +296,8 @@ namespace Jellyfin.Api.Controllers /// <param name="startTimeTicks">Optional. Specify a starting offset, in ticks. 1 tick = 10000 ms.</param> /// <param name="width">Optional. The fixed horizontal resolution of the encoded video.</param> /// <param name="height">Optional. The fixed vertical resolution of the encoded video.</param> + /// <param name="maxWidth">Optional. The maximum horizontal resolution of the encoded video.</param> + /// <param name="maxHeight">Optional. The maximum vertical resolution of the encoded video.</param> /// <param name="videoBitRate">Optional. Specify a video bitrate to encode to, e.g. 500000. If omitted this will be left to encoder defaults.</param> /// <param name="subtitleStreamIndex">Optional. The index of the subtitle stream to use. If omitted no subtitles will be used.</param> /// <param name="subtitleMethod">Optional. Specify the subtitle delivery method.</param> @@ -352,6 +354,8 @@ namespace Jellyfin.Api.Controllers [FromQuery] long? startTimeTicks, [FromQuery] int? width, [FromQuery] int? height, + [FromQuery] int? maxWidth, + [FromQuery] int? maxHeight, [FromQuery] int? videoBitRate, [FromQuery] int? subtitleStreamIndex, [FromQuery] SubtitleDeliveryMethod? subtitleMethod, @@ -407,6 +411,8 @@ namespace Jellyfin.Api.Controllers StartTimeTicks = startTimeTicks, Width = width, Height = height, + MaxWidth = maxWidth, + MaxHeight = maxHeight, VideoBitRate = videoBitRate, SubtitleStreamIndex = subtitleStreamIndex, SubtitleMethod = subtitleMethod ?? SubtitleDeliveryMethod.Encode, @@ -550,6 +556,8 @@ namespace Jellyfin.Api.Controllers /// <param name="startTimeTicks">Optional. Specify a starting offset, in ticks. 1 tick = 10000 ms.</param> /// <param name="width">Optional. The fixed horizontal resolution of the encoded video.</param> /// <param name="height">Optional. The fixed vertical resolution of the encoded video.</param> + /// <param name="maxWidth">Optional. The maximum horizontal resolution of the encoded video.</param> + /// <param name="maxHeight">Optional. The maximum vertical resolution of the encoded video.</param> /// <param name="videoBitRate">Optional. Specify a video bitrate to encode to, e.g. 500000. If omitted this will be left to encoder defaults.</param> /// <param name="subtitleStreamIndex">Optional. The index of the subtitle stream to use. If omitted no subtitles will be used.</param> /// <param name="subtitleMethod">Optional. Specify the subtitle delivery method.</param> @@ -606,6 +614,8 @@ namespace Jellyfin.Api.Controllers [FromQuery] long? startTimeTicks, [FromQuery] int? width, [FromQuery] int? height, + [FromQuery] int? maxWidth, + [FromQuery] int? maxHeight, [FromQuery] int? videoBitRate, [FromQuery] int? subtitleStreamIndex, [FromQuery] SubtitleDeliveryMethod? subtitleMethod, @@ -657,6 +667,8 @@ namespace Jellyfin.Api.Controllers startTimeTicks, width, height, + maxWidth, + maxHeight, videoBitRate, subtitleStreamIndex, subtitleMethod, |
