namespace ytLive.Services.Encoder; /// /// Builds the FFmpeg command line for a live RTMP push (TASK 4 ship step 3): /// raw BGRA frames via stdin (paced -re), silent placeholder audio via lavfi /// anullsrc (the WASAPI step replaces this input), H.264 + AAC encoding, FLV /// muxing to the ingestion URL. Pure — the encoder just starts /// ffmpeg.exe [Build(...)]. /// public static class FfmpegArgs { public static IReadOnlyList Build(EncoderOptions options, string videoEncoder) { var gop = options.GopSize; return [ "-hide_banner", "-loglevel", "info", "-stats", "-stats_period", "0.5", "-re", "-f", "rawvideo", "-pix_fmt", "bgra", "-video_size", $"{options.Width}x{options.Height}", "-framerate", options.Fps.ToString(), "-i", "pipe:0", "-f", "lavfi", "-i", $"anullsrc=channel_layout=stereo:sample_rate={options.AudioSampleRate}", "-c:v", videoEncoder, "-b:v", $"{options.BitrateKbps}k", "-maxrate", $"{options.BitrateKbps}k", "-bufsize", $"{options.BitrateKbps * 2}k", "-g", gop.ToString(), "-keyint_min", gop.ToString(), "-sc_threshold", "0", "-bf", "0", "-pix_fmt", "yuv420p", "-c:a", "aac", "-b:a", "128k", "-ar", options.AudioSampleRate.ToString(), "-ac", options.AudioChannels.ToString(), "-f", "flv", options.RtmpUrl, ]; } }