/// <summary> /// Creates a new instance of <see cref="FFmpegWriter"/>. /// </summary> public FFmpegWriter(FFmpegVideoWriterArgs Args) { if (!FFmpegService.FFmpegExists) { throw new FFmpegNotFoundException(); } var nv12 = Args.ImageProvider.DummyFrame is INV12Frame; var settings = ServiceProvider.Get <FFmpegSettings>(); var w = Args.ImageProvider.Width; var h = Args.ImageProvider.Height; _videoBuffer = new byte[(int)(w * h * (nv12 ? 1.5 : 4))]; Console.WriteLine($"Video Buffer Allocated: {_videoBuffer.Length}"); var videoPipeName = GetPipeName(); var argsBuilder = new FFmpegArgsBuilder(); argsBuilder.AddInputPipe(videoPipeName) .AddArg("thread_queue_size", 512) .AddArg("framerate", Args.FrameRate) .SetFormat("rawvideo") .AddArg("pix_fmt", nv12 ? "nv12" : "rgb32") .SetVideoSize(w, h); var output = argsBuilder.AddOutputFile(Args.FileName) .SetFrameRate(Args.FrameRate); Args.VideoCodec.Apply(settings, Args, output); if (settings.Resize) { var width = settings.ResizeWidth; var height = settings.ResizeHeight; if (width % 2 == 1) { ++width; } if (height % 2 == 1) { ++height; } output.AddArg("vf", $"scale={width}:{height}"); } if (Args.AudioProvider != null) { var audioPipeName = GetPipeName(); argsBuilder.AddInputPipe(audioPipeName) .AddArg("thread_queue_size", 512) .SetFormat("s16le") .SetAudioCodec("pcm_s16le") .SetAudioFrequency(Args.Frequency) .SetAudioChannels(Args.Channels); Args.VideoCodec.AudioArgsProvider(Args.AudioQuality, output); // UpdatePeriod * Frequency * (Bytes per Second) * Channels * 2 var audioBufferSize = (int)((1000.0 / Args.FrameRate) * 44.1 * 2 * 2 * 2); _audioPipe = new NamedPipeServerStream(audioPipeName, PipeDirection.Out, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous, 0, audioBufferSize); } _ffmpegIn = new NamedPipeServerStream(videoPipeName, PipeDirection.Out, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous, 0, _videoBuffer.Length); _ffmpegProcess = FFmpegService.StartFFmpeg(argsBuilder.GetArgs(), Args.FileName, out _); }
/// <summary> /// Creates a new instance of <see cref="FFmpegWriter"/>. /// </summary> public FFmpegWriter(FFmpegVideoWriterArgs Args) { var settings = ServiceProvider.Get <FFmpegSettings>(); _videoBuffer = new byte[Args.ImageProvider.Width * Args.ImageProvider.Height * 4]; Console.WriteLine($"Video Buffer Allocated: {_videoBuffer.Length}"); var videoPipeName = GetPipeName(); var argsBuilder = new FFmpegArgsBuilder(); argsBuilder.AddInputPipe(videoPipeName) .AddArg("-thread_queue_size 512") .AddArg($"-framerate {Args.FrameRate}") .SetFormat("rawvideo") .AddArg("-pix_fmt rgb32") .SetVideoSize(Args.ImageProvider.Width, Args.ImageProvider.Height); var output = argsBuilder.AddOutputFile(Args.FileName) .AddArg(Args.VideoArgsProvider(Args.VideoQuality)) .SetFrameRate(Args.FrameRate); if (settings.Resize) { var width = settings.ResizeWidth; var height = settings.ResizeHeight; if (width % 2 == 1) { ++width; } if (height % 2 == 1) { ++height; } output.AddArg($"-vf scale={width}:{height}"); } if (Args.AudioProvider != null) { var audioPipeName = GetPipeName(); argsBuilder.AddInputPipe(audioPipeName) .AddArg("-thread_queue_size 512") .SetFormat("s16le") .SetAudioCodec("pcm_s16le") .SetAudioFrequency(Args.Frequency) .SetAudioChannels(Args.Channels); output.AddArg(Args.AudioArgsProvider(Args.AudioQuality)); // UpdatePeriod * Frequency * (Bytes per Second) * Channels * 2 var audioBufferSize = (int)((1000.0 / Args.FrameRate) * 44.1 * 2 * 2 * 2); _audioPipe = new NamedPipeServerStream(audioPipeName, PipeDirection.Out, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous, 0, audioBufferSize); } _ffmpegIn = new NamedPipeServerStream(videoPipeName, PipeDirection.Out, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous, 0, _videoBuffer.Length); output.AddArg(Args.OutputArgs); _ffmpegProcess = FFmpegService.StartFFmpeg(argsBuilder.GetArgs(), Args.FileName); }
/// <summary> /// Creates a new instance of <see cref="FFmpegWriter"/>. /// </summary> public FFmpegWriter(FFmpegVideoWriterArgs Args) { var settings = ServiceProvider.Get <FFmpegSettings>(); VideoInputArgs = Args; var crf = (51 * (100 - VideoInputArgs.VideoQuality)) / 99; outputFolderName = Args.FileName.Substring(0, VideoInputArgs.FileName.Length - 4); additionalVideoInputArgsPre = " -r " + Args.FrameRate + " -start_number 1 -i \""; additionalVideoInputArgsPost = "_%d.png\" -s " + Args.ImageProvider.Width + "*" + Args.ImageProvider.Height + " -vcodec libx264 -crf " + crf + " -pix_fmt " + settings.X264.PixelFormat + " -preset " + settings.X264.Preset; if (settings.Resize) { additionalVideoInputArgsPost += " -vf scale=" + settings.ResizeWidth + ":" + settings.ResizeHeight; } if (File.Exists(capturePropertiesPath)) { foreach (string row in File.ReadAllLines(capturePropertiesPath)) { string[] rowValues = row.Split('='); if (!row.StartsWith("#") && rowValues.Length == 2) { if (rowValues[0].Trim() == "PIPE_TIMEOUT_IN_SECONDS") { try { waitTimeForPipeConnection = int.Parse(rowValues[1].Trim()) * 1000; if (waitTimeForPipeConnection != 30000) { WriteLog("Wait Timeout: " + waitTimeForPipeConnection); } } catch (Exception) { } } } } } if (settings.RawBackup) { framesToBeWritten = new Queue <byte[]>(); (new Thread(ThreadForAppendFrames)).Start(); } _videoBuffer = new byte[Args.ImageProvider.Width * Args.ImageProvider.Height * 4]; Console.WriteLine($"Video Buffer Allocated: {_videoBuffer.Length}"); var videoPipeName = GetPipeName(); var argsBuilder = new FFmpegArgsBuilder(); argsBuilder.AddInputPipe(videoPipeName) .AddArg("-thread_queue_size 512") .AddArg($"-framerate {Args.FrameRate}") .SetFormat("rawvideo") .AddArg("-pix_fmt rgb32") .SetVideoSize(Args.ImageProvider.Width, Args.ImageProvider.Height); var output = argsBuilder.AddOutputFile(Args.FileName) .AddArg(Args.VideoArgsProvider(Args.VideoQuality)) .SetFrameRate(Args.FrameRate); if (settings.Resize) { var width = settings.ResizeWidth; var height = settings.ResizeHeight; if (width % 2 == 1) { ++width; } if (height % 2 == 1) { ++height; } output.AddArg($"-vf scale={width}:{height}"); } if (Args.AudioProvider != null) { var audioPipeName = GetPipeName(); argsBuilder.AddInputPipe(audioPipeName) .AddArg("-thread_queue_size 512") .SetFormat("s16le") .SetAudioCodec("pcm_s16le") .SetAudioFrequency(Args.Frequency) .SetAudioChannels(Args.Channels); output.AddArg(Args.AudioArgsProvider(Args.AudioQuality)); // UpdatePeriod * Frequency * (Bytes per Second) * Channels * 2 var audioBufferSize = (int)((1000.0 / Args.FrameRate) * 44.1 * 2 * 2 * 2); _audioPipe = new NamedPipeServerStream(audioPipeName, PipeDirection.Out, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous, 0, audioBufferSize); } _ffmpegIn = new NamedPipeServerStream(videoPipeName, PipeDirection.Out, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous, 0, _videoBuffer.Length); output.AddArg(Args.OutputArgs); _ffmpegProcess = FFmpegService.StartFFmpeg(argsBuilder.GetArgs(), Args.FileName); }