Create a proxy for the trasncoder

This commit is contained in:
Zoe Roux 2023-04-25 00:37:21 +09:00
parent c96db3a3dc
commit 3ab76006af
No known key found for this signature in database
7 changed files with 57 additions and 147 deletions

View File

@ -16,9 +16,9 @@
// You should have received a copy of the GNU General Public License
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
using System;
using System.Collections.Generic;
using System.Linq;
using AspNetCore.Proxy;
using Autofac;
using Kyoo.Abstractions;
using Kyoo.Abstractions.Controllers;
@ -113,6 +113,7 @@ namespace Kyoo.Core
x.EnableForHttps = true;
});
services.AddProxies();
services.AddHttpClient();
}

View File

@ -12,6 +12,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AspNetCore.Proxy" Version="4.4.0" />
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.7" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="5.0.8" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />

View File

@ -0,0 +1,48 @@
// Kyoo - A portable and vast media library solution.
// Copyright (c) Kyoo.
//
// See AUTHORS.md and LICENSE file in the project root for full license information.
//
// Kyoo is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// Kyoo is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
using System.Threading.Tasks;
using AspNetCore.Proxy;
using Kyoo.Abstractions.Models.Permissions;
using Microsoft.AspNetCore.Mvc;
namespace Kyoo.Core.Api
{
/// <summary>
/// Proxy to other services
/// </summary>
[ApiController]
public class ProxyApi : Controller
{
/// <summary>
/// Transcoder proxy
/// </summary>
/// <remarks>
/// Simply proxy requests to the transcoder
/// </remarks>
/// <param name="rest">The path of the transcoder.</param>
/// <returns>The return value of the transcoder.</returns>
[Route("video/{**rest}")]
[Permission("video", Kind.Read)]
public Task Proxy(string rest)
{
// TODO: Use an env var to configure transcoder:7666.
return this.HttpProxyAsync($"http://transcoder:7666/{rest}");
}
}
}

View File

@ -1,146 +0,0 @@
// Kyoo - A portable and vast media library solution.
// Copyright (c) Kyoo.
//
// See AUTHORS.md and LICENSE file in the project root for full license information.
//
// Kyoo is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// Kyoo is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
using System.IO;
using System.Threading.Tasks;
using Kyoo.Abstractions.Controllers;
using Kyoo.Abstractions.Models;
using Kyoo.Abstractions.Models.Attributes;
using Kyoo.Abstractions.Models.Permissions;
using Kyoo.Abstractions.Models.Utils;
using Kyoo.Core.Models.Options;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Options;
using static Kyoo.Abstractions.Models.Utils.Constants;
namespace Kyoo.Core.Api
{
/// <summary>
/// Get the video in a raw format or transcoded in the codec you want.
/// </summary>
[Route("videos")]
[Route("video", Order = AlternativeRoute)]
[ApiController]
[ApiDefinition("Videos", Group = WatchGroup)]
public class VideoApi : Controller
{
/// <summary>
/// The library manager used to modify or retrieve information in the data store.
/// </summary>
private readonly ILibraryManager _libraryManager;
/// <summary>
/// The file system used to send video files.
/// </summary>
private readonly IFileSystem _files;
/// <summary>
/// Create a new <see cref="VideoApi"/>.
/// </summary>
/// <param name="libraryManager">The library manager used to retrieve episodes.</param>
/// <param name="files">The file manager used to send video files.</param>
public VideoApi(ILibraryManager libraryManager,
IFileSystem files)
{
_libraryManager = libraryManager;
_files = files;
}
/// <inheritdoc />
/// <remarks>
/// Disabling the cache prevent an issue on firefox that skip the last 30 seconds of HLS files
/// </remarks>
public override void OnActionExecuted(ActionExecutedContext ctx)
{
base.OnActionExecuted(ctx);
ctx.HttpContext.Response.Headers.Add("Cache-Control", "no-cache, no-store, must-revalidate");
ctx.HttpContext.Response.Headers.Add("Pragma", "no-cache");
ctx.HttpContext.Response.Headers.Add("Expires", "0");
}
/// <summary>
/// Direct video
/// </summary>
/// <remarks>
/// Retrieve the raw video stream, in the same container as the one on the server. No transcoding or
/// transmuxing is done.
/// </remarks>
/// <param name="identifier">The identifier of the episode to retrieve.</param>
/// <returns>The raw video stream</returns>
/// <response code="404">No episode exists for the given identifier.</response>
// TODO enable the following line, this is disabled since the web app can't use bearers. [Permission("video", Kind.Read)]
[HttpGet("direct/{identifier:id}")]
[HttpGet("{identifier:id}", Order = AlternativeRoute)]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> Direct(Identifier identifier)
{
Episode episode = await identifier.Match(
id => _libraryManager.GetOrDefault<Episode>(id),
slug => _libraryManager.GetOrDefault<Episode>(slug)
);
return _files.FileResult(episode?.Path, true);
}
/// <summary>
/// Transmux video
/// </summary>
/// <remarks>
/// Change the container of the video to hls but don't re-encode the video or audio. This doesn't require mutch
/// resources from the server.
/// </remarks>
/// <param name="identifier">The identifier of the episode to retrieve.</param>
/// <returns>The transmuxed video stream</returns>
/// <response code="404">No episode exists for the given identifier.</response>
[HttpGet("transmux/{identifier:id}/master.m3u8")]
[Permission("video", Kind.Read)]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> Transmux(Identifier identifier)
{
Episode episode = await identifier.Match(
id => _libraryManager.GetOrDefault<Episode>(id),
slug => _libraryManager.GetOrDefault<Episode>(slug)
);
return _files.Transmux(episode);
}
/// <summary>
/// Transmuxed chunk
/// </summary>
/// <remarks>
/// Retrieve a chunk of a transmuxed video.
/// </remarks>
/// <param name="episodeLink">The identifier of the episode.</param>
/// <param name="chunk">The identifier of the chunk to retrieve.</param>
/// <param name="options">The options used to retrieve the path of the segments.</param>
/// <returns>A transmuxed video chunk.</returns>
[HttpGet("transmux/{episodeLink}/segments/{chunk}", Order = AlternativeRoute)]
[Permission("video", Kind.Read)]
[ProducesResponseType(StatusCodes.Status200OK)]
public IActionResult GetTransmuxedChunk(string episodeLink, string chunk,
[FromServices] IOptions<BasicOptions> options)
{
string path = Path.GetFullPath(Path.Combine(options.Value.TransmuxPath, episodeLink));
path = Path.Combine(path, "segments", chunk);
return PhysicalFile(path, "video/MP2T");
}
}
}

View File

@ -57,6 +57,8 @@ services:
ports:
- "7666:7666"
restart: on-failure
env_file:
- ./.env
volumes:
- ./transcoder:/app
- ${LIBRARY_ROOT}:/video

View File

@ -37,6 +37,8 @@ services:
transcoder:
image: zoriya/kyoo_transcoder:edge
restart: on-failure
env_file:
- ./.env
volumes:
- ${LIBRARY_ROOT}:/video
- ${CACHE_ROOT}:/cache

View File

@ -37,6 +37,8 @@ services:
transcoder:
build: ./transcoder
restart: on-failure
env_file:
- ./.env
volumes:
- ${LIBRARY_ROOT}:/video
- ${CACHE_ROOT}:/cache