|
|
|
@ -12,6 +12,8 @@ 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;
|
|
|
|
|
using MediaBrowser.Controller.Library;
|
|
|
|
|
using MediaBrowser.Controller.MediaEncoding;
|
|
|
|
@ -22,6 +24,7 @@ using MediaBrowser.Model.Entities;
|
|
|
|
|
using MediaBrowser.Model.IO;
|
|
|
|
|
using MediaBrowser.Model.Net;
|
|
|
|
|
using MediaBrowser.Model.Providers;
|
|
|
|
|
using MediaBrowser.Model.Subtitles;
|
|
|
|
|
using Microsoft.AspNetCore.Authorization;
|
|
|
|
|
using Microsoft.AspNetCore.Http;
|
|
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
@ -35,6 +38,7 @@ namespace Jellyfin.Api.Controllers
|
|
|
|
|
[Route("")]
|
|
|
|
|
public class SubtitleController : BaseJellyfinApiController
|
|
|
|
|
{
|
|
|
|
|
private readonly IServerConfigurationManager _serverConfigurationManager;
|
|
|
|
|
private readonly ILibraryManager _libraryManager;
|
|
|
|
|
private readonly ISubtitleManager _subtitleManager;
|
|
|
|
|
private readonly ISubtitleEncoder _subtitleEncoder;
|
|
|
|
@ -47,6 +51,7 @@ namespace Jellyfin.Api.Controllers
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Initializes a new instance of the <see cref="SubtitleController"/> class.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="serverConfigurationManager">Instance of <see cref="IServerConfigurationManager"/> interface.</param>
|
|
|
|
|
/// <param name="libraryManager">Instance of <see cref="ILibraryManager"/> interface.</param>
|
|
|
|
|
/// <param name="subtitleManager">Instance of <see cref="ISubtitleManager"/> interface.</param>
|
|
|
|
|
/// <param name="subtitleEncoder">Instance of <see cref="ISubtitleEncoder"/> interface.</param>
|
|
|
|
@ -56,6 +61,7 @@ namespace Jellyfin.Api.Controllers
|
|
|
|
|
/// <param name="authContext">Instance of <see cref="IAuthorizationContext"/> interface.</param>
|
|
|
|
|
/// <param name="logger">Instance of <see cref="ILogger{SubtitleController}"/> interface.</param>
|
|
|
|
|
public SubtitleController(
|
|
|
|
|
IServerConfigurationManager serverConfigurationManager,
|
|
|
|
|
ILibraryManager libraryManager,
|
|
|
|
|
ISubtitleManager subtitleManager,
|
|
|
|
|
ISubtitleEncoder subtitleEncoder,
|
|
|
|
@ -65,6 +71,7 @@ namespace Jellyfin.Api.Controllers
|
|
|
|
|
IAuthorizationContext authContext,
|
|
|
|
|
ILogger<SubtitleController> logger)
|
|
|
|
|
{
|
|
|
|
|
_serverConfigurationManager = serverConfigurationManager;
|
|
|
|
|
_libraryManager = libraryManager;
|
|
|
|
|
_subtitleManager = subtitleManager;
|
|
|
|
|
_subtitleEncoder = subtitleEncoder;
|
|
|
|
@ -379,5 +386,95 @@ namespace Jellyfin.Api.Controllers
|
|
|
|
|
copyTimestamps,
|
|
|
|
|
CancellationToken.None);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets a list of available fallback font files.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <response code="200">Information retrieved.</response>
|
|
|
|
|
/// <returns>An array of <see cref="FontFile"/> with the available font files.</returns>
|
|
|
|
|
[HttpGet("FallbackFont/Fonts")]
|
|
|
|
|
[Authorize(Policy = Policies.DefaultAuthorization)]
|
|
|
|
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
|
|
|
public IEnumerable<FontFile> GetFallbackFontList()
|
|
|
|
|
{
|
|
|
|
|
var encodingOptions = _serverConfigurationManager.GetEncodingOptions();
|
|
|
|
|
var fallbackFontPath = encodingOptions.FallbackFontPath;
|
|
|
|
|
|
|
|
|
|
if (!string.IsNullOrEmpty(fallbackFontPath))
|
|
|
|
|
{
|
|
|
|
|
var files = _fileSystem.GetFiles(fallbackFontPath, new[] { ".woff", ".woff2", ".ttf", ".otf" }, false, false);
|
|
|
|
|
var fontFiles = files
|
|
|
|
|
.Select(i => new FontFile
|
|
|
|
|
{
|
|
|
|
|
Name = i.Name,
|
|
|
|
|
Size = i.Length,
|
|
|
|
|
DateCreated = _fileSystem.GetCreationTimeUtc(i),
|
|
|
|
|
DateModified = _fileSystem.GetLastWriteTimeUtc(i)
|
|
|
|
|
})
|
|
|
|
|
.OrderBy(i => i.Size)
|
|
|
|
|
.ThenBy(i => i.Name)
|
|
|
|
|
.ThenByDescending(i => i.DateModified)
|
|
|
|
|
.ThenByDescending(i => i.DateCreated);
|
|
|
|
|
// max total size 20M
|
|
|
|
|
const int MaxSize = 20971520;
|
|
|
|
|
var sizeCounter = 0L;
|
|
|
|
|
foreach (var fontFile in fontFiles)
|
|
|
|
|
{
|
|
|
|
|
sizeCounter += fontFile.Size;
|
|
|
|
|
if (sizeCounter >= MaxSize)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogWarning("Some fonts will not be sent due to size limitations");
|
|
|
|
|
yield break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
yield return fontFile;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
_logger.LogWarning("The path of fallback font folder has not been set");
|
|
|
|
|
encodingOptions.EnableFallbackFont = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets a fallback font file.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="name">The name of the fallback font file to get.</param>
|
|
|
|
|
/// <response code="200">Fallback font file retrieved.</response>
|
|
|
|
|
/// <returns>The fallback font file.</returns>
|
|
|
|
|
[HttpGet("FallbackFont/Fonts/{name}")]
|
|
|
|
|
[Authorize(Policy = Policies.DefaultAuthorization)]
|
|
|
|
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
|
|
|
public ActionResult GetFallbackFont([FromRoute, Required] string name)
|
|
|
|
|
{
|
|
|
|
|
var encodingOptions = _serverConfigurationManager.GetEncodingOptions();
|
|
|
|
|
var fallbackFontPath = encodingOptions.FallbackFontPath;
|
|
|
|
|
|
|
|
|
|
if (!string.IsNullOrEmpty(fallbackFontPath))
|
|
|
|
|
{
|
|
|
|
|
var fontFile = _fileSystem.GetFiles(fallbackFontPath)
|
|
|
|
|
.First(i => string.Equals(i.Name, name, StringComparison.OrdinalIgnoreCase));
|
|
|
|
|
var fileSize = fontFile?.Length;
|
|
|
|
|
|
|
|
|
|
if (fontFile != null && fileSize != null && fileSize > 0)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogDebug("Fallback font size is {fileSize} Bytes", fileSize);
|
|
|
|
|
return PhysicalFile(fontFile.FullName, MimeTypes.GetMimeType(fontFile.FullName));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
_logger.LogWarning("The selected font is null or empty");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
_logger.LogWarning("The path of fallback font folder has not been set");
|
|
|
|
|
encodingOptions.EnableFallbackFont = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// returning HTTP 204 will break the SubtitlesOctopus
|
|
|
|
|
return Ok();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|