using System.Diagnostics; namespace ReviewProxy.Lib; public class StreamEncoder : IEncoder { private Stream stream; private string workDirectory; private string outputFilePath; public StreamEncoder(Stream inputStream, string workDirectory, string outputFilePath) { this.stream = inputStream; this.workDirectory = workDirectory; this.outputFilePath = outputFilePath; this.Init(); } public async ValueTask EncodeAsync() { using (var proc = this.CreateEncoder()) { if (proc is null) { throw new FileNotFoundException("ffmpeg could't execute."); } Console.WriteLine($"CopyToAsync"); await this.stream.CopyToAsync(proc.StandardInput.BaseStream).ConfigureAwait(false); Console.WriteLine($"Close"); proc.StandardInput.BaseStream.Close(); await proc.WaitForExitAsync().ConfigureAwait(false); } this.BundleToZip(); } private void BundleToZip() { using (var archive = new ZipArchiver(this.outputFilePath, this.workDirectory)) { archive.Compress(); } } private void Init() { if (!Directory.Exists(workDirectory)) { Directory.CreateDirectory(workDirectory); } } private Process? CreateEncoder() { string tsFilePath = Path.Combine(workDirectory, "a%03d.ts"); string plFilePath = Path.Combine(workDirectory, "playlist.m3u8"); var args = $"-i pipe:0 -c:v libx264 -vf scale=-2:720 -movflags faststart -b:v 1000K -r 24 -c:a aac -b:a 64k -y -pix_fmt yuv420p -crf 23 -f segment -segment_format mpegts -segment_time 5 -segment_list \"{plFilePath}\" \"{tsFilePath}\""; var startInfo = new ProcessStartInfo() { FileName = "ffmpeg", Arguments = args, RedirectStandardInput = true, }; return Process.Start(startInfo); } public void Dispose() { if (Directory.Exists(workDirectory)) { Directory.Delete(workDirectory, true); } if (File.Exists(outputFilePath)) { File.Delete(outputFilePath); } } }