Add option to always burn in subtitles if transcoding is triggered (#12430)

pull/10756/head
gnattu 6 months ago committed by GitHub
parent 0ff7f28753
commit 62712aa12c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -209,6 +209,7 @@ public class MediaInfoController : BaseJellyfinApiController
enableTranscoding.Value, enableTranscoding.Value,
allowVideoStreamCopy.Value, allowVideoStreamCopy.Value,
allowAudioStreamCopy.Value, allowAudioStreamCopy.Value,
playbackInfoDto?.AlwaysBurnInSubtitleWhenTranscoding ?? false,
Request.HttpContext.GetNormalizedRemoteIP()); Request.HttpContext.GetNormalizedRemoteIP());
} }
@ -236,7 +237,8 @@ public class MediaInfoController : BaseJellyfinApiController
StartTimeTicks = startTimeTicks, StartTimeTicks = startTimeTicks,
SubtitleStreamIndex = subtitleStreamIndex, SubtitleStreamIndex = subtitleStreamIndex,
UserId = userId ?? Guid.Empty, UserId = userId ?? Guid.Empty,
OpenToken = mediaSource.OpenToken OpenToken = mediaSource.OpenToken,
AlwaysBurnInSubtitleWhenTranscoding = playbackInfoDto?.AlwaysBurnInSubtitleWhenTranscoding ?? false
}).ConfigureAwait(false); }).ConfigureAwait(false);
info.MediaSources = new[] { openStreamResult.MediaSource }; info.MediaSources = new[] { openStreamResult.MediaSource };
@ -261,6 +263,7 @@ public class MediaInfoController : BaseJellyfinApiController
/// <param name="openLiveStreamDto">The open live stream dto.</param> /// <param name="openLiveStreamDto">The open live stream dto.</param>
/// <param name="enableDirectPlay">Whether to enable direct play. Default: true.</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="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> /// <response code="200">Media source opened.</response>
/// <returns>A <see cref="Task"/> containing a <see cref="LiveStreamResponse"/>.</returns> /// <returns>A <see cref="Task"/> containing a <see cref="LiveStreamResponse"/>.</returns>
[HttpPost("LiveStreams/Open")] [HttpPost("LiveStreams/Open")]
@ -277,7 +280,8 @@ public class MediaInfoController : BaseJellyfinApiController
[FromQuery] Guid? itemId, [FromQuery] Guid? itemId,
[FromBody] OpenLiveStreamDto? openLiveStreamDto, [FromBody] OpenLiveStreamDto? openLiveStreamDto,
[FromQuery] bool? enableDirectPlay, [FromQuery] bool? enableDirectPlay,
[FromQuery] bool? enableDirectStream) [FromQuery] bool? enableDirectStream,
[FromQuery] bool? alwaysBurnInSubtitleWhenTranscoding)
{ {
userId ??= openLiveStreamDto?.UserId; userId ??= openLiveStreamDto?.UserId;
userId = RequestHelpers.GetUserId(User, userId); userId = RequestHelpers.GetUserId(User, userId);
@ -295,7 +299,8 @@ public class MediaInfoController : BaseJellyfinApiController
DeviceProfile = openLiveStreamDto?.DeviceProfile, DeviceProfile = openLiveStreamDto?.DeviceProfile,
EnableDirectPlay = enableDirectPlay ?? openLiveStreamDto?.EnableDirectPlay ?? true, EnableDirectPlay = enableDirectPlay ?? openLiveStreamDto?.EnableDirectPlay ?? true,
EnableDirectStream = enableDirectStream ?? openLiveStreamDto?.EnableDirectStream ?? 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); return await _mediaInfoHelper.OpenMediaSource(HttpContext, request).ConfigureAwait(false);
} }

@ -160,6 +160,7 @@ public class UniversalAudioController : BaseJellyfinApiController
true, true,
true, true,
true, true,
false,
Request.HttpContext.GetNormalizedRemoteIP()); Request.HttpContext.GetNormalizedRemoteIP());
} }

@ -156,6 +156,7 @@ public class MediaInfoHelper
/// <param name="enableTranscoding">Enable transcoding.</param> /// <param name="enableTranscoding">Enable transcoding.</param>
/// <param name="allowVideoStreamCopy">Allow video stream copy.</param> /// <param name="allowVideoStreamCopy">Allow video stream copy.</param>
/// <param name="allowAudioStreamCopy">Allow audio 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> /// <param name="ipAddress">Requesting IP address.</param>
public void SetDeviceSpecificData( public void SetDeviceSpecificData(
BaseItem item, BaseItem item,
@ -175,6 +176,7 @@ public class MediaInfoHelper
bool enableTranscoding, bool enableTranscoding,
bool allowVideoStreamCopy, bool allowVideoStreamCopy,
bool allowAudioStreamCopy, bool allowAudioStreamCopy,
bool alwaysBurnInSubtitleWhenTranscoding,
IPAddress ipAddress) IPAddress ipAddress)
{ {
var streamBuilder = new StreamBuilder(_mediaEncoder, _logger); var streamBuilder = new StreamBuilder(_mediaEncoder, _logger);
@ -188,7 +190,8 @@ public class MediaInfoHelper
Profile = profile, Profile = profile,
MaxAudioChannels = maxAudioChannels, MaxAudioChannels = maxAudioChannels,
AllowAudioStreamCopy = allowAudioStreamCopy, AllowAudioStreamCopy = allowAudioStreamCopy,
AllowVideoStreamCopy = allowVideoStreamCopy AllowVideoStreamCopy = allowVideoStreamCopy,
AlwaysBurnInSubtitleWhenTranscoding = alwaysBurnInSubtitleWhenTranscoding,
}; };
if (string.Equals(mediaSourceId, mediaSource.Id, StringComparison.OrdinalIgnoreCase)) if (string.Equals(mediaSourceId, mediaSource.Id, StringComparison.OrdinalIgnoreCase))
@ -420,6 +423,7 @@ public class MediaInfoHelper
true, true,
true, true,
true, true,
request.AlwaysBurnInSubtitleWhenTranscoding,
httpContext.GetNormalizedRemoteIP()); httpContext.GetNormalizedRemoteIP());
} }
else else

@ -65,6 +65,11 @@ public class OpenLiveStreamDto
/// </summary> /// </summary>
public bool? EnableDirectStream { get; set; } 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> /// <summary>
/// Gets or sets the device profile. /// Gets or sets the device profile.
/// </summary> /// </summary>

@ -82,4 +82,9 @@ public class PlaybackInfoDto
/// Gets or sets a value indicating whether to auto open the live stream. /// Gets or sets a value indicating whether to auto open the live stream.
/// </summary> /// </summary>
public bool? AutoOpenLiveStream { get; set; } 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; }
} }

@ -49,6 +49,11 @@ namespace MediaBrowser.Model.Dlna
/// </summary> /// </summary>
public bool AllowVideoStreamCopy { get; set; } 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> /// <summary>
/// Gets or sets the item id. /// Gets or sets the item id.
/// </summary> /// </summary>

@ -20,8 +20,8 @@ namespace MediaBrowser.Model.Dlna
// Aliases // Aliases
internal const TranscodeReason ContainerReasons = TranscodeReason.ContainerNotSupported | TranscodeReason.ContainerBitrateExceedsLimit; 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 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 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; internal const TranscodeReason DirectStreamReasons = AudioReasons | TranscodeReason.ContainerNotSupported | TranscodeReason.VideoCodecTagNotSupported;
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly ITranscoderSupport _transcoderSupport; private readonly ITranscoderSupport _transcoderSupport;
@ -352,7 +352,7 @@ namespace MediaBrowser.Model.Dlna
return TranscodeReason.VideoBitrateNotSupported; return TranscodeReason.VideoBitrateNotSupported;
case ProfileConditionValue.VideoCodecTag: case ProfileConditionValue.VideoCodecTag:
return TranscodeReason.VideoCodecNotSupported; return TranscodeReason.VideoCodecTagNotSupported;
case ProfileConditionValue.VideoFramerate: case ProfileConditionValue.VideoFramerate:
return TranscodeReason.VideoFramerateNotSupported; 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); var subtitleProfile = GetSubtitleProfile(item, subtitleStream, options.Profile.SubtitleProfiles, PlayMethod.Transcode, _transcoderSupport, transcodingProfile.Container, transcodingProfile.Protocol);
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.SubtitleDeliveryMethod = subtitleProfile.Method;
}
playlistItem.SubtitleFormat = subtitleProfile.Format; playlistItem.SubtitleFormat = subtitleProfile.Format;
playlistItem.SubtitleCodecs = new[] { subtitleProfile.Format }; playlistItem.SubtitleCodecs = new[] { subtitleProfile.Format };
} }

@ -13,6 +13,7 @@ namespace MediaBrowser.Model.MediaInfo
{ {
EnableDirectPlay = true; EnableDirectPlay = true;
EnableDirectStream = true; EnableDirectStream = true;
AlwaysBurnInSubtitleWhenTranscoding = false;
DirectPlayProtocols = new MediaProtocol[] { MediaProtocol.Http }; DirectPlayProtocols = new MediaProtocol[] { MediaProtocol.Http };
} }
@ -40,6 +41,8 @@ namespace MediaBrowser.Model.MediaInfo
public bool EnableDirectStream { get; set; } public bool EnableDirectStream { get; set; }
public bool AlwaysBurnInSubtitleWhenTranscoding { get; set; }
public IReadOnlyList<MediaProtocol> DirectPlayProtocols { get; set; } public IReadOnlyList<MediaProtocol> DirectPlayProtocols { get; set; }
} }
} }

@ -18,6 +18,7 @@ namespace MediaBrowser.Model.Session
// Video Constraints // Video Constraints
VideoProfileNotSupported = 1 << 6, VideoProfileNotSupported = 1 << 6,
VideoRangeTypeNotSupported = 1 << 24, VideoRangeTypeNotSupported = 1 << 24,
VideoCodecTagNotSupported = 1 << 25,
VideoLevelNotSupported = 1 << 7, VideoLevelNotSupported = 1 << 7,
VideoResolutionNotSupported = 1 << 8, VideoResolutionNotSupported = 1 << 8,
VideoBitDepthNotSupported = 1 << 9, VideoBitDepthNotSupported = 1 << 9,

Loading…
Cancel
Save