From 097b8c3d1f79fdbca606a3c567009480e1f8c9dc Mon Sep 17 00:00:00 2001 From: Jason Dove Date: Thu, 21 Apr 2022 20:17:50 -0500 Subject: [PATCH] subtitle fixes (#750) * fix crash with missing metadata * fix subtitles in docker * fix software overlay bug --- CHANGELOG.md | 1 + ...layoutItemProcessByChannelNumberHandler.cs | 8 ++-- .../FFmpeg/TranscodingTests.cs | 46 ++++++++++++++----- ErsatzTV.FFmpeg/Filter/ComplexFilter.cs | 4 ++ ErsatzTV.Infrastructure/Data/DbInitializer.cs | 2 +- .../Health/Checks/FFmpegVersionHealthCheck.cs | 2 +- docker/Dockerfile | 4 +- docker/nvidia/Dockerfile | 2 + docker/nvidia/ffmpeg.Dockerfile | 4 +- docker/vaapi/Dockerfile | 2 + docker/vaapi/ffmpeg.Dockerfile | 13 ++++-- 11 files changed, 63 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d04ddfaaf..dea6b2c02 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [Unreleased] ### Fixed - Fix unlocking libraries when scanning fails for any reason +- Fix software overlay of actual size watermark ### Added - Add support for burning in embedded text subtitles diff --git a/ErsatzTV.Application/Streaming/Queries/GetPlayoutItemProcessByChannelNumberHandler.cs b/ErsatzTV.Application/Streaming/Queries/GetPlayoutItemProcessByChannelNumberHandler.cs index 8041020da..00e27dffe 100644 --- a/ErsatzTV.Application/Streaming/Queries/GetPlayoutItemProcessByChannelNumberHandler.cs +++ b/ErsatzTV.Application/Streaming/Queries/GetPlayoutItemProcessByChannelNumberHandler.cs @@ -240,16 +240,16 @@ public class GetPlayoutItemProcessByChannelNumberHandler : FFmpegProcessHandler< { List allSubtitles = playoutItemWithPath.PlayoutItem.MediaItem switch { - Episode episode => episode.EpisodeMetadata.HeadOrNone() + Episode episode => Optional(episode.EpisodeMetadata).Flatten().HeadOrNone() .Map(mm => mm.Subtitles) .IfNone(new List()), - Movie movie => movie.MovieMetadata.HeadOrNone() + Movie movie => Optional(movie.MovieMetadata).Flatten().HeadOrNone() .Map(mm => mm.Subtitles) .IfNone(new List()), - MusicVideo musicVideo => musicVideo.MusicVideoMetadata.HeadOrNone() + MusicVideo musicVideo => Optional(musicVideo.MusicVideoMetadata).Flatten().HeadOrNone() .Map(mm => mm.Subtitles) .IfNone(new List()), - OtherVideo otherVideo => otherVideo.OtherVideoMetadata.HeadOrNone() + OtherVideo otherVideo => Optional(otherVideo.OtherVideoMetadata).Flatten().HeadOrNone() .Map(mm => mm.Subtitles) .IfNone(new List()), _ => new List() diff --git a/ErsatzTV.Core.Tests/FFmpeg/TranscodingTests.cs b/ErsatzTV.Core.Tests/FFmpeg/TranscodingTests.cs index ac9d4026e..2b6aaea9f 100644 --- a/ErsatzTV.Core.Tests/FFmpeg/TranscodingTests.cs +++ b/ErsatzTV.Core.Tests/FFmpeg/TranscodingTests.cs @@ -10,6 +10,7 @@ using ErsatzTV.Core.Interfaces.FFmpeg; using ErsatzTV.Core.Interfaces.Images; using ErsatzTV.Core.Interfaces.Repositories; using ErsatzTV.Core.Metadata; +using ErsatzTV.FFmpeg.State; using FluentAssertions; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Logging; @@ -58,11 +59,13 @@ public class TranscodingTests public enum Watermark { None, - PermanentOpaque, - PermanentTransparent, + PermanentOpaqueScaled, + PermanentOpaqueActualSize, + PermanentTransparentScaled, + PermanentTransparentActualSize, IntermittentOpaque, - IntermittentTransparent + // TODO: animated vs static } @@ -78,8 +81,10 @@ public class TranscodingTests public static Watermark[] Watermarks = { Watermark.None, - Watermark.PermanentOpaque, - Watermark.PermanentTransparent + Watermark.PermanentOpaqueScaled, + Watermark.PermanentOpaqueActualSize, + Watermark.PermanentTransparentScaled, + Watermark.PermanentTransparentActualSize }; public static Subtitle[] Subtitles = @@ -184,8 +189,7 @@ public class TranscodingTests [ValueSource(typeof(TestData), nameof(TestData.VideoFormats))] FFmpegProfileVideoFormat profileVideoFormat, // [ValueSource(typeof(TestData), nameof(TestData.NoAcceleration))] HardwareAccelerationKind profileAcceleration) - [ValueSource(typeof(TestData), nameof(TestData.NvidiaAcceleration))] - HardwareAccelerationKind profileAcceleration) + [ValueSource(typeof(TestData), nameof(TestData.NvidiaAcceleration))] HardwareAccelerationKind profileAcceleration) // [ValueSource(typeof(TestData), nameof(TestData.VaapiAcceleration))] HardwareAccelerationKind profileAcceleration) // [ValueSource(typeof(TestData), nameof(TestData.QsvAcceleration))] HardwareAccelerationKind profileAcceleration) // [ValueSource(typeof(TestData), nameof(TestData.VideoToolboxAcceleration))] HardwareAccelerationKind profileAcceleration) @@ -394,20 +398,40 @@ public class TranscodingTests Opacity = 80 }; break; - case Watermark.PermanentOpaque: + case Watermark.PermanentOpaqueScaled: channelWatermark = new ChannelWatermark { ImageSource = ChannelWatermarkImageSource.Custom, Mode = ChannelWatermarkMode.Permanent, - Opacity = 100 + Opacity = 100, + Size = WatermarkSize.Scaled }; break; - case Watermark.PermanentTransparent: + case Watermark.PermanentOpaqueActualSize: channelWatermark = new ChannelWatermark { ImageSource = ChannelWatermarkImageSource.Custom, Mode = ChannelWatermarkMode.Permanent, - Opacity = 80 + Opacity = 100, + Size = WatermarkSize.ActualSize + }; + break; + case Watermark.PermanentTransparentScaled: + channelWatermark = new ChannelWatermark + { + ImageSource = ChannelWatermarkImageSource.Custom, + Mode = ChannelWatermarkMode.Permanent, + Opacity = 80, + Size = WatermarkSize.Scaled + }; + break; + case Watermark.PermanentTransparentActualSize: + channelWatermark = new ChannelWatermark + { + ImageSource = ChannelWatermarkImageSource.Custom, + Mode = ChannelWatermarkMode.Permanent, + Opacity = 80, + Size = WatermarkSize.ActualSize }; break; } diff --git a/ErsatzTV.FFmpeg/Filter/ComplexFilter.cs b/ErsatzTV.FFmpeg/Filter/ComplexFilter.cs index 35555f78d..6f790fac3 100644 --- a/ErsatzTV.FFmpeg/Filter/ComplexFilter.cs +++ b/ErsatzTV.FFmpeg/Filter/ComplexFilter.cs @@ -142,6 +142,10 @@ public class ComplexFilter : IPipelineStep watermarkLabel = "[wm]"; watermarkFilterComplex += watermarkLabel; } + else + { + watermarkLabel = $"[{watermarkLabel}]"; + } IPipelineFilterStep overlayFilter = AvailableWatermarkOverlayFilters.ForAcceleration( _ffmpegState.HardwareAccelerationMode, diff --git a/ErsatzTV.Infrastructure/Data/DbInitializer.cs b/ErsatzTV.Infrastructure/Data/DbInitializer.cs index 0c058979b..336741e0b 100644 --- a/ErsatzTV.Infrastructure/Data/DbInitializer.cs +++ b/ErsatzTV.Infrastructure/Data/DbInitializer.cs @@ -84,7 +84,7 @@ public static class DbInitializer Number = "1", Name = "ErsatzTV", FFmpegProfile = defaultProfile, - StreamingMode = StreamingMode.TransportStream + StreamingMode = StreamingMode.TransportStreamHybrid }; await context.Channels.AddAsync(defaultChannel, cancellationToken); await context.SaveChangesAsync(cancellationToken); diff --git a/ErsatzTV.Infrastructure/Health/Checks/FFmpegVersionHealthCheck.cs b/ErsatzTV.Infrastructure/Health/Checks/FFmpegVersionHealthCheck.cs index d3b553f10..317c1e518 100644 --- a/ErsatzTV.Infrastructure/Health/Checks/FFmpegVersionHealthCheck.cs +++ b/ErsatzTV.Infrastructure/Health/Checks/FFmpegVersionHealthCheck.cs @@ -8,7 +8,7 @@ namespace ErsatzTV.Infrastructure.Health.Checks; public class FFmpegVersionHealthCheck : BaseHealthCheck, IFFmpegVersionHealthCheck { - private const string BundledVersion = "N-105324-g0f5fd44dc9"; + private const string BundledVersion = "N-106635-g83e1a1de88"; private readonly IConfigElementRepository _configElementRepository; public FFmpegVersionHealthCheck(IConfigElementRepository configElementRepository) => diff --git a/docker/Dockerfile b/docker/Dockerfile index 26812f8df..1e6625b59 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -2,7 +2,7 @@ FROM jasongdove/ffmpeg:5.0-ubuntu2004 AS runtime-base COPY --from=dotnet-runtime /usr/share/dotnet /usr/share/dotnet -RUN apt-get update && DEBIAN_FRONTEND="noninteractive" apt-get install -y libicu-dev tzdata +RUN apt-get update && DEBIAN_FRONTEND="noninteractive" apt-get install -y libicu-dev tzdata fontconfig fonts-dejavu # https://hub.docker.com/_/microsoft-dotnet FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build @@ -36,6 +36,8 @@ RUN dotnet publish ErsatzTV.csproj -c release -o /app -r linux-x64 --self-contai # final stage/image FROM runtime-base +ENV FONTCONFIG_PATH=/etc/fonts +RUN fc-cache update WORKDIR /app EXPOSE 8409 COPY --from=build /app ./ diff --git a/docker/nvidia/Dockerfile b/docker/nvidia/Dockerfile index ba5d4565d..931cafe77 100644 --- a/docker/nvidia/Dockerfile +++ b/docker/nvidia/Dockerfile @@ -30,6 +30,8 @@ RUN dotnet publish ErsatzTV.csproj -c release -o /app -r linux-x64 --self-contai # final stage/image FROM jasongdove/ffmpeg:5.0-nvidia2004 AS runtime-base +ENV FONTCONFIG_PATH=/etc/fonts +RUN fc-cache update WORKDIR /app EXPOSE 8409 COPY --from=build /app ./ diff --git a/docker/nvidia/ffmpeg.Dockerfile b/docker/nvidia/ffmpeg.Dockerfile index 0aa74eb20..805ad55db 100644 --- a/docker/nvidia/ffmpeg.Dockerfile +++ b/docker/nvidia/ffmpeg.Dockerfile @@ -3,5 +3,5 @@ FROM jasongdove/ffmpeg-base:5.0-nvidia2004 AS runtime-base COPY --from=dotnet-runtime /usr/share/dotnet /usr/share/dotnet RUN apt-get update \ - && DEBIAN_FRONTEND="noninteractive" apt-get install -y libicu-dev tzdata \ - && rm -rf /var/lib/apt/lists/* + && DEBIAN_FRONTEND="noninteractive" apt-get install -y libicu-dev tzdata fontconfig fonts-dejavu \ + && rm -rf /var/lib/apt/lists/* diff --git a/docker/vaapi/Dockerfile b/docker/vaapi/Dockerfile index ad14c6b50..e27b94414 100644 --- a/docker/vaapi/Dockerfile +++ b/docker/vaapi/Dockerfile @@ -30,6 +30,8 @@ RUN dotnet publish ErsatzTV.csproj -c release -o /app -r linux-x64 --self-contai # final stage/image FROM jasongdove/ffmpeg:5.0-vaapi2004 AS runtime-base +ENV FONTCONFIG_PATH=/etc/fonts +RUN fc-cache update WORKDIR /app EXPOSE 8409 COPY --from=build /app ./ diff --git a/docker/vaapi/ffmpeg.Dockerfile b/docker/vaapi/ffmpeg.Dockerfile index 8d0a22441..e39c57a14 100644 --- a/docker/vaapi/ffmpeg.Dockerfile +++ b/docker/vaapi/ffmpeg.Dockerfile @@ -4,6 +4,8 @@ FROM jasongdove/ffmpeg-base:5.0-vaapi2004 AS runtime-base COPY --from=dotnet-runtime /usr/share/dotnet /usr/share/dotnet RUN apt-get update && DEBIAN_FRONTEND="noninteractive" apt-get install -y libicu-dev \ tzdata \ + fontconfig \ + fonts-dejavu \ autoconf \ libtool \ libdrm-dev \ @@ -14,21 +16,22 @@ RUN apt-get update && DEBIAN_FRONTEND="noninteractive" apt-get install -y libicu wget \ mesa-va-drivers \ && mkdir /tmp/intel && cd /tmp/intel \ - && wget -O - https://github.com/intel/libva/archive/refs/tags/2.12.0.tar.gz | tar zxf - \ - && cd libva-2.12.0 \ + && wget -O - https://github.com/intel/libva/archive/refs/tags/2.14.0.tar.gz | tar zxf - \ + && cd libva-2.14.0 \ && ./autogen.sh \ && ./configure \ && make -j$(nproc) \ && make -j$(nproc) install \ && cd /tmp/intel \ - && wget -O - https://github.com/intel/gmmlib/archive/refs/tags/intel-gmmlib-21.3.1.tar.gz | tar zxf - \ - && mv gmmlib-intel-gmmlib-21.3.1 gmmlib \ + && wget -O - https://github.com/intel/gmmlib/archive/refs/tags/intel-gmmlib-22.1.2.tar.gz | tar zxf - \ + && mv gmmlib-intel-gmmlib-22.1.2 gmmlib \ && cd gmmlib \ && mkdir build && cd build \ && cmake .. \ && make -j$(nproc) \ + && make install \ && cd /tmp/intel \ - && git clone --depth 1 --branch intel-media-21.2.3 https://github.com/intel/media-driver \ + && git clone --depth 1 --branch intel-media-22.3 https://github.com/intel/media-driver \ && mkdir build_media && cd build_media \ && cmake ../media-driver \ && make -j$(nproc) \