diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d74a325f..228dd464a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Changed - Allow multiple watermarks on a single playout item +- Allow multiple watermarks in playback troubleshooting - YAML playout: `watermark` instruction changes: - When value is `true`, will add named watermark to list of active watermarks - When value is `false` and `name` is specified, will remove named watermark from list of active watermarks diff --git a/ErsatzTV.Application/Troubleshooting/Commands/ArchiveTroubleshootingResults.cs b/ErsatzTV.Application/Troubleshooting/Commands/ArchiveTroubleshootingResults.cs index 1da40232e..11b665437 100644 --- a/ErsatzTV.Application/Troubleshooting/Commands/ArchiveTroubleshootingResults.cs +++ b/ErsatzTV.Application/Troubleshooting/Commands/ArchiveTroubleshootingResults.cs @@ -3,6 +3,6 @@ namespace ErsatzTV.Application.Troubleshooting; public record ArchiveTroubleshootingResults( int MediaItemId, int FFmpegProfileId, - int WatermarkId, + List WatermarkIds, bool StartFromBeginning) : IRequest>; diff --git a/ErsatzTV.Application/Troubleshooting/Commands/PrepareTroubleshootingPlayback.cs b/ErsatzTV.Application/Troubleshooting/Commands/PrepareTroubleshootingPlayback.cs index fc69bf5ab..275dab4b4 100644 --- a/ErsatzTV.Application/Troubleshooting/Commands/PrepareTroubleshootingPlayback.cs +++ b/ErsatzTV.Application/Troubleshooting/Commands/PrepareTroubleshootingPlayback.cs @@ -6,7 +6,7 @@ namespace ErsatzTV.Application.Troubleshooting; public record PrepareTroubleshootingPlayback( int MediaItemId, int FFmpegProfileId, - int WatermarkId, + List WatermarkIds, int? SubtitleId, bool StartFromBeginning) : IRequest>; diff --git a/ErsatzTV.Application/Troubleshooting/Commands/PrepareTroubleshootingPlaybackHandler.cs b/ErsatzTV.Application/Troubleshooting/Commands/PrepareTroubleshootingPlaybackHandler.cs index 7181bafd0..548762c16 100644 --- a/ErsatzTV.Application/Troubleshooting/Commands/PrepareTroubleshootingPlaybackHandler.cs +++ b/ErsatzTV.Application/Troubleshooting/Commands/PrepareTroubleshootingPlaybackHandler.cs @@ -1,4 +1,3 @@ -using CliWrap; using Dapper; using ErsatzTV.Core; using ErsatzTV.Core.Domain; @@ -79,10 +78,13 @@ public class PrepareTroubleshootingPlaybackHandler( } List watermarks = []; - if (request.WatermarkId > 0) + if (request.WatermarkIds.Count > 0) { - watermarks.AddRange(await dbContext.ChannelWatermarks - .SelectOneAsync(cw => cw.Id, cw => cw.Id == request.WatermarkId)); + var channelWatermarks = await dbContext.ChannelWatermarks + .Where(w => request.WatermarkIds.Contains(w.Id)) + .ToListAsync(); + + watermarks.AddRange(channelWatermarks); } DateTimeOffset now = DateTimeOffset.Now; diff --git a/ErsatzTV/Controllers/Api/TroubleshootController.cs b/ErsatzTV/Controllers/Api/TroubleshootController.cs index 3a3fb637d..16140d839 100644 --- a/ErsatzTV/Controllers/Api/TroubleshootController.cs +++ b/ErsatzTV/Controllers/Api/TroubleshootController.cs @@ -27,7 +27,7 @@ public class TroubleshootController( [FromQuery] int ffmpegProfile, [FromQuery] - int watermark, + List watermark, [FromQuery] int? subtitleId, [FromQuery] @@ -63,7 +63,7 @@ public class TroubleshootController( troubleshootingInfo.FFmpegProfiles.RemoveAll(p => p.Id != ffmpegProfile); // filter watermarks - troubleshootingInfo.Watermarks.RemoveAll(p => p.Id != watermark); + troubleshootingInfo.Watermarks.RemoveAll(p => !watermark.Contains(p.Id)); await channelWriter.WriteAsync( new StartTroubleshootingPlayback(sessionId, playoutItemResult, mediaInfo, @@ -113,7 +113,7 @@ public class TroubleshootController( [FromQuery] int ffmpegProfile, [FromQuery] - int watermark, + List watermark, [FromQuery] bool startFromBeginning, CancellationToken cancellationToken) diff --git a/ErsatzTV/Pages/PlaybackTroubleshooting.razor b/ErsatzTV/Pages/PlaybackTroubleshooting.razor index aeba4f3e2..2ea0a56a5 100644 --- a/ErsatzTV/Pages/PlaybackTroubleshooting.razor +++ b/ErsatzTV/Pages/PlaybackTroubleshooting.razor @@ -21,7 +21,7 @@ Class="ml-6" StartIcon="@Icons.Material.Filled.Download" Disabled="@(!_hasPlayed || Locker.IsTroubleshootingPlaybackLocked())" - OnClick="DownloadResults"> + OnClick="@DownloadResults"> Download Results @@ -56,13 +56,12 @@
- Watermark + Watermarks
- - (none) + @foreach (WatermarkViewModel watermark in _watermarks) { - @watermark.Name + @watermark.Name }
@@ -119,12 +118,12 @@ @code { private readonly CancellationTokenSource _cts = new(); - private List _ffmpegProfiles = []; - private List _watermarks = []; - private List _subtitleStreams = []; + private readonly List _ffmpegProfiles = []; + private readonly List _watermarks = []; + private readonly List _subtitleStreams = []; private MediaItemInfo _info; private int _ffmpegProfileId; - private int? _watermarkId; + private IEnumerable _watermarkNames = new System.Collections.Generic.HashSet(); private int? _subtitleId; private bool _startFromBeginning; private bool _hasPlayed; @@ -146,13 +145,13 @@ protected override async Task OnParametersSetAsync() { - _ffmpegProfiles = await Mediator.Send(new GetAllFFmpegProfiles(), _cts.Token); + _ffmpegProfiles.AddRange(await Mediator.Send(new GetAllFFmpegProfiles(), _cts.Token)); if (_ffmpegProfiles.Count > 0) { _ffmpegProfileId = _ffmpegProfiles.Map(f => f.Id).Head(); } - _watermarks = await Mediator.Send(new GetAllWatermarks(), _cts.Token); + _watermarks.AddRange(await Mediator.Send(new GetAllWatermarks(), _cts.Token)); if (MediaItemId is not null) { @@ -166,7 +165,14 @@ { var uri = new UriBuilder(NavigationManager.ToAbsoluteUri(NavigationManager.Uri)); uri.Path = uri.Path.Replace("/system/troubleshooting/playback", "/api/troubleshoot/playback.m3u8"); - uri.Query = $"?mediaItem={MediaItemId}&ffmpegProfile={_ffmpegProfileId}&watermark={_watermarkId ?? 0}&startFromBeginning={_startFromBeginning}"; + uri.Query = $"?mediaItem={MediaItemId}&ffmpegProfile={_ffmpegProfileId}&startFromBeginning={_startFromBeginning}"; + foreach (var watermarkName in _watermarkNames) + { + foreach (var watermark in _watermarks.Where(wm => wm.Name == watermarkName)) + { + uri.Query += $"&watermark={watermark.Id}"; + } + } if (_subtitleId is not null) { uri.Query += $"&subtitleId={_subtitleId.Value}"; @@ -207,7 +213,15 @@ private async Task DownloadResults() { - await JsRuntime.InvokeVoidAsync("window.open", $"api/troubleshoot/playback/archive?mediaItem={MediaItemId ?? 0}&ffmpegProfile={_ffmpegProfileId}&watermark={_watermarkId ?? 0}&startFromBeginning={_startFromBeginning}"); + var uri = $"api/troubleshoot/playback/archive?mediaItem={MediaItemId ?? 0}&ffmpegProfile={_ffmpegProfileId}&startFromBeginning={_startFromBeginning}"; + foreach (var watermarkName in _watermarkNames) + { + foreach (var watermark in _watermarks.Where(wm => wm.Name == watermarkName)) + { + uri += $"&watermark={watermark.Id}"; + } + } + await JsRuntime.InvokeVoidAsync("window.open", uri); } private void HandleTroubleshootingCompleted(PlaybackTroubleshootingCompletedNotification result)