diff --git a/Jellyfin.Api/Helpers/StreamingHelpers.cs b/Jellyfin.Api/Helpers/StreamingHelpers.cs index c88ec0b2f2..ee1f1efce2 100644 --- a/Jellyfin.Api/Helpers/StreamingHelpers.cs +++ b/Jellyfin.Api/Helpers/StreamingHelpers.cs @@ -92,7 +92,10 @@ namespace Jellyfin.Api.Helpers var state = new StreamState(mediaSourceManager, transcodingJobType, transcodingJobHelper) { // TODO request was the StreamingRequest living in MediaBrowser.Api.Playback.Progressive - Request = request, + // Request = request, + DeviceId = deviceId, + PlaySessionId = playSessionId, + LiveStreamId = liveStreamId, RequestedUrl = url, UserAgent = request.Headers[HeaderNames.UserAgent], EnableDlnaHeaders = enableDlnaHeaders @@ -113,23 +116,23 @@ namespace Jellyfin.Api.Helpers } */ - if (state.VideoRequest != null && !string.IsNullOrWhiteSpace(state.VideoRequest.VideoCodec)) + if (state.IsVideoRequest && !string.IsNullOrWhiteSpace(state.VideoCodec)) { - state.SupportedVideoCodecs = state.VideoRequest.VideoCodec.Split(',').Where(i => !string.IsNullOrWhiteSpace(i)).ToArray(); - state.VideoRequest.VideoCodec = state.SupportedVideoCodecs.FirstOrDefault(); + state.SupportedVideoCodecs = state.VideoCodec.Split(',').Where(i => !string.IsNullOrWhiteSpace(i)).ToArray(); + state.VideoCodec = state.SupportedVideoCodecs.FirstOrDefault(); } if (!string.IsNullOrWhiteSpace(audioCodec)) { state.SupportedAudioCodecs = audioCodec.Split(',').Where(i => !string.IsNullOrWhiteSpace(i)).ToArray(); - state.Request.AudioCodec = state.SupportedAudioCodecs.FirstOrDefault(i => mediaEncoder.CanEncodeToAudioCodec(i)) + state.AudioCodec = state.SupportedAudioCodecs.FirstOrDefault(i => mediaEncoder.CanEncodeToAudioCodec(i)) ?? state.SupportedAudioCodecs.FirstOrDefault(); } if (!string.IsNullOrWhiteSpace(subtitleCodec)) { state.SupportedSubtitleCodecs = subtitleCodec.Split(',').Where(i => !string.IsNullOrWhiteSpace(i)).ToArray(); - state.Request.SubtitleCodec = state.SupportedSubtitleCodecs.FirstOrDefault(i => mediaEncoder.CanEncodeToSubtitleCodec(i)) + state.SubtitleCodec = state.SupportedSubtitleCodecs.FirstOrDefault(i => mediaEncoder.CanEncodeToSubtitleCodec(i)) ?? state.SupportedSubtitleCodecs.FirstOrDefault(); } @@ -203,7 +206,7 @@ namespace Jellyfin.Api.Helpers if (isVideoRequest) { - state.OutputVideoCodec = state.VideoRequest.VideoCodec; + state.OutputVideoCodec = state.VideoCodec; state.OutputVideoBitrate = EncodingHelper.GetVideoBitrateParamValue(state.VideoRequest, state.VideoStream, state.OutputVideoCodec); encodingHelper.TryStreamCopy(state); @@ -288,7 +291,7 @@ namespace Jellyfin.Api.Helpers var audioCodec = state.ActualOutputAudioCodec; - if (state.VideoRequest == null) + if (!state.IsVideoRequest) { responseHeaders.Add("contentFeatures.dlna.org", new ContentFeatureBuilder(profile).BuildAudioHeader( state.OutputContainer, @@ -426,12 +429,10 @@ namespace Jellyfin.Api.Helpers return ext; } - var isVideoRequest = state.VideoRequest != null; - // Try to infer based on the desired video codec - if (isVideoRequest) + if (state.IsVideoRequest) { - var videoCodec = state.VideoRequest.VideoCodec; + var videoCodec = state.VideoCodec; if (string.Equals(videoCodec, "h264", StringComparison.OrdinalIgnoreCase) || string.Equals(videoCodec, "h265", StringComparison.OrdinalIgnoreCase)) @@ -456,9 +457,9 @@ namespace Jellyfin.Api.Helpers } // Try to infer based on the desired audio codec - if (!isVideoRequest) + if (!state.IsVideoRequest) { - var audioCodec = state.Request.AudioCodec; + var audioCodec = state.AudioCodec; if (string.Equals("aac", audioCodec, StringComparison.OrdinalIgnoreCase)) { @@ -531,7 +532,7 @@ namespace Jellyfin.Api.Helpers var audioCodec = state.ActualOutputAudioCodec; var videoCodec = state.ActualOutputVideoCodec; - var mediaProfile = state.VideoRequest == null + var mediaProfile = !state.IsVideoRequest ? profile.GetAudioMediaProfile(state.OutputContainer, audioCodec, state.OutputAudioChannels, state.OutputAudioBitrate, state.OutputAudioSampleRate, state.OutputAudioBitDepth) : profile.GetVideoMediaProfile( state.OutputContainer, @@ -561,7 +562,7 @@ namespace Jellyfin.Api.Helpers if (!(@static.HasValue && @static.Value)) { - var transcodingProfile = state.VideoRequest == null ? profile.GetAudioTranscodingProfile(state.OutputContainer, audioCodec) : profile.GetVideoTranscodingProfile(state.OutputContainer, audioCodec, videoCodec); + var transcodingProfile = !state.IsVideoRequest ? profile.GetAudioTranscodingProfile(state.OutputContainer, audioCodec) : profile.GetVideoTranscodingProfile(state.OutputContainer, audioCodec, videoCodec); if (transcodingProfile != null) { @@ -569,7 +570,7 @@ namespace Jellyfin.Api.Helpers // state.EnableMpegtsM2TsMode = transcodingProfile.EnableMpegtsM2TsMode; state.TranscodeSeekInfo = transcodingProfile.TranscodeSeekInfo; - if (state.VideoRequest != null) + if (!state.IsVideoRequest) { state.VideoRequest.CopyTimestamps = transcodingProfile.CopyTimestamps; state.VideoRequest.EnableSubtitlesInManifest = transcodingProfile.EnableSubtitlesInManifest; diff --git a/Jellyfin.Api/Helpers/TranscodingJobHelper.cs b/Jellyfin.Api/Helpers/TranscodingJobHelper.cs index 9fbd5ec2db..4605c01831 100644 --- a/Jellyfin.Api/Helpers/TranscodingJobHelper.cs +++ b/Jellyfin.Api/Helpers/TranscodingJobHelper.cs @@ -443,7 +443,7 @@ namespace Jellyfin.Api.Helpers job.BitRate = bitRate; } - var deviceId = state.Request.DeviceId; + var deviceId = state.DeviceId; if (!string.IsNullOrWhiteSpace(deviceId)) { @@ -525,12 +525,12 @@ namespace Jellyfin.Api.Helpers var transcodingJob = this.OnTranscodeBeginning( outputPath, - state.Request.PlaySessionId, + state.PlaySessionId, state.MediaSource.LiveStreamId, Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture), transcodingJobType, process, - state.Request.DeviceId, + state.DeviceId, state, cancellationTokenSource); @@ -647,12 +647,12 @@ namespace Jellyfin.Api.Helpers /// TranscodingJob. public TranscodingJobDto OnTranscodeBeginning( string path, - string playSessionId, - string liveStreamId, + string? playSessionId, + string? liveStreamId, string transcodingJobId, TranscodingJobType type, Process process, - string deviceId, + string? deviceId, StreamState state, CancellationTokenSource cancellationTokenSource) { @@ -706,9 +706,9 @@ namespace Jellyfin.Api.Helpers _transcodingLocks.Remove(path); } - if (!string.IsNullOrWhiteSpace(state.Request.DeviceId)) + if (!string.IsNullOrWhiteSpace(state.DeviceId)) { - _sessionManager.ClearTranscodingInfo(state.Request.DeviceId); + _sessionManager.ClearTranscodingInfo(state.DeviceId); } } @@ -747,7 +747,7 @@ namespace Jellyfin.Api.Helpers state.IsoMount = await _isoManager.Mount(state.MediaPath, cancellationTokenSource.Token).ConfigureAwait(false); } - if (state.MediaSource.RequiresOpening && string.IsNullOrWhiteSpace(state.Request.LiveStreamId)) + if (state.MediaSource.RequiresOpening && string.IsNullOrWhiteSpace(state.LiveStreamId)) { var liveStreamResponse = await _mediaSourceManager.OpenLiveStream( new LiveStreamRequest { OpenToken = state.MediaSource.OpenToken }, diff --git a/Jellyfin.Api/Models/StreamingDtos/StreamState.cs b/Jellyfin.Api/Models/StreamingDtos/StreamState.cs index b962e0ac79..db7cc6a75c 100644 --- a/Jellyfin.Api/Models/StreamingDtos/StreamState.cs +++ b/Jellyfin.Api/Models/StreamingDtos/StreamState.cs @@ -53,10 +53,10 @@ namespace Jellyfin.Api.Models.StreamingDtos /// public TranscodingThrottler? TranscodingThrottler { get; set; } - /// + /*/// /// Gets the video request. /// - public VideoStreamRequest VideoRequest => Request as VideoStreamRequest; + public VideoStreamRequest VideoRequest => Request as VideoStreamRequest;*/ /// /// Gets or sets the direct stream provicer. @@ -68,10 +68,10 @@ namespace Jellyfin.Api.Models.StreamingDtos /// public string? WaitForPath { get; set; } - /// + /*/// /// Gets a value indicating whether the request outputs video. /// - public bool IsOutputVideo => Request is VideoStreamRequest; + public bool IsOutputVideo => Request is VideoStreamRequest;*/ /// /// Gets the segment length. @@ -161,6 +161,36 @@ namespace Jellyfin.Api.Models.StreamingDtos /// public TranscodingJobDto? TranscodingJob { get; set; } + /// + /// Gets or sets the device id. + /// + public string? DeviceId { get; set; } + + /// + /// Gets or sets the play session id. + /// + public string? PlaySessionId { get; set; } + + /// + /// Gets or sets the live stream id. + /// + public string? LiveStreamId { get; set; } + + /// + /// Gets or sets the video coded. + /// + public string? VideoCodec { get; set; } + + /// + /// Gets or sets the audio codec. + /// + public string? AudioCodec { get; set; } + + /// + /// Gets or sets the subtitle codec. + /// + public string? SubtitleCodec { get; set; } + /// public void Dispose() { @@ -189,7 +219,7 @@ namespace Jellyfin.Api.Models.StreamingDtos { // REVIEW: Is this the right place for this? if (MediaSource.RequiresClosing - && string.IsNullOrWhiteSpace(Request.LiveStreamId) + && string.IsNullOrWhiteSpace(LiveStreamId) && !string.IsNullOrWhiteSpace(MediaSource.LiveStreamId)) { _mediaSourceManager.CloseLiveStream(MediaSource.LiveStreamId).GetAwaiter().GetResult();