diff options
| author | nyanmisaka <nst799610810@gmail.com> | 2020-11-08 19:11:54 +0800 |
|---|---|---|
| committer | nyanmisaka <nst799610810@gmail.com> | 2020-11-08 19:11:54 +0800 |
| commit | 737cb727f9f943f8bb55fca8a5c5023a98aca2d7 (patch) | |
| tree | 8858a423545a03d0f7dfe5c1d1b0ae1157d62c5e /Jellyfin.Api/Controllers/SubtitleController.cs | |
| parent | 05e78ee78c56364971956507f6239ded61f0af87 (diff) | |
| parent | 96dcd9c87e2eb4b14004368856949e9fde2db261 (diff) | |
Merge remote-tracking branch 'upstream/master' into fonts
Diffstat (limited to 'Jellyfin.Api/Controllers/SubtitleController.cs')
| -rw-r--r-- | Jellyfin.Api/Controllers/SubtitleController.cs | 67 |
1 files changed, 50 insertions, 17 deletions
diff --git a/Jellyfin.Api/Controllers/SubtitleController.cs b/Jellyfin.Api/Controllers/SubtitleController.cs index 8550a86e0..4c9a15384 100644 --- a/Jellyfin.Api/Controllers/SubtitleController.cs +++ b/Jellyfin.Api/Controllers/SubtitleController.cs @@ -9,7 +9,9 @@ using System.Net.Mime; using System.Text; using System.Threading; using System.Threading.Tasks; +using Jellyfin.Api.Attributes; using Jellyfin.Api.Constants; +using Jellyfin.Api.Models.SubtitleDtos; using MediaBrowser.Common.Configuration; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; @@ -93,8 +95,8 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status404NotFound)] public ActionResult<Task> DeleteSubtitle( - [FromRoute] Guid itemId, - [FromRoute] int index) + [FromRoute, Required] Guid itemId, + [FromRoute, Required] int index) { var item = _libraryManager.GetItemById(itemId); @@ -119,8 +121,8 @@ namespace Jellyfin.Api.Controllers [Authorize(Policy = Policies.DefaultAuthorization)] [ProducesResponseType(StatusCodes.Status200OK)] public async Task<ActionResult<IEnumerable<RemoteSubtitleInfo>>> SearchRemoteSubtitles( - [FromRoute] Guid itemId, - [FromRoute, Required] string? language, + [FromRoute, Required] Guid itemId, + [FromRoute, Required] string language, [FromQuery] bool? isPerfectMatch) { var video = (Video)_libraryManager.GetItemById(itemId); @@ -139,8 +141,8 @@ namespace Jellyfin.Api.Controllers [Authorize(Policy = Policies.DefaultAuthorization)] [ProducesResponseType(StatusCodes.Status204NoContent)] public async Task<ActionResult> DownloadRemoteSubtitles( - [FromRoute] Guid itemId, - [FromRoute, Required] string? subtitleId) + [FromRoute, Required] Guid itemId, + [FromRoute, Required] string subtitleId) { var video = (Video)_libraryManager.GetItemById(itemId); @@ -169,7 +171,8 @@ namespace Jellyfin.Api.Controllers [Authorize(Policy = Policies.DefaultAuthorization)] [ProducesResponseType(StatusCodes.Status200OK)] [Produces(MediaTypeNames.Application.Octet)] - public async Task<ActionResult> GetRemoteSubtitles([FromRoute, Required] string? id) + [ProducesFile("text/*")] + public async Task<ActionResult> GetRemoteSubtitles([FromRoute, Required] string id) { var result = await _subtitleManager.GetRemoteSubtitles(id, CancellationToken.None).ConfigureAwait(false); @@ -192,11 +195,12 @@ namespace Jellyfin.Api.Controllers [HttpGet("Videos/{itemId}/{mediaSourceId}/Subtitles/{index}/Stream.{format}")] [HttpGet("Videos/{itemId}/{mediaSourceId}/Subtitles/{index}/{startPositionTicks?}/Stream.{format}", Name = "GetSubtitle_2")] [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesFile("text/*")] public async Task<ActionResult> GetSubtitle( [FromRoute, Required] Guid itemId, - [FromRoute, Required] string? mediaSourceId, + [FromRoute, Required] string mediaSourceId, [FromRoute, Required] int index, - [FromRoute, Required] string? format, + [FromRoute, Required] string format, [FromQuery] long? endPositionTicks, [FromQuery] bool copyTimestamps = false, [FromQuery] bool addVttTimeMap = false, @@ -218,8 +222,7 @@ namespace Jellyfin.Api.Controllers var subtitleStream = mediaSource.MediaStreams .First(i => i.Type == MediaStreamType.Subtitle && i.Index == index); - FileStream stream = new FileStream(subtitleStream.Path, FileMode.Open, FileAccess.Read); - return File(stream, MimeTypes.GetMimeType(subtitleStream.Path)); + return PhysicalFile(subtitleStream.Path, MimeTypes.GetMimeType(subtitleStream.Path)); } if (string.Equals(format, "vtt", StringComparison.OrdinalIgnoreCase) && addVttTimeMap) @@ -258,11 +261,12 @@ namespace Jellyfin.Api.Controllers [HttpGet("Videos/{itemId}/{mediaSourceId}/Subtitles/{index}/subtitles.m3u8")] [Authorize(Policy = Policies.DefaultAuthorization)] [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesPlaylistFile] [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "index", Justification = "Imported from ServiceStack")] public async Task<ActionResult> GetSubtitlePlaylist( - [FromRoute] Guid itemId, - [FromRoute] int index, - [FromRoute] string? mediaSourceId, + [FromRoute, Required] Guid itemId, + [FromRoute, Required] int index, + [FromRoute, Required] string mediaSourceId, [FromQuery, Required] int segmentLength) { var item = (Video)_libraryManager.GetItemById(itemId); @@ -285,7 +289,8 @@ namespace Jellyfin.Api.Controllers var builder = new StringBuilder(); builder.AppendLine("#EXTM3U") .Append("#EXT-X-TARGETDURATION:") - .AppendLine(segmentLength.ToString(CultureInfo.InvariantCulture)) + .Append(segmentLength) + .AppendLine() .AppendLine("#EXT-X-VERSION:3") .AppendLine("#EXT-X-MEDIA-SEQUENCE:0") .AppendLine("#EXT-X-PLAYLIST-TYPE:VOD"); @@ -300,8 +305,9 @@ namespace Jellyfin.Api.Controllers var lengthTicks = Math.Min(remaining, segmentLengthTicks); builder.Append("#EXTINF:") - .Append(TimeSpan.FromTicks(lengthTicks).TotalSeconds.ToString(CultureInfo.InvariantCulture)) - .AppendLine(","); + .Append(TimeSpan.FromTicks(lengthTicks).TotalSeconds) + .Append(',') + .AppendLine(); var endPositionTicks = Math.Min(runtime, positionTicks + segmentLengthTicks); @@ -322,6 +328,33 @@ namespace Jellyfin.Api.Controllers } /// <summary> + /// Upload an external subtitle file. + /// </summary> + /// <param name="itemId">The item the subtitle belongs to.</param> + /// <param name="body">The request body.</param> + /// <response code="204">Subtitle uploaded.</response> + /// <returns>A <see cref="NoContentResult"/>.</returns> + [HttpPost("Videos/{itemId}/Subtitles")] + public async Task<ActionResult> UploadSubtitle( + [FromRoute, Required] Guid itemId, + [FromBody, Required] UploadSubtitleDto body) + { + var video = (Video)_libraryManager.GetItemById(itemId); + var data = Convert.FromBase64String(body.Data); + await using var memoryStream = new MemoryStream(data); + await _subtitleManager.UploadSubtitle( + video, + new SubtitleResponse + { + Format = body.Format, + Language = body.Language, + IsForced = body.IsForced, + Stream = memoryStream + }).ConfigureAwait(false); + return NoContent(); + } + + /// <summary> /// Encodes a subtitle in the specified format. /// </summary> /// <param name="id">The media id.</param> |
