diff --git a/ErsatzTV.Application/Playouts/Commands/SyncNextPlayoutHandler.cs b/ErsatzTV.Application/Playouts/Commands/SyncNextPlayoutHandler.cs index a656955bc..4d626bd52 100644 --- a/ErsatzTV.Application/Playouts/Commands/SyncNextPlayoutHandler.cs +++ b/ErsatzTV.Application/Playouts/Commands/SyncNextPlayoutHandler.cs @@ -304,6 +304,7 @@ public partial class SyncNextPlayoutHandler( var audioVersion = new MediaItemAudioVersion(playoutItem.MediaItem, headVersion); await SelectTracks( channel, + playoutItem, audioVersion, nextPlayoutItem, playoutItem.PreferredAudioLanguageCode ?? channel.PreferredAudioLanguageCode, @@ -327,6 +328,7 @@ public partial class SyncNextPlayoutHandler( private async Task SelectTracks( Channel channel, + PlayoutItem playoutItem, MediaItemAudioVersion audioVersion, Core.Next.PlayoutItem nextPlayoutItem, string preferredAudioLanguage, @@ -335,7 +337,7 @@ public partial class SyncNextPlayoutHandler( ChannelSubtitleMode subtitleMode, CancellationToken cancellationToken) { - List allSubtitles = await GetSubtitles(audioVersion.MediaItem); + List allSubtitles = await GetSubtitles(audioVersion.MediaItem, playoutItem.Id, playoutItem.InPoint); Option maybeAudioStream = Option.None; Option maybeSubtitle = Option.None; @@ -407,6 +409,21 @@ public partial class SyncNextPlayoutHandler( }; } } + else if (subtitle.Path.StartsWith("http://localhost", StringComparison.OrdinalIgnoreCase)) + { + if (nextPlayoutItem.Tracks?.Subtitle?.Source is null) + { + nextPlayoutItem.Tracks ??= new Core.Next.PlayoutItemTracks(); + nextPlayoutItem.Tracks.Subtitle ??= new Core.Next.TrackSelection(); + nextPlayoutItem.Tracks.Subtitle.Source = new Core.Next.Source + { + SourceType = Core.Next.SourceType.Http, + Uri = subtitle.Path, + KeepAlive = false, + Reconnect = true + }; + } + } } } @@ -672,7 +689,10 @@ public partial class SyncNextPlayoutHandler( } } - private static async Task> GetSubtitles(MediaItem mediaItem) + private static async Task> GetSubtitles( + MediaItem mediaItem, + int playoutItemId, + TimeSpan playoutItemInPoint) { List allSubtitles = mediaItem switch { @@ -682,7 +702,7 @@ public partial class SyncNextPlayoutHandler( Movie movie => await Optional(movie.MovieMetadata).Flatten().HeadOrNone() .Map(mm => mm.Subtitles ?? []) .IfNoneAsync([]), - //MusicVideo musicVideo => await GetMusicVideoSubtitles(musicVideo, channel, settings), + MusicVideo => GetMusicVideoSubtitles(playoutItemId, playoutItemInPoint), OtherVideo otherVideo => await Optional(otherVideo.OtherVideoMetadata).Flatten().HeadOrNone() .Map(mm => mm.Subtitles ?? []) .IfNoneAsync([]), @@ -703,4 +723,25 @@ public partial class SyncNextPlayoutHandler( return allSubtitles; } + + private static List GetMusicVideoSubtitles(int playoutItemId, TimeSpan playoutItemInPoint) + { + string seekToMs = playoutItemInPoint > TimeSpan.Zero + ? $"?seekToMs={(long)playoutItemInPoint.TotalMilliseconds}" + : string.Empty; + + return + [ + new Subtitle + { + Codec = "ass", + Default = true, + Forced = true, + IsExtracted = false, + SubtitleKind = SubtitleKind.Generated, + Path = $"http://localhost:{Settings.StreamingPort}/ffmpeg/music-video-credits/{playoutItemId}{seekToMs}", + SDH = false + } + ]; + } } diff --git a/ErsatzTV.Application/Streaming/Queries/GetMusicVideoCreditsByPlayoutItemIdHandler.cs b/ErsatzTV.Application/Streaming/Queries/GetMusicVideoCreditsByPlayoutItemIdHandler.cs index 3ce977cc2..98cdf7655 100644 --- a/ErsatzTV.Application/Streaming/Queries/GetMusicVideoCreditsByPlayoutItemIdHandler.cs +++ b/ErsatzTV.Application/Streaming/Queries/GetMusicVideoCreditsByPlayoutItemIdHandler.cs @@ -60,9 +60,10 @@ public class GetMusicVideoCreditsByPlayoutItemIdHandler( switch (playoutItem.Playout.Channel.MusicVideoCreditsMode) { case ChannelMusicVideoCreditsMode.GenerateSubtitles: - var fileWithExtension = $"{playoutItem.Playout.Channel.MusicVideoCreditsTemplate}.sbntxt"; - if (!string.IsNullOrWhiteSpace(fileWithExtension)) + string templateName = playoutItem.Playout.Channel.MusicVideoCreditsTemplate; + if (!string.IsNullOrWhiteSpace(templateName)) { + var fileWithExtension = $"{templateName}.sbntxt"; subtitles.AddRange( await musicVideoCreditsGenerator.GenerateCreditsSubtitleFromTemplate( musicVideo, @@ -74,7 +75,7 @@ public class GetMusicVideoCreditsByPlayoutItemIdHandler( { logger.LogWarning( "Music video credits template {Template} does not exist; falling back to built-in template", - fileWithExtension); + templateName); subtitles.AddRange( await musicVideoCreditsGenerator.GenerateCreditsSubtitle(