2
0
Эх сурвалжийг харах

Use proper IHttpContextAccessor

crobibero 4 жил өмнө
parent
commit
c5e9cf15f6

+ 1 - 1
Jellyfin.Api/Controllers/AudioController.cs

@@ -192,7 +192,7 @@ namespace Jellyfin.Api.Controllers
                 StreamOptions = streamOptions
             };
 
-            return await _audioHelper.GetAudioStream(this, _transcodingJobType, streamingRequest).ConfigureAwait(false);
+            return await _audioHelper.GetAudioStream(_transcodingJobType, streamingRequest).ConfigureAwait(false);
         }
     }
 }

+ 3 - 3
Jellyfin.Api/Controllers/DynamicHlsController.cs

@@ -272,7 +272,7 @@ namespace Jellyfin.Api.Controllers
                 EnableAdaptiveBitrateStreaming = enableAdaptiveBitrateStreaming
             };
 
-            return await _dynamicHlsHelper.GetMasterHlsPlaylist(this, _transcodingJobType, streamingRequest, enableAdaptiveBitrateStreaming).ConfigureAwait(false);
+            return await _dynamicHlsHelper.GetMasterHlsPlaylist(_transcodingJobType, streamingRequest, enableAdaptiveBitrateStreaming).ConfigureAwait(false);
         }
 
         /// <summary>
@@ -439,7 +439,7 @@ namespace Jellyfin.Api.Controllers
                 EnableAdaptiveBitrateStreaming = enableAdaptiveBitrateStreaming
             };
 
-            return await _dynamicHlsHelper.GetMasterHlsPlaylist(this, _transcodingJobType, streamingRequest, enableAdaptiveBitrateStreaming).ConfigureAwait(false);
+            return await _dynamicHlsHelper.GetMasterHlsPlaylist(_transcodingJobType, streamingRequest, enableAdaptiveBitrateStreaming).ConfigureAwait(false);
         }
 
         /// <summary>
@@ -1657,7 +1657,7 @@ namespace Jellyfin.Api.Controllers
                 return Task.CompletedTask;
             });
 
-            return FileStreamResponseHelpers.GetStaticFileResult(segmentPath, MimeTypes.GetMimeType(segmentPath)!, false, this);
+            return FileStreamResponseHelpers.GetStaticFileResult(segmentPath, MimeTypes.GetMimeType(segmentPath)!, false, HttpContext);
         }
 
         private long GetEndPositionTicks(StreamState state, int requestedIndex)

+ 2 - 2
Jellyfin.Api/Controllers/HlsSegmentController.cs

@@ -61,7 +61,7 @@ namespace Jellyfin.Api.Controllers
             var file = segmentId + Path.GetExtension(Request.Path);
             file = Path.Combine(_serverConfigurationManager.GetTranscodePath(), file);
 
-            return FileStreamResponseHelpers.GetStaticFileResult(file, MimeTypes.GetMimeType(file)!, false, this);
+            return FileStreamResponseHelpers.GetStaticFileResult(file, MimeTypes.GetMimeType(file)!, false, HttpContext);
         }
 
         /// <summary>
@@ -148,7 +148,7 @@ namespace Jellyfin.Api.Controllers
                 return Task.CompletedTask;
             });
 
-            return FileStreamResponseHelpers.GetStaticFileResult(path, MimeTypes.GetMimeType(path)!, false, this);
+            return FileStreamResponseHelpers.GetStaticFileResult(path, MimeTypes.GetMimeType(path)!, false, HttpContext);
         }
     }
 }

+ 2 - 3
Jellyfin.Api/Controllers/UniversalAudioController.cs

@@ -110,7 +110,6 @@ namespace Jellyfin.Api.Controllers
             [FromQuery] bool breakOnNonKeyFrames,
             [FromQuery] bool enableRedirection = true)
         {
-            bool isHeadRequest = Request.Method == System.Net.WebRequestMethods.Http.Head;
             var deviceProfile = GetDeviceProfile(container, transcodingContainer, audioCodec, transcodingProtocol, breakOnNonKeyFrames, transcodingAudioChannels, maxAudioSampleRate, maxAudioBitDepth, maxAudioChannels);
             _authorizationContext.GetAuthorizationInfo(Request).DeviceId = deviceId;
 
@@ -222,7 +221,7 @@ namespace Jellyfin.Api.Controllers
                     EnableAdaptiveBitrateStreaming = true
                 };
 
-                return await _dynamicHlsHelper.GetMasterHlsPlaylist(this, TranscodingJobType.Hls, dynamicHlsRequestDto, true)
+                return await _dynamicHlsHelper.GetMasterHlsPlaylist(TranscodingJobType.Hls, dynamicHlsRequestDto, true)
                     .ConfigureAwait(false);
             }
 
@@ -251,7 +250,7 @@ namespace Jellyfin.Api.Controllers
                 Context = EncodingContext.Static
             };
 
-            return await _audioHelper.GetAudioStream(this, TranscodingJobType.Progressive, audioStreamingDto).ConfigureAwait(false);
+            return await _audioHelper.GetAudioStream(TranscodingJobType.Progressive, audioStreamingDto).ConfigureAwait(false);
         }
 
         private DeviceProfile GetDeviceProfile(

+ 3 - 4
Jellyfin.Api/Controllers/VideosController.cs

@@ -471,7 +471,7 @@ namespace Jellyfin.Api.Controllers
                 StreamingHelpers.AddDlnaHeaders(state, Response.Headers, true, startTimeTicks, Request, _dlnaManager);
 
                 using var httpClient = _httpClientFactory.CreateClient();
-                return await FileStreamResponseHelpers.GetStaticRemoteStreamResult(state, isHeadRequest, this, httpClient).ConfigureAwait(false);
+                return await FileStreamResponseHelpers.GetStaticRemoteStreamResult(state, isHeadRequest, httpClient, HttpContext).ConfigureAwait(false);
             }
 
             if (@static.HasValue && @static.Value && state.InputProtocol != MediaProtocol.File)
@@ -507,7 +507,7 @@ namespace Jellyfin.Api.Controllers
                     state.MediaPath,
                     contentType,
                     isHeadRequest,
-                    this);
+                    HttpContext);
             }
 
             // Need to start ffmpeg (because media can't be returned directly)
@@ -517,10 +517,9 @@ namespace Jellyfin.Api.Controllers
             return await FileStreamResponseHelpers.GetTranscodedFile(
                 state,
                 isHeadRequest,
-                this,
+                HttpContext,
                 _transcodingJobHelper,
                 ffmpegCommandLineArguments,
-                Request,
                 _transcodingJobType,
                 cancellationTokenSource).ConfigureAwait(false);
         }

+ 19 - 17
Jellyfin.Api/Helpers/AudioHelper.cs

@@ -12,6 +12,7 @@ using MediaBrowser.Controller.Net;
 using MediaBrowser.Model.IO;
 using MediaBrowser.Model.MediaInfo;
 using MediaBrowser.Model.Net;
+using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.Extensions.Configuration;
 
@@ -35,6 +36,7 @@ namespace Jellyfin.Api.Helpers
         private readonly IDeviceManager _deviceManager;
         private readonly TranscodingJobHelper _transcodingJobHelper;
         private readonly IHttpClientFactory _httpClientFactory;
+        private readonly IHttpContextAccessor _httpContextAccessor;
 
         /// <summary>
         /// Initializes a new instance of the <see cref="AudioHelper"/> class.
@@ -52,6 +54,7 @@ namespace Jellyfin.Api.Helpers
         /// <param name="deviceManager">Instance of the <see cref="IDeviceManager"/> interface.</param>
         /// <param name="transcodingJobHelper">Instance of <see cref="TranscodingJobHelper"/>.</param>
         /// <param name="httpClientFactory">Instance of the <see cref="IHttpClientFactory"/> interface.</param>
+        /// <param name="httpContextAccessor">Instance of the <see cref="IHttpContextAccessor"/> interface.</param>
         public AudioHelper(
             IDlnaManager dlnaManager,
             IAuthorizationContext authContext,
@@ -65,7 +68,8 @@ namespace Jellyfin.Api.Helpers
             IConfiguration configuration,
             IDeviceManager deviceManager,
             TranscodingJobHelper transcodingJobHelper,
-            IHttpClientFactory httpClientFactory)
+            IHttpClientFactory httpClientFactory,
+            IHttpContextAccessor httpContextAccessor)
         {
             _dlnaManager = dlnaManager;
             _authContext = authContext;
@@ -80,26 +84,25 @@ namespace Jellyfin.Api.Helpers
             _deviceManager = deviceManager;
             _transcodingJobHelper = transcodingJobHelper;
             _httpClientFactory = httpClientFactory;
+            _httpContextAccessor = httpContextAccessor;
         }
 
         /// <summary>
         /// Get audio stream.
         /// </summary>
-        /// <param name="controller">Requesting controller.</param>
         /// <param name="transcodingJobType">Transcoding job type.</param>
         /// <param name="streamingRequest">Streaming controller.Request dto.</param>
         /// <returns>A <see cref="Task"/> containing the resulting <see cref="ActionResult"/>.</returns>
         public async Task<ActionResult> GetAudioStream(
-            BaseJellyfinApiController controller,
             TranscodingJobType transcodingJobType,
             StreamingRequestDto streamingRequest)
         {
-            bool isHeadRequest = controller.Request.Method == System.Net.WebRequestMethods.Http.Head;
+            bool isHeadRequest = _httpContextAccessor.HttpContext.Request.Method == System.Net.WebRequestMethods.Http.Head;
             var cancellationTokenSource = new CancellationTokenSource();
 
             using var state = await StreamingHelpers.GetStreamingState(
                     streamingRequest,
-                    controller.Request,
+                    _httpContextAccessor.HttpContext.Request,
                     _authContext,
                     _mediaSourceManager,
                     _userManager,
@@ -118,30 +121,30 @@ namespace Jellyfin.Api.Helpers
 
             if (streamingRequest.Static && state.DirectStreamProvider != null)
             {
-                StreamingHelpers.AddDlnaHeaders(state, controller.Response.Headers, true, streamingRequest.StartTimeTicks, controller.Request, _dlnaManager);
+                StreamingHelpers.AddDlnaHeaders(state, _httpContextAccessor.HttpContext.Response.Headers, true, streamingRequest.StartTimeTicks, _httpContextAccessor.HttpContext.Request, _dlnaManager);
 
                 await new ProgressiveFileCopier(state.DirectStreamProvider, null, _transcodingJobHelper, CancellationToken.None)
                     {
                         AllowEndOfFile = false
-                    }.WriteToAsync(controller.Response.Body, CancellationToken.None)
+                    }.WriteToAsync(_httpContextAccessor.HttpContext.Response.Body, CancellationToken.None)
                     .ConfigureAwait(false);
 
                 // TODO (moved from MediaBrowser.Api): Don't hardcode contentType
-                return controller.File(controller.Response.Body, MimeTypes.GetMimeType("file.ts")!);
+                return new FileStreamResult(_httpContextAccessor.HttpContext.Response.Body, MimeTypes.GetMimeType("file.ts")!);
             }
 
             // Static remote stream
             if (streamingRequest.Static && state.InputProtocol == MediaProtocol.Http)
             {
-                StreamingHelpers.AddDlnaHeaders(state, controller.Response.Headers, true, streamingRequest.StartTimeTicks, controller.Request, _dlnaManager);
+                StreamingHelpers.AddDlnaHeaders(state, _httpContextAccessor.HttpContext.Response.Headers, true, streamingRequest.StartTimeTicks, _httpContextAccessor.HttpContext.Request, _dlnaManager);
 
                 using var httpClient = _httpClientFactory.CreateClient();
-                return await FileStreamResponseHelpers.GetStaticRemoteStreamResult(state, isHeadRequest, controller, httpClient).ConfigureAwait(false);
+                return await FileStreamResponseHelpers.GetStaticRemoteStreamResult(state, isHeadRequest, httpClient, _httpContextAccessor.HttpContext).ConfigureAwait(false);
             }
 
             if (streamingRequest.Static && state.InputProtocol != MediaProtocol.File)
             {
-                return controller.BadRequest($"Input protocol {state.InputProtocol} cannot be streamed statically");
+                return new BadRequestObjectResult($"Input protocol {state.InputProtocol} cannot be streamed statically");
             }
 
             var outputPath = state.OutputFilePath;
@@ -150,7 +153,7 @@ namespace Jellyfin.Api.Helpers
             var transcodingJob = _transcodingJobHelper.GetTranscodingJob(outputPath, TranscodingJobType.Progressive);
             var isTranscodeCached = outputPathExists && transcodingJob != null;
 
-            StreamingHelpers.AddDlnaHeaders(state, controller.Response.Headers, streamingRequest.Static || isTranscodeCached, streamingRequest.StartTimeTicks, controller.Request, _dlnaManager);
+            StreamingHelpers.AddDlnaHeaders(state, _httpContextAccessor.HttpContext.Response.Headers, streamingRequest.Static || isTranscodeCached, streamingRequest.StartTimeTicks, _httpContextAccessor.HttpContext.Request, _dlnaManager);
 
             // Static stream
             if (streamingRequest.Static)
@@ -162,17 +165,17 @@ namespace Jellyfin.Api.Helpers
                     await new ProgressiveFileCopier(state.MediaPath, null, _transcodingJobHelper, CancellationToken.None)
                         {
                             AllowEndOfFile = false
-                        }.WriteToAsync(controller.Response.Body, CancellationToken.None)
+                        }.WriteToAsync(_httpContextAccessor.HttpContext.Response.Body, CancellationToken.None)
                         .ConfigureAwait(false);
 
-                    return controller.File(controller.Response.Body, contentType);
+                    return new FileStreamResult(_httpContextAccessor.HttpContext.Response.Body, contentType);
                 }
 
                 return FileStreamResponseHelpers.GetStaticFileResult(
                     state.MediaPath,
                     contentType,
                     isHeadRequest,
-                    controller);
+                    _httpContextAccessor.HttpContext);
             }
 
             // Need to start ffmpeg (because media can't be returned directly)
@@ -182,10 +185,9 @@ namespace Jellyfin.Api.Helpers
             return await FileStreamResponseHelpers.GetTranscodedFile(
                 state,
                 isHeadRequest,
-                controller,
+                _httpContextAccessor.HttpContext,
                 _transcodingJobHelper,
                 ffmpegCommandLineArguments,
-                controller.Request,
                 transcodingJobType,
                 cancellationTokenSource).ConfigureAwait(false);
         }

+ 12 - 11
Jellyfin.Api/Helpers/DynamicHlsHelper.cs

@@ -19,6 +19,7 @@ using MediaBrowser.Model.Dlna;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.IO;
 using MediaBrowser.Model.Net;
+using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.Logging;
@@ -45,6 +46,7 @@ namespace Jellyfin.Api.Helpers
         private readonly TranscodingJobHelper _transcodingJobHelper;
         private readonly INetworkManager _networkManager;
         private readonly ILogger<DynamicHlsHelper> _logger;
+        private readonly IHttpContextAccessor _httpContextAccessor;
 
         /// <summary>
         /// Initializes a new instance of the <see cref="DynamicHlsHelper"/> class.
@@ -63,6 +65,7 @@ namespace Jellyfin.Api.Helpers
         /// <param name="transcodingJobHelper">Instance of <see cref="TranscodingJobHelper"/>.</param>
         /// <param name="networkManager">Instance of the <see cref="INetworkManager"/> interface.</param>
         /// <param name="logger">Instance of the <see cref="ILogger{DynamicHlsHelper}"/> interface.</param>
+        /// <param name="httpContextAccessor">Instance of the <see cref="IHttpContextAccessor"/> interface.</param>
         public DynamicHlsHelper(
             ILibraryManager libraryManager,
             IUserManager userManager,
@@ -77,7 +80,8 @@ namespace Jellyfin.Api.Helpers
             IDeviceManager deviceManager,
             TranscodingJobHelper transcodingJobHelper,
             INetworkManager networkManager,
-            ILogger<DynamicHlsHelper> logger)
+            ILogger<DynamicHlsHelper> logger,
+            IHttpContextAccessor httpContextAccessor)
         {
             _libraryManager = libraryManager;
             _userManager = userManager;
@@ -93,26 +97,24 @@ namespace Jellyfin.Api.Helpers
             _transcodingJobHelper = transcodingJobHelper;
             _networkManager = networkManager;
             _logger = logger;
+            _httpContextAccessor = httpContextAccessor;
         }
 
         /// <summary>
         /// Get master hls playlist.
         /// </summary>
-        /// <param name="controller">Requesting controller.</param>
         /// <param name="transcodingJobType">Transcoding job type.</param>
         /// <param name="streamingRequest">Streaming request dto.</param>
         /// <param name="enableAdaptiveBitrateStreaming">Enable adaptive bitrate streaming.</param>
         /// <returns>A <see cref="Task"/> containing the resulting <see cref="ActionResult"/>.</returns>
         public async Task<ActionResult> GetMasterHlsPlaylist(
-            BaseJellyfinApiController controller,
             TranscodingJobType transcodingJobType,
             StreamingRequestDto streamingRequest,
             bool enableAdaptiveBitrateStreaming)
         {
-            var isHeadRequest = controller.Request.Method == WebRequestMethods.Http.Head;
+            var isHeadRequest = _httpContextAccessor.HttpContext.Request.Method == WebRequestMethods.Http.Head;
             var cancellationTokenSource = new CancellationTokenSource();
             return await GetMasterPlaylistInternal(
-                controller,
                 streamingRequest,
                 isHeadRequest,
                 enableAdaptiveBitrateStreaming,
@@ -121,7 +123,6 @@ namespace Jellyfin.Api.Helpers
         }
 
         private async Task<ActionResult> GetMasterPlaylistInternal(
-            BaseJellyfinApiController controller,
             StreamingRequestDto streamingRequest,
             bool isHeadRequest,
             bool enableAdaptiveBitrateStreaming,
@@ -130,7 +131,7 @@ namespace Jellyfin.Api.Helpers
         {
             using var state = await StreamingHelpers.GetStreamingState(
                     streamingRequest,
-                    controller.Request,
+                    _httpContextAccessor.HttpContext.Request,
                     _authContext,
                     _mediaSourceManager,
                     _userManager,
@@ -147,7 +148,7 @@ namespace Jellyfin.Api.Helpers
                     cancellationTokenSource.Token)
                 .ConfigureAwait(false);
 
-            controller.Response.Headers.Add(HeaderNames.Expires, "0");
+            _httpContextAccessor.HttpContext.Response.Headers.Add(HeaderNames.Expires, "0");
             if (isHeadRequest)
             {
                 return new FileContentResult(Array.Empty<byte>(), MimeTypes.GetMimeType("playlist.m3u8"));
@@ -161,7 +162,7 @@ namespace Jellyfin.Api.Helpers
 
             var isLiveStream = state.IsSegmentedLiveStream;
 
-            var queryString = controller.Request.QueryString.ToString();
+            var queryString = _httpContextAccessor.HttpContext.Request.QueryString.ToString();
 
             // from universal audio service
             if (queryString.IndexOf("SegmentContainer", StringComparison.OrdinalIgnoreCase) == -1 && !string.IsNullOrWhiteSpace(state.Request.SegmentContainer))
@@ -197,12 +198,12 @@ namespace Jellyfin.Api.Helpers
 
             if (!string.IsNullOrWhiteSpace(subtitleGroup))
             {
-                AddSubtitles(state, subtitleStreams, builder, controller.Request.HttpContext.User);
+                AddSubtitles(state, subtitleStreams, builder, _httpContextAccessor.HttpContext.Request.HttpContext.User);
             }
 
             AppendPlaylist(builder, state, playlistUrl, totalBitrate, subtitleGroup);
 
-            if (EnableAdaptiveBitrateStreaming(state, isLiveStream, enableAdaptiveBitrateStreaming, controller.Request.HttpContext.Connection.RemoteIpAddress))
+            if (EnableAdaptiveBitrateStreaming(state, isLiveStream, enableAdaptiveBitrateStreaming, _httpContextAccessor.HttpContext.Request.HttpContext.Connection.RemoteIpAddress))
             {
                 var requestedVideoBitrate = state.VideoRequest == null ? 0 : state.VideoRequest.VideoBitRate ?? 0;
 

+ 17 - 19
Jellyfin.Api/Helpers/FileStreamResponseHelpers.cs

@@ -22,14 +22,14 @@ namespace Jellyfin.Api.Helpers
         /// </summary>
         /// <param name="state">The current <see cref="StreamState"/>.</param>
         /// <param name="isHeadRequest">Whether the current request is a HTTP HEAD request so only the headers get returned.</param>
-        /// <param name="controller">The <see cref="ControllerBase"/> managing the response.</param>
         /// <param name="httpClient">The <see cref="HttpClient"/> making the remote request.</param>
+        /// <param name="httpContext">The current http context.</param>
         /// <returns>A <see cref="Task{ActionResult}"/> containing the API response.</returns>
         public static async Task<ActionResult> GetStaticRemoteStreamResult(
             StreamState state,
             bool isHeadRequest,
-            ControllerBase controller,
-            HttpClient httpClient)
+            HttpClient httpClient,
+            HttpContext httpContext)
         {
             if (state.RemoteHttpHeaders.TryGetValue(HeaderNames.UserAgent, out var useragent))
             {
@@ -39,14 +39,14 @@ namespace Jellyfin.Api.Helpers
             using var response = await httpClient.GetAsync(state.MediaPath).ConfigureAwait(false);
             var contentType = response.Content.Headers.ContentType.ToString();
 
-            controller.Response.Headers[HeaderNames.AcceptRanges] = "none";
+            httpContext.Response.Headers[HeaderNames.AcceptRanges] = "none";
 
             if (isHeadRequest)
             {
-                return controller.File(Array.Empty<byte>(), contentType);
+                return new FileContentResult(Array.Empty<byte>(), contentType);
             }
 
-            return controller.File(await response.Content.ReadAsStreamAsync().ConfigureAwait(false), contentType);
+            return new FileStreamResult(await response.Content.ReadAsStreamAsync().ConfigureAwait(false), contentType);
         }
 
         /// <summary>
@@ -55,23 +55,23 @@ namespace Jellyfin.Api.Helpers
         /// <param name="path">The path to the file.</param>
         /// <param name="contentType">The content type of the file.</param>
         /// <param name="isHeadRequest">Whether the current request is a HTTP HEAD request so only the headers get returned.</param>
-        /// <param name="controller">The <see cref="ControllerBase"/> managing the response.</param>
+        /// <param name="httpContext">The current http context.</param>
         /// <returns>An <see cref="ActionResult"/> the file.</returns>
         public static ActionResult GetStaticFileResult(
             string path,
             string contentType,
             bool isHeadRequest,
-            ControllerBase controller)
+            HttpContext httpContext)
         {
-            controller.Response.ContentType = contentType;
+            httpContext.Response.ContentType = contentType;
 
             // if the request is a head request, return a NoContent result with the same headers as it would with a GET request
             if (isHeadRequest)
             {
-                return controller.NoContent();
+                return new NoContentResult();
             }
 
-            return controller.PhysicalFile(path, contentType);
+            return new PhysicalFileResult(path, contentType);
         }
 
         /// <summary>
@@ -79,34 +79,32 @@ namespace Jellyfin.Api.Helpers
         /// </summary>
         /// <param name="state">The current <see cref="StreamState"/>.</param>
         /// <param name="isHeadRequest">Whether the current request is a HTTP HEAD request so only the headers get returned.</param>
-        /// <param name="controller">The <see cref="ControllerBase"/> managing the response.</param>
+        /// <param name="httpContext">The current http context.</param>
         /// <param name="transcodingJobHelper">The <see cref="TranscodingJobHelper"/> singleton.</param>
         /// <param name="ffmpegCommandLineArguments">The command line arguments to start ffmpeg.</param>
-        /// <param name="request">The <see cref="HttpRequest"/> starting the transcoding.</param>
         /// <param name="transcodingJobType">The <see cref="TranscodingJobType"/>.</param>
         /// <param name="cancellationTokenSource">The <see cref="CancellationTokenSource"/>.</param>
         /// <returns>A <see cref="Task{ActionResult}"/> containing the transcoded file.</returns>
         public static async Task<ActionResult> GetTranscodedFile(
             StreamState state,
             bool isHeadRequest,
-            ControllerBase controller,
+            HttpContext httpContext,
             TranscodingJobHelper transcodingJobHelper,
             string ffmpegCommandLineArguments,
-            HttpRequest request,
             TranscodingJobType transcodingJobType,
             CancellationTokenSource cancellationTokenSource)
         {
             // Use the command line args with a dummy playlist path
             var outputPath = state.OutputFilePath;
 
-            controller.Response.Headers[HeaderNames.AcceptRanges] = "none";
+            httpContext.Response.Headers[HeaderNames.AcceptRanges] = "none";
 
             var contentType = state.GetMimeType(outputPath);
 
             // Headers only
             if (isHeadRequest)
             {
-                return controller.File(Array.Empty<byte>(), contentType);
+                return new FileContentResult(Array.Empty<byte>(), contentType);
             }
 
             var transcodingLock = transcodingJobHelper.GetTranscodingLock(outputPath);
@@ -116,7 +114,7 @@ namespace Jellyfin.Api.Helpers
                 TranscodingJobDto? job;
                 if (!File.Exists(outputPath))
                 {
-                    job = await transcodingJobHelper.StartFfMpeg(state, outputPath, ffmpegCommandLineArguments, request, transcodingJobType, cancellationTokenSource).ConfigureAwait(false);
+                    job = await transcodingJobHelper.StartFfMpeg(state, outputPath, ffmpegCommandLineArguments, httpContext.Request, transcodingJobType, cancellationTokenSource).ConfigureAwait(false);
                 }
                 else
                 {
@@ -127,7 +125,7 @@ namespace Jellyfin.Api.Helpers
                 var memoryStream = new MemoryStream();
                 await new ProgressiveFileCopier(outputPath, job, transcodingJobHelper, CancellationToken.None).WriteToAsync(memoryStream, CancellationToken.None).ConfigureAwait(false);
                 memoryStream.Position = 0;
-                return controller.File(memoryStream, contentType);
+                return new FileStreamResult(memoryStream, contentType);
             }
             finally
             {