Browse Source

use subtitles instead of drawtext for songs (#510)

pull/512/head
Jason Dove 5 years ago committed by GitHub
parent
commit
919325033d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 11
      ErsatzTV.Application/Streaming/Queries/GetPlayoutItemProcessByChannelNumberHandler.cs
  2. 41
      ErsatzTV.Core/FFmpeg/FFmpegComplexFilterBuilder.cs
  3. 8
      ErsatzTV.Core/FFmpeg/FFmpegProcessBuilder.cs
  4. 4
      ErsatzTV.Core/FFmpeg/FFmpegProcessService.cs
  5. 2
      ErsatzTV.Core/FFmpeg/TempFileCategory.cs
  6. 2
      ErsatzTV.Core/Interfaces/FFmpeg/IFFmpegProcessService.cs

11
ErsatzTV.Application/Streaming/Queries/GetPlayoutItemProcessByChannelNumberHandler.cs

@ -142,7 +142,7 @@ namespace ErsatzTV.Application.Streaming.Queries @@ -142,7 +142,7 @@ namespace ErsatzTV.Application.Streaming.Queries
if (playoutItemWithPath.PlayoutItem.MediaItem is Song song)
{
Option<string> drawtextFile = None;
Option<string> subtitleFile = None;
videoVersion = new FallbackMediaVersion
{
@ -175,10 +175,13 @@ namespace ErsatzTV.Application.Streaming.Queries @@ -175,10 +175,13 @@ namespace ErsatzTV.Application.Streaming.Queries
// use thumbnail (cover art) if present
foreach (SongMetadata metadata in song.SongMetadata)
{
string fileName = _tempFilePool.GetNextTempFile(TempFileCategory.DrawText);
drawtextFile = fileName;
string fileName = _tempFilePool.GetNextTempFile(TempFileCategory.Subtitle);
subtitleFile = fileName;
var sb = new StringBuilder();
sb.AppendLine("1");
sb.AppendLine("00:00:00,000 --> 99:99:99,999");
if (!string.IsNullOrWhiteSpace(metadata.Artist))
{
sb.AppendLine(metadata.Artist);
@ -231,7 +234,7 @@ namespace ErsatzTV.Application.Streaming.Queries @@ -231,7 +234,7 @@ namespace ErsatzTV.Application.Streaming.Queries
Either<BaseError, string> maybeSongImage = await _ffmpegProcessService.GenerateSongImage(
ffmpegPath,
drawtextFile,
subtitleFile,
channel,
maybeGlobalWatermark,
videoVersion,

41
ErsatzTV.Core/FFmpeg/FFmpegComplexFilterBuilder.cs

@ -28,7 +28,7 @@ namespace ErsatzTV.Core.FFmpeg @@ -28,7 +28,7 @@ namespace ErsatzTV.Core.FFmpeg
private Option<int> _watermarkIndex;
private string _pixelFormat;
private string _videoEncoder;
private Option<string> _drawtext;
private Option<string> _subtitle;
public FFmpegComplexFilterBuilder WithHardwareAcceleration(HardwareAccelerationKind hardwareAccelerationKind)
{
@ -97,21 +97,21 @@ namespace ErsatzTV.Core.FFmpeg @@ -97,21 +97,21 @@ namespace ErsatzTV.Core.FFmpeg
return this;
}
public FFmpegComplexFilterBuilder WithDrawtextFile(
public FFmpegComplexFilterBuilder WithSubtitleFile(
MediaVersion videoVersion,
Option<string> drawtextFile)
Option<string> subtitleFile)
{
foreach (string file in drawtextFile)
foreach (string file in subtitleFile)
{
string effectiveFile = file;
if (videoVersion is FallbackMediaVersion or CoverArtMediaVersion)
{
string fontPath = Path.Combine(FileSystemLayout.ResourcesCacheFolder, "OPTIKabel-Heavy.otf");
string fontsDir = FileSystemLayout.ResourcesCacheFolder;
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
fontPath = fontPath
fontsDir = fontsDir
.Replace(@"\", @"/\")
.Replace(@":/", @"\\:/");
@ -120,27 +120,31 @@ namespace ErsatzTV.Core.FFmpeg @@ -120,27 +120,31 @@ namespace ErsatzTV.Core.FFmpeg
.Replace(@":/", @"\\:/");
}
var horizontalMarginPercent = 3;
var leftMarginPercent = 3;
var rightMarginPercent = 3;
const int VERTICAL_MARGIN_PERCENT = 5;
foreach (ChannelWatermark watermark in _watermark)
{
horizontalMarginPercent = watermark.HorizontalMarginPercent;
leftMarginPercent = rightMarginPercent = watermark.HorizontalMarginPercent;
switch (watermark.Location)
{
case ChannelWatermarkLocation.BottomLeft:
horizontalMarginPercent += watermark.WidthPercent + watermark.HorizontalMarginPercent;
leftMarginPercent += watermark.WidthPercent + watermark.HorizontalMarginPercent;
break;
case ChannelWatermarkLocation.BottomRight:
rightMarginPercent += watermark.WidthPercent + watermark.HorizontalMarginPercent;
break;
}
}
double horizontalMargin = Math.Round(horizontalMarginPercent / 100.0 * _resolution.Width);
double leftMargin = Math.Round(leftMarginPercent / 100.0 * _resolution.Width);
double rightMargin = Math.Round(rightMarginPercent / 100.0 * _resolution.Width);
double verticalMargin = Math.Round(VERTICAL_MARGIN_PERCENT / 100.0 * _resolution.Height);
var location = $"x={horizontalMargin}:y=H-text_h-{verticalMargin}";
_drawtext =
$"drawtext=fontfile={fontPath}:textfile={effectiveFile}:{location}:fontsize=(h/25):fontcolor=white:line_spacing=7";
double fontSize = Math.Round(_resolution.Height / 20.0);
_subtitle =
$"subtitles={effectiveFile}:fontsdir={fontsDir}:force_style='PlayResX={_resolution.Width},PlayResY={_resolution.Height},Fontname=OPTIKabel-Heavy,Fontsize={fontSize},PrimaryColour=&HFFFFFF,OutlineColour=&H555555,Alignment=0,MarginR={rightMargin},MarginL={leftMargin},MarginV={verticalMargin},Shadow=3'";
}
}
@ -308,9 +312,6 @@ namespace ErsatzTV.Core.FFmpeg @@ -308,9 +312,6 @@ namespace ErsatzTV.Core.FFmpeg
$"palettegen=max_colors=8,crop=1:1:{next}:0,scale={_resolution.Width}:{_resolution.Height},setsar=1:1";
}
filter +=
"[b];[b]split[b1][b2];[b1]format=rgba,geq=r=0:g=0:b=0:a=70[fg];[b2][fg]overlay=format=auto";
videoFilterQueue.Add(filter);
}
@ -365,9 +366,9 @@ namespace ErsatzTV.Core.FFmpeg @@ -365,9 +366,9 @@ namespace ErsatzTV.Core.FFmpeg
_padToSize.IfSome(size => videoFilterQueue.Add($"pad={size.Width}:{size.Height}:(ow-iw)/2:(oh-ih)/2"));
foreach (string drawtext in _drawtext)
foreach (string subtitle in _subtitle)
{
videoFilterQueue.Add(drawtext);
videoFilterQueue.Add(subtitle);
}
string outputPixelFormat = null;

8
ErsatzTV.Core/FFmpeg/FFmpegProcessBuilder.cs

@ -221,13 +221,13 @@ namespace ErsatzTV.Core.FFmpeg @@ -221,13 +221,13 @@ namespace ErsatzTV.Core.FFmpeg
return this;
}
public FFmpegProcessBuilder WithDrawtextFile(
public FFmpegProcessBuilder WithSubtitleFile(
MediaVersion videoVersion,
Option<string> drawtextFile)
Option<string> subtitleFile)
{
_complexFilterBuilder = _complexFilterBuilder.WithDrawtextFile(
_complexFilterBuilder = _complexFilterBuilder.WithSubtitleFile(
videoVersion,
drawtextFile);
subtitleFile);
return this;
}

4
ErsatzTV.Core/FFmpeg/FFmpegProcessService.cs

@ -238,7 +238,7 @@ namespace ErsatzTV.Core.FFmpeg @@ -238,7 +238,7 @@ namespace ErsatzTV.Core.FFmpeg
public async Task<Either<BaseError, string>> GenerateSongImage(
string ffmpegPath,
Option<string> drawtextFile,
Option<string> subtitleFile,
Channel channel,
Option<ChannelWatermark> globalWatermark,
MediaVersion videoVersion,
@ -273,7 +273,7 @@ namespace ErsatzTV.Core.FFmpeg @@ -273,7 +273,7 @@ namespace ErsatzTV.Core.FFmpeg
.WithFormatFlags(playbackSettings.FormatFlags)
.WithSongInput(videoPath, videoStream.Codec, videoStream.PixelFormat)
.WithWatermark(watermarkOptions, channel.FFmpegProfile.Resolution)
.WithDrawtextFile(videoVersion, drawtextFile);
.WithSubtitleFile(videoVersion, subtitleFile);
foreach (IDisplaySize scaledSize in scalePlaybackSettings.ScaledSize)
{

2
ErsatzTV.Core/FFmpeg/TempFileCategory.cs

@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
{
public enum TempFileCategory
{
DrawText = 0,
Subtitle = 0,
SongBackground = 1,
CoverArt = 2
}

2
ErsatzTV.Core/Interfaces/FFmpeg/IFFmpegProcessService.cs

@ -42,7 +42,7 @@ namespace ErsatzTV.Core.Interfaces.FFmpeg @@ -42,7 +42,7 @@ namespace ErsatzTV.Core.Interfaces.FFmpeg
Task<Either<BaseError, string>> GenerateSongImage(
string ffmpegPath,
Option<string> drawtextFile,
Option<string> subtitleFile,
Channel channel,
Option<ChannelWatermark> globalWatermark,
MediaVersion videoVersion,

Loading…
Cancel
Save