aboutsummaryrefslogtreecommitdiff
path: root/Jellyfin.Api/Controllers/SubtitleController.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Jellyfin.Api/Controllers/SubtitleController.cs')
-rw-r--r--Jellyfin.Api/Controllers/SubtitleController.cs76
1 files changed, 53 insertions, 23 deletions
diff --git a/Jellyfin.Api/Controllers/SubtitleController.cs b/Jellyfin.Api/Controllers/SubtitleController.cs
index 16a47f2d8..16acedcf3 100644
--- a/Jellyfin.Api/Controllers/SubtitleController.cs
+++ b/Jellyfin.Api/Controllers/SubtitleController.cs
@@ -127,7 +127,7 @@ namespace Jellyfin.Api.Controllers
{
var video = (Video)_libraryManager.GetItemById(itemId);
- return await _subtitleManager.SearchSubtitles(video, language, isPerfectMatch, CancellationToken.None).ConfigureAwait(false);
+ return await _subtitleManager.SearchSubtitles(video, language, isPerfectMatch, false, CancellationToken.None).ConfigureAwait(false);
}
/// <summary>
@@ -182,6 +182,10 @@ namespace Jellyfin.Api.Controllers
/// <summary>
/// Gets subtitles in a specified format.
/// </summary>
+ /// <param name="routeItemId">The (route) item id.</param>
+ /// <param name="routeMediaSourceId">The (route) media source id.</param>
+ /// <param name="routeIndex">The (route) subtitle stream index.</param>
+ /// <param name="routeFormat">The (route) format of the returned subtitle.</param>
/// <param name="itemId">The item id.</param>
/// <param name="mediaSourceId">The media source id.</param>
/// <param name="index">The subtitle stream index.</param>
@@ -189,22 +193,32 @@ namespace Jellyfin.Api.Controllers
/// <param name="endPositionTicks">Optional. The end position of the subtitle in ticks.</param>
/// <param name="copyTimestamps">Optional. Whether to copy the timestamps.</param>
/// <param name="addVttTimeMap">Optional. Whether to add a VTT time map.</param>
- /// <param name="startPositionTicks">Optional. The start position of the subtitle in ticks.</param>
+ /// <param name="startPositionTicks">The start position of the subtitle in ticks.</param>
/// <response code="200">File returned.</response>
/// <returns>A <see cref="FileContentResult"/> with the subtitle file.</returns>
- [HttpGet("Videos/{itemId}/{mediaSourceId}/Subtitles/{index}/Stream.{format}")]
+ [HttpGet("Videos/{routeItemId}/{routeMediaSourceId}/Subtitles/{routeIndex}/Stream.{routeFormat}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesFile("text/*")]
public async Task<ActionResult> GetSubtitle(
- [FromRoute, Required] Guid itemId,
- [FromRoute, Required] string mediaSourceId,
- [FromRoute, Required] int index,
- [FromRoute, Required] string format,
+ [FromRoute, Required] Guid routeItemId,
+ [FromRoute, Required] string routeMediaSourceId,
+ [FromRoute, Required] int routeIndex,
+ [FromRoute, Required] string routeFormat,
+ [FromQuery, ParameterObsolete] Guid? itemId,
+ [FromQuery, ParameterObsolete] string? mediaSourceId,
+ [FromQuery, ParameterObsolete] int? index,
+ [FromQuery, ParameterObsolete] string? format,
[FromQuery] long? endPositionTicks,
[FromQuery] bool copyTimestamps = false,
[FromQuery] bool addVttTimeMap = false,
[FromQuery] long startPositionTicks = 0)
{
+ // Set parameters to route value if not provided via query.
+ itemId ??= routeItemId;
+ mediaSourceId ??= routeMediaSourceId;
+ index ??= routeIndex;
+ format ??= routeFormat;
+
if (string.Equals(format, "js", StringComparison.OrdinalIgnoreCase))
{
format = "json";
@@ -212,9 +226,9 @@ namespace Jellyfin.Api.Controllers
if (string.IsNullOrEmpty(format))
{
- var item = (Video)_libraryManager.GetItemById(itemId);
+ var item = (Video)_libraryManager.GetItemById(itemId.Value);
- var idString = itemId.ToString("N", CultureInfo.InvariantCulture);
+ var idString = itemId.Value.ToString("N", CultureInfo.InvariantCulture);
var mediaSource = _mediaSourceManager.GetStaticMediaSources(item, false)
.First(i => string.Equals(i.Id, mediaSourceId ?? idString, StringComparison.Ordinal));
@@ -226,7 +240,7 @@ namespace Jellyfin.Api.Controllers
if (string.Equals(format, "vtt", StringComparison.OrdinalIgnoreCase) && addVttTimeMap)
{
- await using Stream stream = await EncodeSubtitles(itemId, mediaSourceId, index, format, startPositionTicks, endPositionTicks, copyTimestamps).ConfigureAwait(false);
+ await using Stream stream = await EncodeSubtitles(itemId.Value, mediaSourceId, index.Value, format, startPositionTicks, endPositionTicks, copyTimestamps).ConfigureAwait(false);
using var reader = new StreamReader(stream);
var text = await reader.ReadToEndAsync().ConfigureAwait(false);
@@ -238,9 +252,9 @@ namespace Jellyfin.Api.Controllers
return File(
await EncodeSubtitles(
- itemId,
+ itemId.Value,
mediaSourceId,
- index,
+ index.Value,
format,
startPositionTicks,
endPositionTicks,
@@ -251,30 +265,44 @@ namespace Jellyfin.Api.Controllers
/// <summary>
/// Gets subtitles in a specified format.
/// </summary>
+ /// <param name="routeItemId">The (route) item id.</param>
+ /// <param name="routeMediaSourceId">The (route) media source id.</param>
+ /// <param name="routeIndex">The (route) subtitle stream index.</param>
+ /// <param name="routeStartPositionTicks">The (route) start position of the subtitle in ticks.</param>
+ /// <param name="routeFormat">The (route) format of the returned subtitle.</param>
/// <param name="itemId">The item id.</param>
/// <param name="mediaSourceId">The media source id.</param>
/// <param name="index">The subtitle stream index.</param>
- /// <param name="startPositionTicks">Optional. The start position of the subtitle in ticks.</param>
+ /// <param name="startPositionTicks">The start position of the subtitle in ticks.</param>
/// <param name="format">The format of the returned subtitle.</param>
/// <param name="endPositionTicks">Optional. The end position of the subtitle in ticks.</param>
/// <param name="copyTimestamps">Optional. Whether to copy the timestamps.</param>
/// <param name="addVttTimeMap">Optional. Whether to add a VTT time map.</param>
/// <response code="200">File returned.</response>
/// <returns>A <see cref="FileContentResult"/> with the subtitle file.</returns>
- [HttpGet("Videos/{itemId}/{mediaSourceId}/Subtitles/{index}/{startPositionTicks}/Stream.{format}")]
+ [HttpGet("Videos/{routeItemId}/{routeMediaSourceId}/Subtitles/{routeIndex}/{routeStartPositionTicks}/Stream.{routeFormat}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesFile("text/*")]
public Task<ActionResult> GetSubtitleWithTicks(
- [FromRoute, Required] Guid itemId,
- [FromRoute, Required] string mediaSourceId,
- [FromRoute, Required] int index,
- [FromRoute, Required] long startPositionTicks,
- [FromRoute, Required] string format,
+ [FromRoute, Required] Guid routeItemId,
+ [FromRoute, Required] string routeMediaSourceId,
+ [FromRoute, Required] int routeIndex,
+ [FromRoute, Required] long routeStartPositionTicks,
+ [FromRoute, Required] string routeFormat,
+ [FromQuery, ParameterObsolete] Guid? itemId,
+ [FromQuery, ParameterObsolete] string? mediaSourceId,
+ [FromQuery, ParameterObsolete] int? index,
+ [FromQuery, ParameterObsolete] long? startPositionTicks,
+ [FromQuery, ParameterObsolete] string? format,
[FromQuery] long? endPositionTicks,
[FromQuery] bool copyTimestamps = false,
[FromQuery] bool addVttTimeMap = false)
{
return GetSubtitle(
+ routeItemId,
+ routeMediaSourceId,
+ routeIndex,
+ routeFormat,
itemId,
mediaSourceId,
index,
@@ -282,7 +310,7 @@ namespace Jellyfin.Api.Controllers
endPositionTicks,
copyTimestamps,
addVttTimeMap,
- startPositionTicks);
+ startPositionTicks ?? routeStartPositionTicks);
}
/// <summary>
@@ -333,7 +361,7 @@ namespace Jellyfin.Api.Controllers
long positionTicks = 0;
- var accessToken = _authContext.GetAuthorizationInfo(Request).Token;
+ var accessToken = (await _authContext.GetAuthorizationInfo(Request).ConfigureAwait(false)).Token;
while (positionTicks < runtime)
{
@@ -348,7 +376,7 @@ namespace Jellyfin.Api.Controllers
var endPositionTicks = Math.Min(runtime, positionTicks + segmentLengthTicks);
var url = string.Format(
- CultureInfo.CurrentCulture,
+ CultureInfo.InvariantCulture,
"stream.vtt?CopyTimestamps=true&AddVttTimeMap=true&StartPositionTicks={0}&EndPositionTicks={1}&api_key={2}",
positionTicks.ToString(CultureInfo.InvariantCulture),
endPositionTicks.ToString(CultureInfo.InvariantCulture),
@@ -389,6 +417,8 @@ namespace Jellyfin.Api.Controllers
IsForced = body.IsForced,
Stream = memoryStream
}).ConfigureAwait(false);
+ _providerManager.QueueRefresh(video.Id, new MetadataRefreshOptions(new DirectoryService(_fileSystem)), RefreshPriority.High);
+
return NoContent();
}
@@ -498,7 +528,7 @@ namespace Jellyfin.Api.Controllers
if (fontFile != null && fileSize != null && fileSize > 0)
{
- _logger.LogDebug("Fallback font size is {fileSize} Bytes", fileSize);
+ _logger.LogDebug("Fallback font size is {FileSize} Bytes", fileSize);
return PhysicalFile(fontFile.FullName, MimeTypes.GetMimeType(fontFile.FullName));
}
else