diff options
Diffstat (limited to 'Jellyfin.Api/Controllers/DynamicHlsController.cs')
| -rw-r--r-- | Jellyfin.Api/Controllers/DynamicHlsController.cs | 90 |
1 files changed, 46 insertions, 44 deletions
diff --git a/Jellyfin.Api/Controllers/DynamicHlsController.cs b/Jellyfin.Api/Controllers/DynamicHlsController.cs index ca8ab0ef7..4cac8ed67 100644 --- a/Jellyfin.Api/Controllers/DynamicHlsController.cs +++ b/Jellyfin.Api/Controllers/DynamicHlsController.cs @@ -166,18 +166,18 @@ public class DynamicHlsController : BaseJellyfinApiController [ProducesPlaylistFile] public async Task<ActionResult> GetLiveHlsStream( [FromRoute, Required] Guid itemId, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? container, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? container, [FromQuery] bool? @static, [FromQuery] string? @params, [FromQuery] string? tag, [FromQuery, ParameterObsolete] string? deviceProfileId, [FromQuery] string? playSessionId, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? segmentContainer, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? segmentContainer, [FromQuery] int? segmentLength, [FromQuery] int? minSegments, [FromQuery] string? mediaSourceId, [FromQuery] string? deviceId, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? audioCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? audioCodec, [FromQuery] bool? enableAutoStreamCopy, [FromQuery] bool? allowVideoStreamCopy, [FromQuery] bool? allowAudioStreamCopy, @@ -188,7 +188,7 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] int? audioChannels, [FromQuery] int? maxAudioChannels, [FromQuery] string? profile, - [FromQuery] string? level, + [FromQuery] [RegularExpression(EncodingHelper.LevelValidationRegex)] string? level, [FromQuery] float? framerate, [FromQuery] float? maxFramerate, [FromQuery] bool? copyTimestamps, @@ -207,8 +207,8 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] int? cpuCoreLimit, [FromQuery] string? liveStreamId, [FromQuery] bool? enableMpegtsM2TsMode, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? videoCodec, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? subtitleCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? videoCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? subtitleCodec, [FromQuery] string? transcodeReasons, [FromQuery] int? audioStreamIndex, [FromQuery] int? videoStreamIndex, @@ -415,12 +415,12 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] string? tag, [FromQuery, ParameterObsolete] string? deviceProfileId, [FromQuery] string? playSessionId, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? segmentContainer, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? segmentContainer, [FromQuery] int? segmentLength, [FromQuery] int? minSegments, [FromQuery, Required] string mediaSourceId, [FromQuery] string? deviceId, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? audioCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? audioCodec, [FromQuery] bool? enableAutoStreamCopy, [FromQuery] bool? allowVideoStreamCopy, [FromQuery] bool? allowAudioStreamCopy, @@ -431,7 +431,7 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] int? audioChannels, [FromQuery] int? maxAudioChannels, [FromQuery] string? profile, - [FromQuery] string? level, + [FromQuery] [RegularExpression(EncodingHelper.LevelValidationRegex)] string? level, [FromQuery] float? framerate, [FromQuery] float? maxFramerate, [FromQuery] bool? copyTimestamps, @@ -452,8 +452,8 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] int? cpuCoreLimit, [FromQuery] string? liveStreamId, [FromQuery] bool? enableMpegtsM2TsMode, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? videoCodec, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? subtitleCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? videoCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? subtitleCodec, [FromQuery] string? transcodeReasons, [FromQuery] int? audioStreamIndex, [FromQuery] int? videoStreamIndex, @@ -591,12 +591,12 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] string? tag, [FromQuery, ParameterObsolete] string? deviceProfileId, [FromQuery] string? playSessionId, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? segmentContainer, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? segmentContainer, [FromQuery] int? segmentLength, [FromQuery] int? minSegments, [FromQuery, Required] string mediaSourceId, [FromQuery] string? deviceId, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? audioCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? audioCodec, [FromQuery] bool? enableAutoStreamCopy, [FromQuery] bool? allowVideoStreamCopy, [FromQuery] bool? allowAudioStreamCopy, @@ -608,7 +608,7 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] int? audioChannels, [FromQuery] int? maxAudioChannels, [FromQuery] string? profile, - [FromQuery] string? level, + [FromQuery] [RegularExpression(EncodingHelper.LevelValidationRegex)] string? level, [FromQuery] float? framerate, [FromQuery] float? maxFramerate, [FromQuery] bool? copyTimestamps, @@ -627,8 +627,8 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] int? cpuCoreLimit, [FromQuery] string? liveStreamId, [FromQuery] bool? enableMpegtsM2TsMode, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? videoCodec, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? subtitleCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? videoCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? subtitleCodec, [FromQuery] string? transcodeReasons, [FromQuery] int? audioStreamIndex, [FromQuery] int? videoStreamIndex, @@ -761,12 +761,12 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] string? tag, [FromQuery, ParameterObsolete] string? deviceProfileId, [FromQuery] string? playSessionId, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? segmentContainer, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? segmentContainer, [FromQuery] int? segmentLength, [FromQuery] int? minSegments, [FromQuery] string? mediaSourceId, [FromQuery] string? deviceId, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? audioCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? audioCodec, [FromQuery] bool? enableAutoStreamCopy, [FromQuery] bool? allowVideoStreamCopy, [FromQuery] bool? allowAudioStreamCopy, @@ -777,7 +777,7 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] int? audioChannels, [FromQuery] int? maxAudioChannels, [FromQuery] string? profile, - [FromQuery] string? level, + [FromQuery] [RegularExpression(EncodingHelper.LevelValidationRegex)] string? level, [FromQuery] float? framerate, [FromQuery] float? maxFramerate, [FromQuery] bool? copyTimestamps, @@ -798,8 +798,8 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] int? cpuCoreLimit, [FromQuery] string? liveStreamId, [FromQuery] bool? enableMpegtsM2TsMode, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? videoCodec, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? subtitleCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? videoCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? subtitleCodec, [FromQuery] string? transcodeReasons, [FromQuery] int? audioStreamIndex, [FromQuery] int? videoStreamIndex, @@ -933,12 +933,12 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] string? tag, [FromQuery, ParameterObsolete] string? deviceProfileId, [FromQuery] string? playSessionId, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? segmentContainer, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? segmentContainer, [FromQuery] int? segmentLength, [FromQuery] int? minSegments, [FromQuery] string? mediaSourceId, [FromQuery] string? deviceId, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? audioCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? audioCodec, [FromQuery] bool? enableAutoStreamCopy, [FromQuery] bool? allowVideoStreamCopy, [FromQuery] bool? allowAudioStreamCopy, @@ -950,7 +950,7 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] int? audioChannels, [FromQuery] int? maxAudioChannels, [FromQuery] string? profile, - [FromQuery] string? level, + [FromQuery] [RegularExpression(EncodingHelper.LevelValidationRegex)] string? level, [FromQuery] float? framerate, [FromQuery] float? maxFramerate, [FromQuery] bool? copyTimestamps, @@ -969,8 +969,8 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] int? cpuCoreLimit, [FromQuery] string? liveStreamId, [FromQuery] bool? enableMpegtsM2TsMode, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? videoCodec, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? subtitleCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? videoCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? subtitleCodec, [FromQuery] string? transcodeReasons, [FromQuery] int? audioStreamIndex, [FromQuery] int? videoStreamIndex, @@ -1106,7 +1106,7 @@ public class DynamicHlsController : BaseJellyfinApiController [FromRoute, Required] Guid itemId, [FromRoute, Required] string playlistId, [FromRoute, Required] int segmentId, - [FromRoute, Required] string container, + [FromRoute, Required] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string container, [FromQuery, Required] long runtimeTicks, [FromQuery, Required] long actualSegmentLengthTicks, [FromQuery] bool? @static, @@ -1114,12 +1114,12 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] string? tag, [FromQuery, ParameterObsolete] string? deviceProfileId, [FromQuery] string? playSessionId, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? segmentContainer, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? segmentContainer, [FromQuery] int? segmentLength, [FromQuery] int? minSegments, [FromQuery] string? mediaSourceId, [FromQuery] string? deviceId, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? audioCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? audioCodec, [FromQuery] bool? enableAutoStreamCopy, [FromQuery] bool? allowVideoStreamCopy, [FromQuery] bool? allowAudioStreamCopy, @@ -1130,7 +1130,7 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] int? audioChannels, [FromQuery] int? maxAudioChannels, [FromQuery] string? profile, - [FromQuery] string? level, + [FromQuery] [RegularExpression(EncodingHelper.LevelValidationRegex)] string? level, [FromQuery] float? framerate, [FromQuery] float? maxFramerate, [FromQuery] bool? copyTimestamps, @@ -1151,8 +1151,8 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] int? cpuCoreLimit, [FromQuery] string? liveStreamId, [FromQuery] bool? enableMpegtsM2TsMode, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? videoCodec, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? subtitleCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? videoCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? subtitleCodec, [FromQuery] string? transcodeReasons, [FromQuery] int? audioStreamIndex, [FromQuery] int? videoStreamIndex, @@ -1291,7 +1291,7 @@ public class DynamicHlsController : BaseJellyfinApiController [FromRoute, Required] Guid itemId, [FromRoute, Required] string playlistId, [FromRoute, Required] int segmentId, - [FromRoute, Required] string container, + [FromRoute, Required] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string container, [FromQuery, Required] long runtimeTicks, [FromQuery, Required] long actualSegmentLengthTicks, [FromQuery] bool? @static, @@ -1299,12 +1299,12 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] string? tag, [FromQuery, ParameterObsolete] string? deviceProfileId, [FromQuery] string? playSessionId, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? segmentContainer, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? segmentContainer, [FromQuery] int? segmentLength, [FromQuery] int? minSegments, [FromQuery] string? mediaSourceId, [FromQuery] string? deviceId, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? audioCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? audioCodec, [FromQuery] bool? enableAutoStreamCopy, [FromQuery] bool? allowVideoStreamCopy, [FromQuery] bool? allowAudioStreamCopy, @@ -1316,7 +1316,7 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] int? audioChannels, [FromQuery] int? maxAudioChannels, [FromQuery] string? profile, - [FromQuery] string? level, + [FromQuery] [RegularExpression(EncodingHelper.LevelValidationRegex)] string? level, [FromQuery] float? framerate, [FromQuery] float? maxFramerate, [FromQuery] bool? copyTimestamps, @@ -1335,8 +1335,8 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] int? cpuCoreLimit, [FromQuery] string? liveStreamId, [FromQuery] bool? enableMpegtsM2TsMode, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? videoCodec, - [FromQuery] [RegularExpression(EncodingHelper.ValidationRegex)] string? subtitleCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? videoCodec, + [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? subtitleCodec, [FromQuery] string? transcodeReasons, [FromQuery] int? audioStreamIndex, [FromQuery] int? videoStreamIndex, @@ -1419,8 +1419,9 @@ public class DynamicHlsController : BaseJellyfinApiController TranscodingJobType, cancellationTokenSource.Token) .ConfigureAwait(false); - + var mediaSourceId = state.BaseRequest.MediaSourceId; var request = new CreateMainPlaylistRequest( + mediaSourceId is null ? null : Guid.Parse(mediaSourceId), state.MediaPath, state.SegmentLength * 1000, state.RunTimeTicks ?? 0, @@ -1675,7 +1676,7 @@ public class DynamicHlsController : BaseJellyfinApiController } var audioCodec = _encodingHelper.GetAudioEncoder(state); - var bitStreamArgs = EncodingHelper.GetAudioBitStreamArguments(state, state.Request.SegmentContainer, state.MediaSource.Container); + var bitStreamArgs = _encodingHelper.GetAudioBitStreamArguments(state, state.Request.SegmentContainer, state.MediaSource.Container); // opus, dts, truehd and flac (in FFmpeg 5 and older) are experimental in mp4 muxer var strictArgs = string.Empty; @@ -1753,7 +1754,7 @@ public class DynamicHlsController : BaseJellyfinApiController if (channels.HasValue && (channels.Value != 2 - || (state.AudioStream?.Channels != null && !useDownMixAlgorithm))) + || (state.AudioStream?.Channels is not null && !useDownMixAlgorithm))) { args += " -ac " + channels.Value; } @@ -1822,10 +1823,11 @@ public class DynamicHlsController : BaseJellyfinApiController // Clients reporting Dolby Vision capabilities with fallbacks may only support the fallback layer. // Only enable Dolby Vision remuxing if the client explicitly declares support for profiles without fallbacks. var clientSupportsDoVi = requestedRange.Contains(VideoRangeType.DOVI.ToString(), StringComparison.OrdinalIgnoreCase); - var videoIsDoVi = state.VideoStream.VideoRangeType is VideoRangeType.DOVI or VideoRangeType.DOVIWithHDR10 or VideoRangeType.DOVIWithHLG or VideoRangeType.DOVIWithSDR; + var videoIsDoVi = EncodingHelper.IsDovi(state.VideoStream); if (EncodingHelper.IsCopyCodec(codec) - && (videoIsDoVi && clientSupportsDoVi)) + && (videoIsDoVi && clientSupportsDoVi) + && !_encodingHelper.IsDoviRemoved(state)) { if (isActualOutputVideoCodecHevc) { @@ -1855,7 +1857,7 @@ public class DynamicHlsController : BaseJellyfinApiController // If h264_mp4toannexb is ever added, do not use it for live tv. if (state.VideoStream is not null && !string.Equals(state.VideoStream.NalLengthSize, "0", StringComparison.OrdinalIgnoreCase)) { - string bitStreamArgs = EncodingHelper.GetBitStreamArgs(state.VideoStream); + string bitStreamArgs = _encodingHelper.GetBitStreamArgs(state, MediaStreamType.Video); if (!string.IsNullOrEmpty(bitStreamArgs)) { args += " " + bitStreamArgs; |
