mirror of
https://github.com/jellyfin/jellyfin.git
synced 2025-04-23 21:47:14 -04:00
Fix suggestions from review
This commit is contained in:
parent
d39f481a5c
commit
ca3dcc3db0
4 changed files with 59 additions and 145 deletions
|
@ -260,7 +260,7 @@ namespace Jellyfin.Api.Controllers
|
|||
StreamOptions = streamOptions
|
||||
};
|
||||
|
||||
var state = await StreamingHelpers.GetStreamingState(
|
||||
using var state = await StreamingHelpers.GetStreamingState(
|
||||
streamingRequest,
|
||||
Request,
|
||||
_authContext,
|
||||
|
@ -283,14 +283,11 @@ namespace Jellyfin.Api.Controllers
|
|||
{
|
||||
StreamingHelpers.AddDlnaHeaders(state, Response.Headers, true, startTimeTicks, Request, _dlnaManager);
|
||||
|
||||
using (state)
|
||||
{
|
||||
// TODO AllowEndOfFile = false
|
||||
await new ProgressiveFileCopier(_streamHelper, state.DirectStreamProvider).WriteToAsync(Response.Body, CancellationToken.None).ConfigureAwait(false);
|
||||
// TODO AllowEndOfFile = false
|
||||
await new ProgressiveFileCopier(_streamHelper, state.DirectStreamProvider).WriteToAsync(Response.Body, CancellationToken.None).ConfigureAwait(false);
|
||||
|
||||
// TODO (moved from MediaBrowser.Api): Don't hardcode contentType
|
||||
return File(Response.Body, MimeTypes.GetMimeType("file.ts")!);
|
||||
}
|
||||
// TODO (moved from MediaBrowser.Api): Don't hardcode contentType
|
||||
return File(Response.Body, MimeTypes.GetMimeType("file.ts")!);
|
||||
}
|
||||
|
||||
// Static remote stream
|
||||
|
@ -298,10 +295,7 @@ namespace Jellyfin.Api.Controllers
|
|||
{
|
||||
StreamingHelpers.AddDlnaHeaders(state, Response.Headers, true, startTimeTicks, Request, _dlnaManager);
|
||||
|
||||
using (state)
|
||||
{
|
||||
return await FileStreamResponseHelpers.GetStaticRemoteStreamResult(state, isHeadRequest, this, _httpClient).ConfigureAwait(false);
|
||||
}
|
||||
return await FileStreamResponseHelpers.GetStaticRemoteStreamResult(state, isHeadRequest, this, _httpClient).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (@static.HasValue && @static.Value && state.InputProtocol != MediaProtocol.File)
|
||||
|
@ -322,80 +316,35 @@ namespace Jellyfin.Api.Controllers
|
|||
{
|
||||
var contentType = state.GetMimeType("." + state.OutputContainer, false) ?? state.GetMimeType(state.MediaPath);
|
||||
|
||||
using (state)
|
||||
if (state.MediaSource.IsInfiniteStream)
|
||||
{
|
||||
if (state.MediaSource.IsInfiniteStream)
|
||||
{
|
||||
// TODO AllowEndOfFile = false
|
||||
await new ProgressiveFileCopier(_streamHelper, state.MediaPath).WriteToAsync(Response.Body, CancellationToken.None).ConfigureAwait(false);
|
||||
// TODO AllowEndOfFile = false
|
||||
await new ProgressiveFileCopier(_streamHelper, state.MediaPath).WriteToAsync(Response.Body, CancellationToken.None).ConfigureAwait(false);
|
||||
|
||||
return File(Response.Body, contentType);
|
||||
}
|
||||
|
||||
return FileStreamResponseHelpers.GetStaticFileResult(
|
||||
state.MediaPath,
|
||||
contentType,
|
||||
isHeadRequest,
|
||||
this);
|
||||
return File(Response.Body, contentType);
|
||||
}
|
||||
|
||||
return FileStreamResponseHelpers.GetStaticFileResult(
|
||||
state.MediaPath,
|
||||
contentType,
|
||||
isHeadRequest,
|
||||
this);
|
||||
}
|
||||
|
||||
/*
|
||||
// Not static but transcode cache file exists
|
||||
if (isTranscodeCached && state.VideoRequest == null)
|
||||
{
|
||||
var contentType = state.GetMimeType(outputPath)
|
||||
try
|
||||
{
|
||||
if (transcodingJob != null)
|
||||
{
|
||||
ApiEntryPoint.Instance.OnTranscodeBeginRequest(transcodingJob);
|
||||
}
|
||||
return await ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions
|
||||
{
|
||||
ResponseHeaders = responseHeaders,
|
||||
ContentType = contentType,
|
||||
IsHeadRequest = isHeadRequest,
|
||||
Path = outputPath,
|
||||
FileShare = FileShare.ReadWrite,
|
||||
OnComplete = () =>
|
||||
{
|
||||
if (transcodingJob != null)
|
||||
{
|
||||
ApiEntryPoint.Instance.OnTranscodeEndRequest(transcodingJob);
|
||||
}
|
||||
}).ConfigureAwait(false);
|
||||
}
|
||||
finally
|
||||
{
|
||||
state.Dispose();
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// Need to start ffmpeg (because media can't be returned directly)
|
||||
try
|
||||
{
|
||||
var encodingOptions = _serverConfigurationManager.GetEncodingOptions();
|
||||
var encodingHelper = new EncodingHelper(_mediaEncoder, _fileSystem, _subtitleEncoder, _configuration);
|
||||
var ffmpegCommandLineArguments = encodingHelper.GetProgressiveAudioFullCommandLine(state, encodingOptions, outputPath);
|
||||
return await FileStreamResponseHelpers.GetTranscodedFile(
|
||||
state,
|
||||
isHeadRequest,
|
||||
_streamHelper,
|
||||
this,
|
||||
_transcodingJobHelper,
|
||||
ffmpegCommandLineArguments,
|
||||
Request,
|
||||
_transcodingJobType,
|
||||
cancellationTokenSource).ConfigureAwait(false);
|
||||
}
|
||||
catch
|
||||
{
|
||||
state.Dispose();
|
||||
|
||||
throw;
|
||||
}
|
||||
var encodingOptions = _serverConfigurationManager.GetEncodingOptions();
|
||||
var encodingHelper = new EncodingHelper(_mediaEncoder, _fileSystem, _subtitleEncoder, _configuration);
|
||||
var ffmpegCommandLineArguments = encodingHelper.GetProgressiveAudioFullCommandLine(state, encodingOptions, outputPath);
|
||||
return await FileStreamResponseHelpers.GetTranscodedFile(
|
||||
state,
|
||||
isHeadRequest,
|
||||
_streamHelper,
|
||||
this,
|
||||
_transcodingJobHelper,
|
||||
ffmpegCommandLineArguments,
|
||||
Request,
|
||||
_transcodingJobType,
|
||||
cancellationTokenSource).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,17 +36,14 @@ namespace Jellyfin.Api.Helpers
|
|||
httpClient.DefaultRequestHeaders.Add(HeaderNames.UserAgent, useragent);
|
||||
}
|
||||
|
||||
var response = await httpClient.GetAsync(state.MediaPath).ConfigureAwait(false);
|
||||
using var response = await httpClient.GetAsync(state.MediaPath).ConfigureAwait(false);
|
||||
var contentType = response.Content.Headers.ContentType.ToString();
|
||||
|
||||
controller.Response.Headers[HeaderNames.AcceptRanges] = "none";
|
||||
|
||||
if (isHeadRequest)
|
||||
{
|
||||
using (response)
|
||||
{
|
||||
return controller.File(Array.Empty<byte>(), contentType);
|
||||
}
|
||||
return controller.File(Array.Empty<byte>(), contentType);
|
||||
}
|
||||
|
||||
return controller.File(await response.Content.ReadAsStreamAsync().ConfigureAwait(false), contentType);
|
||||
|
@ -74,7 +71,7 @@ namespace Jellyfin.Api.Helpers
|
|||
return controller.NoContent();
|
||||
}
|
||||
|
||||
var stream = new FileStream(path, FileMode.Open, FileAccess.Read);
|
||||
using var stream = new FileStream(path, FileMode.Open, FileAccess.Read);
|
||||
return controller.File(stream, contentType);
|
||||
}
|
||||
|
||||
|
@ -129,11 +126,9 @@ namespace Jellyfin.Api.Helpers
|
|||
state.Dispose();
|
||||
}
|
||||
|
||||
using (var memoryStream = new MemoryStream())
|
||||
{
|
||||
await new ProgressiveFileCopier(streamHelper, outputPath).WriteToAsync(memoryStream, CancellationToken.None).ConfigureAwait(false);
|
||||
return controller.File(memoryStream, contentType);
|
||||
}
|
||||
await using var memoryStream = new MemoryStream();
|
||||
await new ProgressiveFileCopier(streamHelper, outputPath).WriteToAsync(memoryStream, CancellationToken.None).ConfigureAwait(false);
|
||||
return controller.File(memoryStream, contentType);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
|
|
@ -74,7 +74,7 @@ namespace Jellyfin.Api.Helpers
|
|||
{
|
||||
var timeSeek = httpRequest.Headers["TimeSeekRange.dlna.org"];
|
||||
|
||||
streamingRequest.StartTimeTicks = ParseTimeSeekHeader(timeSeek);
|
||||
streamingRequest.StartTimeTicks = ParseTimeSeekHeader(timeSeek.ToString());
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(streamingRequest.Params))
|
||||
|
@ -108,31 +108,22 @@ namespace Jellyfin.Api.Helpers
|
|||
state.User = userManager.GetUserById(auth.UserId);
|
||||
}
|
||||
|
||||
/*
|
||||
if ((Request.UserAgent ?? string.Empty).IndexOf("iphone", StringComparison.OrdinalIgnoreCase) != -1 ||
|
||||
(Request.UserAgent ?? string.Empty).IndexOf("ipad", StringComparison.OrdinalIgnoreCase) != -1 ||
|
||||
(Request.UserAgent ?? string.Empty).IndexOf("ipod", StringComparison.OrdinalIgnoreCase) != -1)
|
||||
{
|
||||
state.SegmentLength = 6;
|
||||
}
|
||||
*/
|
||||
|
||||
if (state.IsVideoRequest && !string.IsNullOrWhiteSpace(state.Request.VideoCodec))
|
||||
{
|
||||
state.SupportedVideoCodecs = state.Request.VideoCodec.Split(',').Where(i => !string.IsNullOrWhiteSpace(i)).ToArray();
|
||||
state.SupportedVideoCodecs = state.Request.VideoCodec.Split(',', StringSplitOptions.RemoveEmptyEntries);
|
||||
state.Request.VideoCodec = state.SupportedVideoCodecs.FirstOrDefault();
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(streamingRequest.AudioCodec))
|
||||
{
|
||||
state.SupportedAudioCodecs = streamingRequest.AudioCodec.Split(',').Where(i => !string.IsNullOrWhiteSpace(i)).ToArray();
|
||||
state.SupportedAudioCodecs = streamingRequest.AudioCodec.Split(',', StringSplitOptions.RemoveEmptyEntries);
|
||||
state.Request.AudioCodec = state.SupportedAudioCodecs.FirstOrDefault(i => mediaEncoder.CanEncodeToAudioCodec(i))
|
||||
?? state.SupportedAudioCodecs.FirstOrDefault();
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(streamingRequest.SubtitleCodec))
|
||||
{
|
||||
state.SupportedSubtitleCodecs = streamingRequest.SubtitleCodec.Split(',').Where(i => !string.IsNullOrWhiteSpace(i)).ToArray();
|
||||
state.SupportedSubtitleCodecs = streamingRequest.SubtitleCodec.Split(',', StringSplitOptions.RemoveEmptyEntries);
|
||||
state.Request.SubtitleCodec = state.SupportedSubtitleCodecs.FirstOrDefault(i => mediaEncoder.CanEncodeToSubtitleCodec(i))
|
||||
?? state.SupportedSubtitleCodecs.FirstOrDefault();
|
||||
}
|
||||
|
@ -141,15 +132,6 @@ namespace Jellyfin.Api.Helpers
|
|||
|
||||
state.IsInputVideo = string.Equals(item.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
/*
|
||||
var primaryImage = item.GetImageInfo(ImageType.Primary, 0) ??
|
||||
item.Parents.Select(i => i.GetImageInfo(ImageType.Primary, 0)).FirstOrDefault(i => i != null);
|
||||
if (primaryImage != null)
|
||||
{
|
||||
state.AlbumCoverPath = primaryImage.Path;
|
||||
}
|
||||
*/
|
||||
|
||||
MediaSourceInfo? mediaSource = null;
|
||||
if (string.IsNullOrWhiteSpace(streamingRequest.LiveStreamId))
|
||||
{
|
||||
|
@ -322,25 +304,24 @@ namespace Jellyfin.Api.Helpers
|
|||
/// </summary>
|
||||
/// <param name="value">The time seek header string.</param>
|
||||
/// <returns>A nullable <see cref="long"/> representing the seek time in ticks.</returns>
|
||||
private static long? ParseTimeSeekHeader(string value)
|
||||
private static long? ParseTimeSeekHeader(ReadOnlySpan<char> value)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
if (value.IsEmpty)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
const string Npt = "npt=";
|
||||
if (!value.StartsWith(Npt, StringComparison.OrdinalIgnoreCase))
|
||||
const string npt = "npt=";
|
||||
if (!value.StartsWith(npt, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
throw new ArgumentException("Invalid timeseek header");
|
||||
}
|
||||
|
||||
int index = value.IndexOf('-', StringComparison.InvariantCulture);
|
||||
var index = value.IndexOf('-');
|
||||
value = index == -1
|
||||
? value.Substring(Npt.Length)
|
||||
: value.Substring(Npt.Length, index - Npt.Length);
|
||||
|
||||
if (value.IndexOf(':', StringComparison.InvariantCulture) == -1)
|
||||
? value.Slice(npt.Length)
|
||||
: value.Slice(npt.Length, index - npt.Length);
|
||||
if (value.IndexOf(':') == -1)
|
||||
{
|
||||
// Parses npt times in the format of '417.33'
|
||||
if (double.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var seconds))
|
||||
|
@ -351,26 +332,15 @@ namespace Jellyfin.Api.Helpers
|
|||
throw new ArgumentException("Invalid timeseek header");
|
||||
}
|
||||
|
||||
// Parses npt times in the format of '10:19:25.7'
|
||||
var tokens = value.Split(new[] { ':' }, 3);
|
||||
double secondsSum = 0;
|
||||
var timeFactor = 3600;
|
||||
|
||||
foreach (var time in tokens)
|
||||
try
|
||||
{
|
||||
if (double.TryParse(time, NumberStyles.Any, CultureInfo.InvariantCulture, out var digit))
|
||||
{
|
||||
secondsSum += digit * timeFactor;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException("Invalid timeseek header");
|
||||
}
|
||||
|
||||
timeFactor /= 60;
|
||||
// Parses npt times in the format of '10:19:25.7'
|
||||
return TimeSpan.Parse(value).Ticks;
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw new ArgumentException("Invalid timeseek header");
|
||||
}
|
||||
|
||||
return TimeSpan.FromSeconds(secondsSum).Ticks;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -88,11 +88,11 @@ namespace Jellyfin.Api.Models.StreamingDtos
|
|||
{
|
||||
var userAgent = UserAgent ?? string.Empty;
|
||||
|
||||
if (userAgent.IndexOf("AppleTV", StringComparison.OrdinalIgnoreCase) != -1 ||
|
||||
userAgent.IndexOf("cfnetwork", StringComparison.OrdinalIgnoreCase) != -1 ||
|
||||
userAgent.IndexOf("ipad", StringComparison.OrdinalIgnoreCase) != -1 ||
|
||||
userAgent.IndexOf("iphone", StringComparison.OrdinalIgnoreCase) != -1 ||
|
||||
userAgent.IndexOf("ipod", StringComparison.OrdinalIgnoreCase) != -1)
|
||||
if (userAgent.IndexOf("AppleTV", StringComparison.OrdinalIgnoreCase) != -1
|
||||
|| userAgent.IndexOf("cfnetwork", StringComparison.OrdinalIgnoreCase) != -1
|
||||
|| userAgent.IndexOf("ipad", StringComparison.OrdinalIgnoreCase) != -1
|
||||
|| userAgent.IndexOf("iphone", StringComparison.OrdinalIgnoreCase) != -1
|
||||
|| userAgent.IndexOf("ipod", StringComparison.OrdinalIgnoreCase) != -1)
|
||||
{
|
||||
return 6;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue