aboutsummaryrefslogtreecommitdiff
path: root/Jellyfin.Api/Controllers/VideoHlsController.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Jellyfin.Api/Controllers/VideoHlsController.cs')
-rw-r--r--Jellyfin.Api/Controllers/VideoHlsController.cs44
1 files changed, 16 insertions, 28 deletions
diff --git a/Jellyfin.Api/Controllers/VideoHlsController.cs b/Jellyfin.Api/Controllers/VideoHlsController.cs
index e95410d02..ef25db8c9 100644
--- a/Jellyfin.Api/Controllers/VideoHlsController.cs
+++ b/Jellyfin.Api/Controllers/VideoHlsController.cs
@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.IO;
-using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Api.Attributes;
@@ -20,12 +19,10 @@ using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Dlna;
-using MediaBrowser.Model.IO;
using MediaBrowser.Model.Net;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
-using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
namespace Jellyfin.Api.Controllers
@@ -48,9 +45,6 @@ namespace Jellyfin.Api.Controllers
private readonly IMediaSourceManager _mediaSourceManager;
private readonly IServerConfigurationManager _serverConfigurationManager;
private readonly IMediaEncoder _mediaEncoder;
- private readonly IFileSystem _fileSystem;
- private readonly ISubtitleEncoder _subtitleEncoder;
- private readonly IConfiguration _configuration;
private readonly IDeviceManager _deviceManager;
private readonly TranscodingJobHelper _transcodingJobHelper;
private readonly ILogger<VideoHlsController> _logger;
@@ -60,9 +54,6 @@ namespace Jellyfin.Api.Controllers
/// Initializes a new instance of the <see cref="VideoHlsController"/> class.
/// </summary>
/// <param name="mediaEncoder">Instance of the <see cref="IMediaEncoder"/> interface.</param>
- /// <param name="fileSystem">Instance of the <see cref="IFileSystem"/> interface.</param>
- /// <param name="subtitleEncoder">Instance of the <see cref="ISubtitleEncoder"/> interface.</param>
- /// <param name="configuration">Instance of the <see cref="IConfiguration"/> interface.</param>
/// <param name="dlnaManager">Instance of the <see cref="IDlnaManager"/> interface.</param>
/// <param name="userManger">Instance of the <see cref="IUserManager"/> interface.</param>
/// <param name="authorizationContext">Instance of the <see cref="IAuthorizationContext"/> interface.</param>
@@ -72,11 +63,9 @@ namespace Jellyfin.Api.Controllers
/// <param name="deviceManager">Instance of the <see cref="IDeviceManager"/> interface.</param>
/// <param name="transcodingJobHelper">The <see cref="TranscodingJobHelper"/> singleton.</param>
/// <param name="logger">Instance of the <see cref="ILogger{VideoHlsController}"/>.</param>
+ /// <param name="encodingHelper">Instance of <see cref="EncodingHelper"/>.</param>
public VideoHlsController(
IMediaEncoder mediaEncoder,
- IFileSystem fileSystem,
- ISubtitleEncoder subtitleEncoder,
- IConfiguration configuration,
IDlnaManager dlnaManager,
IUserManager userManger,
IAuthorizationContext authorizationContext,
@@ -85,10 +74,9 @@ namespace Jellyfin.Api.Controllers
IServerConfigurationManager serverConfigurationManager,
IDeviceManager deviceManager,
TranscodingJobHelper transcodingJobHelper,
- ILogger<VideoHlsController> logger)
+ ILogger<VideoHlsController> logger,
+ EncodingHelper encodingHelper)
{
- _encodingHelper = new EncodingHelper(mediaEncoder, fileSystem, subtitleEncoder, configuration);
-
_dlnaManager = dlnaManager;
_authContext = authorizationContext;
_userManager = userManger;
@@ -96,12 +84,11 @@ namespace Jellyfin.Api.Controllers
_mediaSourceManager = mediaSourceManager;
_serverConfigurationManager = serverConfigurationManager;
_mediaEncoder = mediaEncoder;
- _fileSystem = fileSystem;
- _subtitleEncoder = subtitleEncoder;
- _configuration = configuration;
_deviceManager = deviceManager;
_transcodingJobHelper = transcodingJobHelper;
_logger = logger;
+ _encodingHelper = encodingHelper;
+
_encodingOptions = serverConfigurationManager.GetEncodingOptions();
}
@@ -150,7 +137,7 @@ namespace Jellyfin.Api.Controllers
/// <param name="cpuCoreLimit">Optional. The limit of how many cpu cores to use.</param>
/// <param name="liveStreamId">The live stream id.</param>
/// <param name="enableMpegtsM2TsMode">Optional. Whether to enable the MpegtsM2Ts mode.</param>
- /// <param name="videoCodec">Optional. Specify a video codec to encode to, e.g. h264. If omitted the server will auto-select using the url's extension. Options: h265, h264, mpeg4, theora, vpx, wmv.</param>
+ /// <param name="videoCodec">Optional. Specify a video codec to encode to, e.g. h264. If omitted the server will auto-select using the url's extension. Options: h265, h264, mpeg4, theora, vp8, vp9, vpx (deprecated), wmv.</param>
/// <param name="subtitleCodec">Optional. Specify a subtitle codec to encode to.</param>
/// <param name="transcodeReasons">Optional. The transcoding reason.</param>
/// <param name="audioStreamIndex">Optional. The index of the audio stream to use. If omitted the first audio stream will be used.</param>
@@ -275,7 +262,11 @@ namespace Jellyfin.Api.Controllers
EnableSubtitlesInManifest = enableSubtitlesInManifest ?? true
};
+ // CTS lifecycle is managed internally.
var cancellationTokenSource = new CancellationTokenSource();
+ // Due to CTS.Token calling ThrowIfDisposed (https://github.com/dotnet/runtime/issues/29970) we have to "cache" the token
+ // since it gets disposed when ffmpeg exits
+ var cancellationToken = cancellationTokenSource.Token;
using var state = await StreamingHelpers.GetStreamingState(
streamingRequest,
Request,
@@ -285,14 +276,12 @@ namespace Jellyfin.Api.Controllers
_libraryManager,
_serverConfigurationManager,
_mediaEncoder,
- _fileSystem,
- _subtitleEncoder,
- _configuration,
+ _encodingHelper,
_dlnaManager,
_deviceManager,
_transcodingJobHelper,
TranscodingJobType,
- cancellationTokenSource.Token)
+ cancellationToken)
.ConfigureAwait(false);
TranscodingJobDto? job = null;
@@ -301,7 +290,7 @@ namespace Jellyfin.Api.Controllers
if (!System.IO.File.Exists(playlistPath))
{
var transcodingLock = _transcodingJobHelper.GetTranscodingLock(playlistPath);
- await transcodingLock.WaitAsync(cancellationTokenSource.Token).ConfigureAwait(false);
+ await transcodingLock.WaitAsync(cancellationToken).ConfigureAwait(false);
try
{
if (!System.IO.File.Exists(playlistPath))
@@ -328,7 +317,7 @@ namespace Jellyfin.Api.Controllers
minSegments = state.MinSegments;
if (minSegments > 0)
{
- await HlsHelpers.WaitForMinimumSegmentCount(playlistPath, minSegments, _logger, cancellationTokenSource.Token).ConfigureAwait(false);
+ await HlsHelpers.WaitForMinimumSegmentCount(playlistPath, minSegments, _logger, cancellationToken).ConfigureAwait(false);
}
}
}
@@ -377,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 + "\"";
@@ -496,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;
}