diff options
| author | gnattu <gnattu@users.noreply.github.com> | 2024-09-12 23:53:21 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-09-12 09:53:21 -0600 |
| commit | 62712aa12cdc88c524923cb318783b23a8a7a2c5 (patch) | |
| tree | 9c748127903fb0978f16ac234334305facba2160 | |
| parent | 0ff7f28753ed4848b0d5cdbe615787bcf7f3426b (diff) | |
Add option to always burn in subtitles if transcoding is triggered (#12430)
| -rw-r--r-- | Jellyfin.Api/Controllers/MediaInfoController.cs | 11 | ||||
| -rw-r--r-- | Jellyfin.Api/Controllers/UniversalAudioController.cs | 1 | ||||
| -rw-r--r-- | Jellyfin.Api/Helpers/MediaInfoHelper.cs | 6 | ||||
| -rw-r--r-- | Jellyfin.Api/Models/MediaInfoDtos/OpenLiveStreamDto.cs | 5 | ||||
| -rw-r--r-- | Jellyfin.Api/Models/MediaInfoDtos/PlaybackInfoDto.cs | 5 | ||||
| -rw-r--r-- | MediaBrowser.Model/Dlna/MediaOptions.cs | 5 | ||||
| -rw-r--r-- | MediaBrowser.Model/Dlna/StreamBuilder.cs | 20 | ||||
| -rw-r--r-- | MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs | 3 | ||||
| -rw-r--r-- | MediaBrowser.Model/Session/TranscodeReason.cs | 1 |
9 files changed, 49 insertions, 8 deletions
diff --git a/Jellyfin.Api/Controllers/MediaInfoController.cs b/Jellyfin.Api/Controllers/MediaInfoController.cs index bc52be184..f22ac0b73 100644 --- a/Jellyfin.Api/Controllers/MediaInfoController.cs +++ b/Jellyfin.Api/Controllers/MediaInfoController.cs @@ -209,6 +209,7 @@ public class MediaInfoController : BaseJellyfinApiController enableTranscoding.Value, allowVideoStreamCopy.Value, allowAudioStreamCopy.Value, + playbackInfoDto?.AlwaysBurnInSubtitleWhenTranscoding ?? false, Request.HttpContext.GetNormalizedRemoteIP()); } @@ -236,7 +237,8 @@ public class MediaInfoController : BaseJellyfinApiController StartTimeTicks = startTimeTicks, SubtitleStreamIndex = subtitleStreamIndex, UserId = userId ?? Guid.Empty, - OpenToken = mediaSource.OpenToken + OpenToken = mediaSource.OpenToken, + AlwaysBurnInSubtitleWhenTranscoding = playbackInfoDto?.AlwaysBurnInSubtitleWhenTranscoding ?? false }).ConfigureAwait(false); info.MediaSources = new[] { openStreamResult.MediaSource }; @@ -261,6 +263,7 @@ public class MediaInfoController : BaseJellyfinApiController /// <param name="openLiveStreamDto">The open live stream dto.</param> /// <param name="enableDirectPlay">Whether to enable direct play. Default: true.</param> /// <param name="enableDirectStream">Whether to enable direct stream. Default: true.</param> + /// <param name="alwaysBurnInSubtitleWhenTranscoding">Always burn-in subtitle when transcoding.</param> /// <response code="200">Media source opened.</response> /// <returns>A <see cref="Task"/> containing a <see cref="LiveStreamResponse"/>.</returns> [HttpPost("LiveStreams/Open")] @@ -277,7 +280,8 @@ public class MediaInfoController : BaseJellyfinApiController [FromQuery] Guid? itemId, [FromBody] OpenLiveStreamDto? openLiveStreamDto, [FromQuery] bool? enableDirectPlay, - [FromQuery] bool? enableDirectStream) + [FromQuery] bool? enableDirectStream, + [FromQuery] bool? alwaysBurnInSubtitleWhenTranscoding) { userId ??= openLiveStreamDto?.UserId; userId = RequestHelpers.GetUserId(User, userId); @@ -295,7 +299,8 @@ public class MediaInfoController : BaseJellyfinApiController DeviceProfile = openLiveStreamDto?.DeviceProfile, EnableDirectPlay = enableDirectPlay ?? openLiveStreamDto?.EnableDirectPlay ?? true, EnableDirectStream = enableDirectStream ?? openLiveStreamDto?.EnableDirectStream ?? true, - DirectPlayProtocols = openLiveStreamDto?.DirectPlayProtocols ?? new[] { MediaProtocol.Http } + DirectPlayProtocols = openLiveStreamDto?.DirectPlayProtocols ?? new[] { MediaProtocol.Http }, + AlwaysBurnInSubtitleWhenTranscoding = alwaysBurnInSubtitleWhenTranscoding ?? openLiveStreamDto?.AlwaysBurnInSubtitleWhenTranscoding ?? false }; return await _mediaInfoHelper.OpenMediaSource(HttpContext, request).ConfigureAwait(false); } diff --git a/Jellyfin.Api/Controllers/UniversalAudioController.cs b/Jellyfin.Api/Controllers/UniversalAudioController.cs index fe7353496..41c4886d4 100644 --- a/Jellyfin.Api/Controllers/UniversalAudioController.cs +++ b/Jellyfin.Api/Controllers/UniversalAudioController.cs @@ -160,6 +160,7 @@ public class UniversalAudioController : BaseJellyfinApiController true, true, true, + false, Request.HttpContext.GetNormalizedRemoteIP()); } diff --git a/Jellyfin.Api/Helpers/MediaInfoHelper.cs b/Jellyfin.Api/Helpers/MediaInfoHelper.cs index 9bda27031..5050cab41 100644 --- a/Jellyfin.Api/Helpers/MediaInfoHelper.cs +++ b/Jellyfin.Api/Helpers/MediaInfoHelper.cs @@ -156,6 +156,7 @@ public class MediaInfoHelper /// <param name="enableTranscoding">Enable transcoding.</param> /// <param name="allowVideoStreamCopy">Allow video stream copy.</param> /// <param name="allowAudioStreamCopy">Allow audio stream copy.</param> + /// <param name="alwaysBurnInSubtitleWhenTranscoding">Always burn-in subtitle when transcoding.</param> /// <param name="ipAddress">Requesting IP address.</param> public void SetDeviceSpecificData( BaseItem item, @@ -175,6 +176,7 @@ public class MediaInfoHelper bool enableTranscoding, bool allowVideoStreamCopy, bool allowAudioStreamCopy, + bool alwaysBurnInSubtitleWhenTranscoding, IPAddress ipAddress) { var streamBuilder = new StreamBuilder(_mediaEncoder, _logger); @@ -188,7 +190,8 @@ public class MediaInfoHelper Profile = profile, MaxAudioChannels = maxAudioChannels, AllowAudioStreamCopy = allowAudioStreamCopy, - AllowVideoStreamCopy = allowVideoStreamCopy + AllowVideoStreamCopy = allowVideoStreamCopy, + AlwaysBurnInSubtitleWhenTranscoding = alwaysBurnInSubtitleWhenTranscoding, }; if (string.Equals(mediaSourceId, mediaSource.Id, StringComparison.OrdinalIgnoreCase)) @@ -420,6 +423,7 @@ public class MediaInfoHelper true, true, true, + request.AlwaysBurnInSubtitleWhenTranscoding, httpContext.GetNormalizedRemoteIP()); } else diff --git a/Jellyfin.Api/Models/MediaInfoDtos/OpenLiveStreamDto.cs b/Jellyfin.Api/Models/MediaInfoDtos/OpenLiveStreamDto.cs index 53104988f..978e99b35 100644 --- a/Jellyfin.Api/Models/MediaInfoDtos/OpenLiveStreamDto.cs +++ b/Jellyfin.Api/Models/MediaInfoDtos/OpenLiveStreamDto.cs @@ -66,6 +66,11 @@ public class OpenLiveStreamDto public bool? EnableDirectStream { get; set; } /// <summary> + /// Gets or sets a value indicating whether always burn in subtitles when transcoding. + /// </summary> + public bool? AlwaysBurnInSubtitleWhenTranscoding { get; set; } + + /// <summary> /// Gets or sets the device profile. /// </summary> public DeviceProfile? DeviceProfile { get; set; } diff --git a/Jellyfin.Api/Models/MediaInfoDtos/PlaybackInfoDto.cs b/Jellyfin.Api/Models/MediaInfoDtos/PlaybackInfoDto.cs index 9e12ddde6..82f603ca1 100644 --- a/Jellyfin.Api/Models/MediaInfoDtos/PlaybackInfoDto.cs +++ b/Jellyfin.Api/Models/MediaInfoDtos/PlaybackInfoDto.cs @@ -82,4 +82,9 @@ public class PlaybackInfoDto /// Gets or sets a value indicating whether to auto open the live stream. /// </summary> public bool? AutoOpenLiveStream { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether always burn in subtitles when transcoding. + /// </summary> + public bool? AlwaysBurnInSubtitleWhenTranscoding { get; set; } } diff --git a/MediaBrowser.Model/Dlna/MediaOptions.cs b/MediaBrowser.Model/Dlna/MediaOptions.cs index eca971e95..6b26ca94b 100644 --- a/MediaBrowser.Model/Dlna/MediaOptions.cs +++ b/MediaBrowser.Model/Dlna/MediaOptions.cs @@ -50,6 +50,11 @@ namespace MediaBrowser.Model.Dlna public bool AllowVideoStreamCopy { get; set; } /// <summary> + /// Gets or sets a value indicating whether always burn in subtitles when transcoding. + /// </summary> + public bool AlwaysBurnInSubtitleWhenTranscoding { get; set; } + + /// <summary> /// Gets or sets the item id. /// </summary> public Guid ItemId { get; set; } diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index f68a8bca3..e4492ac79 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -20,8 +20,8 @@ namespace MediaBrowser.Model.Dlna // Aliases internal const TranscodeReason ContainerReasons = TranscodeReason.ContainerNotSupported | TranscodeReason.ContainerBitrateExceedsLimit; internal const TranscodeReason AudioReasons = TranscodeReason.AudioCodecNotSupported | TranscodeReason.AudioBitrateNotSupported | TranscodeReason.AudioChannelsNotSupported | TranscodeReason.AudioProfileNotSupported | TranscodeReason.AudioSampleRateNotSupported | TranscodeReason.SecondaryAudioNotSupported | TranscodeReason.AudioBitDepthNotSupported | TranscodeReason.AudioIsExternal; - internal const TranscodeReason VideoReasons = TranscodeReason.VideoCodecNotSupported | TranscodeReason.VideoResolutionNotSupported | TranscodeReason.AnamorphicVideoNotSupported | TranscodeReason.InterlacedVideoNotSupported | TranscodeReason.VideoBitDepthNotSupported | TranscodeReason.VideoBitrateNotSupported | TranscodeReason.VideoFramerateNotSupported | TranscodeReason.VideoLevelNotSupported | TranscodeReason.RefFramesNotSupported; - internal const TranscodeReason DirectStreamReasons = AudioReasons | TranscodeReason.ContainerNotSupported; + internal const TranscodeReason VideoReasons = TranscodeReason.VideoCodecNotSupported | TranscodeReason.VideoResolutionNotSupported | TranscodeReason.AnamorphicVideoNotSupported | TranscodeReason.InterlacedVideoNotSupported | TranscodeReason.VideoBitDepthNotSupported | TranscodeReason.VideoBitrateNotSupported | TranscodeReason.VideoFramerateNotSupported | TranscodeReason.VideoLevelNotSupported | TranscodeReason.RefFramesNotSupported | TranscodeReason.VideoRangeTypeNotSupported | TranscodeReason.VideoProfileNotSupported; + internal const TranscodeReason DirectStreamReasons = AudioReasons | TranscodeReason.ContainerNotSupported | TranscodeReason.VideoCodecTagNotSupported; private readonly ILogger _logger; private readonly ITranscoderSupport _transcoderSupport; @@ -352,7 +352,7 @@ namespace MediaBrowser.Model.Dlna return TranscodeReason.VideoBitrateNotSupported; case ProfileConditionValue.VideoCodecTag: - return TranscodeReason.VideoCodecNotSupported; + return TranscodeReason.VideoCodecTagNotSupported; case ProfileConditionValue.VideoFramerate: return TranscodeReason.VideoFramerateNotSupported; @@ -765,7 +765,19 @@ namespace MediaBrowser.Model.Dlna { var subtitleProfile = GetSubtitleProfile(item, subtitleStream, options.Profile.SubtitleProfiles, PlayMethod.Transcode, _transcoderSupport, transcodingProfile.Container, transcodingProfile.Protocol); - playlistItem.SubtitleDeliveryMethod = subtitleProfile.Method; + if (options.AlwaysBurnInSubtitleWhenTranscoding && (playlistItem.TranscodeReasons & (VideoReasons | TranscodeReason.ContainerBitrateExceedsLimit)) != 0) + { + playlistItem.SubtitleDeliveryMethod = SubtitleDeliveryMethod.Encode; + foreach (SubtitleProfile profile in options.Profile.SubtitleProfiles) + { + profile.Method = SubtitleDeliveryMethod.Encode; + } + } + else + { + playlistItem.SubtitleDeliveryMethod = subtitleProfile.Method; + } + playlistItem.SubtitleFormat = subtitleProfile.Format; playlistItem.SubtitleCodecs = new[] { subtitleProfile.Format }; } diff --git a/MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs b/MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs index 24eab1a74..92f467eb0 100644 --- a/MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs +++ b/MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs @@ -13,6 +13,7 @@ namespace MediaBrowser.Model.MediaInfo { EnableDirectPlay = true; EnableDirectStream = true; + AlwaysBurnInSubtitleWhenTranscoding = false; DirectPlayProtocols = new MediaProtocol[] { MediaProtocol.Http }; } @@ -40,6 +41,8 @@ namespace MediaBrowser.Model.MediaInfo public bool EnableDirectStream { get; set; } + public bool AlwaysBurnInSubtitleWhenTranscoding { get; set; } + public IReadOnlyList<MediaProtocol> DirectPlayProtocols { get; set; } } } diff --git a/MediaBrowser.Model/Session/TranscodeReason.cs b/MediaBrowser.Model/Session/TranscodeReason.cs index bbdf4536b..39c5ac8fa 100644 --- a/MediaBrowser.Model/Session/TranscodeReason.cs +++ b/MediaBrowser.Model/Session/TranscodeReason.cs @@ -18,6 +18,7 @@ namespace MediaBrowser.Model.Session // Video Constraints VideoProfileNotSupported = 1 << 6, VideoRangeTypeNotSupported = 1 << 24, + VideoCodecTagNotSupported = 1 << 25, VideoLevelNotSupported = 1 << 7, VideoResolutionNotSupported = 1 << 8, VideoBitDepthNotSupported = 1 << 9, |
