add watermark support to experimental transcoder logic (#654)

* wip

* fix songs again

* don't use lists of video and audio input files

* test concat command output

* move concat pipeline

* start to use ffmpeg state

* add ffmpeg state and audio state

* audio state is required

* attach input options directly to input files

* move filters to input files

* add watermark support
This commit is contained in:
Jason Dove
2022-02-25 21:06:17 -06:00
committed by GitHub
parent 78fdc9c57a
commit a21f62ff8c
70 changed files with 1227 additions and 701 deletions
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using ErsatzTV.Core.Domain;
using ErsatzTV.Core.FFmpeg;
using ErsatzTV.FFmpeg.State;
using FluentAssertions;
using LanguageExt;
using NUnit.Framework;
@@ -141,7 +142,7 @@ namespace ErsatzTV.Core.Tests.FFmpeg
false,
false,
false,
ChannelWatermarkLocation.BottomLeft,
WatermarkLocation.BottomLeft,
false,
100,
"[0:0][1:v]overlay=x=134:y=H-h-54[v]",
@@ -151,7 +152,7 @@ namespace ErsatzTV.Core.Tests.FFmpeg
false,
false,
false,
ChannelWatermarkLocation.BottomRight,
WatermarkLocation.BottomRight,
false,
100,
"[0:0][1:v]overlay=x=W-w-134:y=H-h-54[v]",
@@ -161,7 +162,7 @@ namespace ErsatzTV.Core.Tests.FFmpeg
false,
false,
false,
ChannelWatermarkLocation.TopLeft,
WatermarkLocation.TopLeft,
false,
100,
"[0:0][1:v]overlay=x=134:y=54[v]",
@@ -171,7 +172,7 @@ namespace ErsatzTV.Core.Tests.FFmpeg
false,
false,
false,
ChannelWatermarkLocation.TopRight,
WatermarkLocation.TopRight,
false,
100,
"[0:0][1:v]overlay=x=W-w-134:y=54[v]",
@@ -181,7 +182,7 @@ namespace ErsatzTV.Core.Tests.FFmpeg
false,
false,
true,
ChannelWatermarkLocation.TopLeft,
WatermarkLocation.TopLeft,
false,
100,
"[1:v]format=yuva420p|yuva444p|yuva422p|rgba|abgr|bgra|gbrap|ya8,fade=in:st=300:d=1:alpha=1:enable='between(t,0,314)',fade=out:st=315:d=1:alpha=1:enable='between(t,301,899)',fade=in:st=900:d=1:alpha=1:enable='between(t,316,914)',fade=out:st=915:d=1:alpha=1:enable='between(t,901,1499)',fade=in:st=1500:d=1:alpha=1:enable='between(t,916,1514)',fade=out:st=1515:d=1:alpha=1:enable='between(t,1501,2099)',fade=in:st=2100:d=1:alpha=1:enable='between(t,1516,2114)',fade=out:st=2115:d=1:alpha=1:enable='between(t,2101,2699)',fade=in:st=2700:d=1:alpha=1:enable='between(t,2116,2714)',fade=out:st=2715:d=1:alpha=1:enable='between(t,2701,3300)'[wmp];[0:0][wmp]overlay=x=134:y=54,format=nv12[v]",
@@ -191,7 +192,7 @@ namespace ErsatzTV.Core.Tests.FFmpeg
false,
false,
false,
ChannelWatermarkLocation.TopLeft,
WatermarkLocation.TopLeft,
true,
100,
"[1:v]scale=384:-1[wmp];[0:0][wmp]overlay=x=134:y=54[v]",
@@ -201,7 +202,7 @@ namespace ErsatzTV.Core.Tests.FFmpeg
false,
false,
false,
ChannelWatermarkLocation.TopLeft,
WatermarkLocation.TopLeft,
false,
90,
"[1:v]format=yuva420p|yuva444p|yuva422p|rgba|abgr|bgra|gbrap|ya8,colorchannelmixer=aa=0.90[wmp];[0:0][wmp]overlay=x=134:y=54[v]",
@@ -211,7 +212,7 @@ namespace ErsatzTV.Core.Tests.FFmpeg
false,
true,
false,
ChannelWatermarkLocation.TopLeft,
WatermarkLocation.TopLeft,
false,
100,
"[0:0]yadif=1[vt];[vt][1:v]overlay=x=134:y=54[v]",
@@ -221,7 +222,7 @@ namespace ErsatzTV.Core.Tests.FFmpeg
false,
true,
false,
ChannelWatermarkLocation.TopLeft,
WatermarkLocation.TopLeft,
true,
100,
"[0:0]yadif=1[vt];[1:v]scale=384:-1[wmp];[vt][wmp]overlay=x=134:y=54[v]",
@@ -231,7 +232,7 @@ namespace ErsatzTV.Core.Tests.FFmpeg
true,
true,
false,
ChannelWatermarkLocation.TopLeft,
WatermarkLocation.TopLeft,
false,
100,
"[0:1]apad=whole_dur=3300000ms[a];[0:0]yadif=1[vt];[vt][1:v]overlay=x=134:y=54[v]",
@@ -241,7 +242,7 @@ namespace ErsatzTV.Core.Tests.FFmpeg
true,
false,
false,
ChannelWatermarkLocation.TopLeft,
WatermarkLocation.TopLeft,
false,
100,
"[0:1]apad=whole_dur=3300000ms[a];[0:0][1:v]overlay=x=134:y=54[v]",
@@ -251,7 +252,7 @@ namespace ErsatzTV.Core.Tests.FFmpeg
bool alignAudio,
bool deinterlace,
bool intermittent,
ChannelWatermarkLocation location,
WatermarkLocation location,
bool scaled,
int opacity,
string expectedVideoFilter,
@@ -266,7 +267,7 @@ namespace ErsatzTV.Core.Tests.FFmpeg
DurationSeconds = intermittent ? 15 : 0,
FrequencyMinutes = intermittent ? 10 : 0,
Location = location,
Size = scaled ? ChannelWatermarkSize.Scaled : ChannelWatermarkSize.ActualSize,
Size = scaled ? WatermarkSize.Scaled : WatermarkSize.ActualSize,
WidthPercent = scaled ? 20 : 0,
Opacity = opacity,
HorizontalMarginPercent = 7,
@@ -310,7 +311,7 @@ namespace ErsatzTV.Core.Tests.FFmpeg
false,
false,
false,
ChannelWatermarkLocation.BottomLeft,
WatermarkLocation.BottomLeft,
false,
100,
"[0:0]scale_cuda=format=yuv420p[vt];[1:v]format=yuva420p,hwupload_cuda[wmp];[vt][wmp]overlay_cuda=x=134:y=H-h-54[v]",
@@ -321,7 +322,7 @@ namespace ErsatzTV.Core.Tests.FFmpeg
false,
false,
false,
ChannelWatermarkLocation.BottomLeft,
WatermarkLocation.BottomLeft,
false,
100,
"[0:0]scale_cuda=1920:1080,setsar=1,hwdownload,format=nv12,format=yuv420p,hwupload_cuda[vt];[1:v]format=yuva420p,hwupload_cuda[wmp];[vt][wmp]overlay_cuda=x=134:y=H-h-54,hwupload[v]",
@@ -332,7 +333,7 @@ namespace ErsatzTV.Core.Tests.FFmpeg
false,
false,
true,
ChannelWatermarkLocation.TopLeft,
WatermarkLocation.TopLeft,
false,
100,
"[0:0]scale_cuda=format=yuv420p[vt];[1:v]format=yuva420p,fade=in:st=300:d=1:alpha=1:enable='between(t,0,314)',fade=out:st=315:d=1:alpha=1:enable='between(t,301,899)',fade=in:st=900:d=1:alpha=1:enable='between(t,316,914)',fade=out:st=915:d=1:alpha=1:enable='between(t,901,1499)',fade=in:st=1500:d=1:alpha=1:enable='between(t,916,1514)',fade=out:st=1515:d=1:alpha=1:enable='between(t,1501,2099)',fade=in:st=2100:d=1:alpha=1:enable='between(t,1516,2114)',fade=out:st=2115:d=1:alpha=1:enable='between(t,2101,2699)',fade=in:st=2700:d=1:alpha=1:enable='between(t,2116,2714)',fade=out:st=2715:d=1:alpha=1:enable='between(t,2701,3300)',hwupload_cuda[wmp];[vt][wmp]overlay_cuda=x=134:y=54[v]",
@@ -343,7 +344,7 @@ namespace ErsatzTV.Core.Tests.FFmpeg
false,
false,
true,
ChannelWatermarkLocation.TopLeft,
WatermarkLocation.TopLeft,
false,
100,
"[0:0]scale_cuda=1920:1080,setsar=1,hwdownload,format=nv12,format=yuv420p,hwupload_cuda[vt];[1:v]format=yuva420p,fade=in:st=300:d=1:alpha=1:enable='between(t,0,314)',fade=out:st=315:d=1:alpha=1:enable='between(t,301,899)',fade=in:st=900:d=1:alpha=1:enable='between(t,316,914)',fade=out:st=915:d=1:alpha=1:enable='between(t,901,1499)',fade=in:st=1500:d=1:alpha=1:enable='between(t,916,1514)',fade=out:st=1515:d=1:alpha=1:enable='between(t,1501,2099)',fade=in:st=2100:d=1:alpha=1:enable='between(t,1516,2114)',fade=out:st=2115:d=1:alpha=1:enable='between(t,2101,2699)',fade=in:st=2700:d=1:alpha=1:enable='between(t,2116,2714)',fade=out:st=2715:d=1:alpha=1:enable='between(t,2701,3300)',hwupload_cuda[wmp];[vt][wmp]overlay_cuda=x=134:y=54,hwupload[v]",
@@ -354,7 +355,7 @@ namespace ErsatzTV.Core.Tests.FFmpeg
false,
false,
false,
ChannelWatermarkLocation.TopLeft,
WatermarkLocation.TopLeft,
true,
100,
"[0:0]scale_cuda=format=yuv420p[vt];[1:v]format=yuva420p,scale=384:-1,hwupload_cuda[wmp];[vt][wmp]overlay_cuda=x=134:y=54[v]",
@@ -365,7 +366,7 @@ namespace ErsatzTV.Core.Tests.FFmpeg
false,
false,
false,
ChannelWatermarkLocation.TopLeft,
WatermarkLocation.TopLeft,
true,
100,
"[0:0]scale_cuda=1920:1080,setsar=1,hwdownload,format=nv12,format=yuv420p,hwupload_cuda[vt];[1:v]format=yuva420p,scale=384:-1,hwupload_cuda[wmp];[vt][wmp]overlay_cuda=x=134:y=54,hwupload[v]",
@@ -376,7 +377,7 @@ namespace ErsatzTV.Core.Tests.FFmpeg
false,
false,
false,
ChannelWatermarkLocation.TopLeft,
WatermarkLocation.TopLeft,
false,
90,
"[0:0]scale_cuda=format=yuv420p[vt];[1:v]format=yuva420p,colorchannelmixer=aa=0.90,hwupload_cuda[wmp];[vt][wmp]overlay_cuda=x=134:y=54[v]",
@@ -387,7 +388,7 @@ namespace ErsatzTV.Core.Tests.FFmpeg
false,
false,
false,
ChannelWatermarkLocation.TopLeft,
WatermarkLocation.TopLeft,
false,
90,
"[0:0]scale_cuda=1920:1080,setsar=1,hwdownload,format=nv12,format=yuv420p,hwupload_cuda[vt];[1:v]format=yuva420p,colorchannelmixer=aa=0.90,hwupload_cuda[wmp];[vt][wmp]overlay_cuda=x=134:y=54,hwupload[v]",
@@ -399,7 +400,7 @@ namespace ErsatzTV.Core.Tests.FFmpeg
// false,
// true,
// false,
// ChannelWatermarkLocation.TopLeft,
// WatermarkLocation.TopLeft,
// false,
// 100,
// "[0:0]yadif=1[vt];[vt][1:v]overlay=x=134:y=54[v]",
@@ -409,7 +410,7 @@ namespace ErsatzTV.Core.Tests.FFmpeg
// false,
// true,
// false,
// ChannelWatermarkLocation.TopLeft,
// WatermarkLocation.TopLeft,
// true,
// 100,
// "[0:0]yadif=1[vt];[1:v]scale=384:-1[wmp];[vt][wmp]overlay=x=134:y=54[v]",
@@ -419,7 +420,7 @@ namespace ErsatzTV.Core.Tests.FFmpeg
// true,
// true,
// false,
// ChannelWatermarkLocation.TopLeft,
// WatermarkLocation.TopLeft,
// false,
// 100,
// "[0:1]apad=whole_dur=3300000ms[a];[0:0]yadif=1[vt];[vt][1:v]overlay=x=134:y=54[v]",
@@ -429,7 +430,7 @@ namespace ErsatzTV.Core.Tests.FFmpeg
true,
false,
false,
ChannelWatermarkLocation.TopLeft,
WatermarkLocation.TopLeft,
false,
100,
"[0:1]apad=whole_dur=3300000ms[a];[0:0]scale_cuda=format=yuv420p[vt];[1:v]format=yuva420p,hwupload_cuda[wmp];[vt][wmp]overlay_cuda=x=134:y=54[v]",
@@ -440,7 +441,7 @@ namespace ErsatzTV.Core.Tests.FFmpeg
true,
false,
false,
ChannelWatermarkLocation.TopLeft,
WatermarkLocation.TopLeft,
false,
100,
"[0:1]apad=whole_dur=3300000ms[a];[0:0]scale_cuda=1920:1080,setsar=1,hwdownload,format=nv12,format=yuv420p,hwupload_cuda[vt];[1:v]format=yuva420p,hwupload_cuda[wmp];[vt][wmp]overlay_cuda=x=134:y=54,hwupload[v]",
@@ -451,7 +452,7 @@ namespace ErsatzTV.Core.Tests.FFmpeg
bool alignAudio,
bool deinterlace,
bool intermittent,
ChannelWatermarkLocation location,
WatermarkLocation location,
bool scaled,
int opacity,
string expectedVideoFilter,
@@ -467,7 +468,7 @@ namespace ErsatzTV.Core.Tests.FFmpeg
DurationSeconds = intermittent ? 15 : 0,
FrequencyMinutes = intermittent ? 10 : 0,
Location = location,
Size = scaled ? ChannelWatermarkSize.Scaled : ChannelWatermarkSize.ActualSize,
Size = scaled ? WatermarkSize.Scaled : WatermarkSize.ActualSize,
WidthPercent = scaled ? 20 : 0,
Opacity = opacity,
HorizontalMarginPercent = 7,