From dcd792a354cebbc24d41fb379517198180c5afd0 Mon Sep 17 00:00:00 2001 From: Jason Dove Date: Mon, 7 Mar 2022 20:04:21 -0600 Subject: [PATCH] fix hls direct streaming mode (#682) --- CHANGELOG.md | 2 + ErsatzTV.FFmpeg.Tests/PipelineBuilderTests.cs | 62 +++++++++++++++++++ ErsatzTV.FFmpeg/PipelineBuilder.cs | 5 ++ 3 files changed, 69 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d067f1cf1..79bc859cc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [Unreleased] +### Fixed +- Fix `HLS Direct` streaming mode ## [0.4.3-alpha] - 2022-03-05 ### Fixed diff --git a/ErsatzTV.FFmpeg.Tests/PipelineBuilderTests.cs b/ErsatzTV.FFmpeg.Tests/PipelineBuilderTests.cs index 1e74ee749..6f1b2c768 100644 --- a/ErsatzTV.FFmpeg.Tests/PipelineBuilderTests.cs +++ b/ErsatzTV.FFmpeg.Tests/PipelineBuilderTests.cs @@ -93,6 +93,68 @@ public class PipelineGeneratorTests "-threads 1 -nostdin -hide_banner -nostats -loglevel error -fflags +genpts+discardcorrupt+igndts -f concat -safe 0 -protocol_whitelist file,http,tcp,https,tcp,tls -probesize 32 -re -stream_loop -1 -i http://localhost:8080/ffmpeg/concat/1 -muxdelay 0 -muxpreload 0 -movflags +faststart -flags cgop -sc_threshold 0 -c copy -map_metadata -1 -metadata service_provider=\"ErsatzTV\" -metadata service_name=\"Some Channel\" -f mpegts -mpegts_flags +initial_discontinuity pipe:1"); } + [Test] + public void HlsDirect_Test() + { + var videoInputFile = new VideoInputFile( + "/tmp/whatever.mkv", + new List + { new(0, VideoFormat.H264, new PixelFormatYuv420P(), new FrameSize(1920, 1080), "24", false) }); + + var audioInputFile = new AudioInputFile( + "/tmp/whatever.mkv", + new List { new(1, AudioFormat.Aac, 2) }, + new AudioState( + AudioFormat.Copy, + None, + None, + None, + None, + None, + false)); + + var desiredState = new FrameState( + true, + false, + VideoFormat.Copy, + new PixelFormatYuv420P(), + new FrameSize(1920, 1080), + new FrameSize(1920, 1080), + Option.None, + 2000, + 4000, + 90_000, + false); + + var ffmpegState = new FFmpegState( + false, + HardwareAccelerationMode.None, + Option.None, + Option.None, + Option.None, + Option.None, + false, + Option.None, + Option.None, + Option.None, + OutputFormatKind.MpegTs, + Option.None, + Option.None, + 0); + + var builder = new PipelineBuilder(videoInputFile, audioInputFile, None, "", _logger); + FFmpegPipeline result = builder.Build(ffmpegState, desiredState); + + result.PipelineSteps.Should().HaveCountGreaterThan(0); + result.PipelineSteps.Should().Contain(ps => ps is EncoderCopyVideo); + result.PipelineSteps.Should().Contain(ps => ps is EncoderCopyAudio); + + string command = PrintCommand(videoInputFile, audioInputFile, None, None, result); + + command.Should().Be( + "-threads 1 -nostdin -hide_banner -nostats -loglevel error -fflags +genpts+discardcorrupt+igndts -i /tmp/whatever.mkv -map 0:1 -map 0:0 -muxdelay 0 -muxpreload 0 -movflags +faststart -flags cgop -sc_threshold 0 -c:v copy -c:a copy -f mpegts -mpegts_flags +initial_discontinuity pipe:1"); + } + private static string PrintCommand( Option videoInputFile, Option audioInputFile, diff --git a/ErsatzTV.FFmpeg/PipelineBuilder.cs b/ErsatzTV.FFmpeg/PipelineBuilder.cs index 75a7a171d..d3f0bf6e4 100644 --- a/ErsatzTV.FFmpeg/PipelineBuilder.cs +++ b/ErsatzTV.FFmpeg/PipelineBuilder.cs @@ -607,6 +607,11 @@ public class PipelineBuilder private static bool IsDesiredVideoState(FrameState currentState, FrameState desiredState) { + if (desiredState.VideoFormat == VideoFormat.Copy) + { + return true; + } + return currentState.VideoFormat == desiredState.VideoFormat && currentState.PixelFormat.Match(pf => pf.Name, () => string.Empty) == desiredState.PixelFormat.Match(pf => pf.Name, string.Empty) &&