Пример #1
0
 public bool MediaConvertPCM_S16E(string input, string output, int sampleRate)
 {
     try
     {
         if (!FFmpegService.FFmpegExists)
         {
             throw new FFmpegNotFoundException();
         }
         FFmpegArgsBuilder fFmpegArgsBuilder = new FFmpegArgsBuilder();
         fFmpegArgsBuilder.GlobalOptionArgs
         .OverwriteOutput()
         .SetThreadQueueSize(512);
         fFmpegArgsBuilder.SetInputFile(input);
         fFmpegArgsBuilder.SetOutputFile(output)
         //.SetAudioFormat(AudioFormat.s16le)
         .SetAudioCodec(FFmpegAudioCodec.pcm_s16le)
         .SetAudioFrequency(sampleRate)
         .SetAudioChannels(2)
         ;
         FFmpegService.StartFFmpeg(fFmpegArgsBuilder.Args);
         return(true);
     }
     catch
     {
         return(false);
     }
 }
Пример #2
0
 public Stream ReadVideoFrame(TimeSpan seek, Size?size)
 {
     this.Dispose();
     try
     {
         FFmpegArgsBuilder fFmpegArgsBuilder = new FFmpegArgsBuilder();
         fFmpegArgsBuilder.GlobalOptionArgs
         .SetThreadQueueSize(512)
         ;
         fFmpegArgsBuilder.SetInputFile(this.filePath)
         .SeekAccurate()
         .ReadByNativeFrame()
         .SetSeek(seek)
         ;
         var outputOptionArgs = fFmpegArgsBuilder.SetOutputImagePipe(videoPipeName)
                                .SetPixFormat(Formats.FFmpegPixFormat.rgb24)
                                .SetOutputVideoFrame(1)
                                .SetVideoFormat(FFmpegVideoFormat.image2)
                                .SetFramerate(this.FPS)
         ;
         if (size != null)
         {
             outputOptionArgs
             .SetVideoSize(size.Value);
         }
         this.ffmpegProcess = FFmpegService.StartFFmpegStandardOutput(fFmpegArgsBuilder.Args);
         return(this.ffmpegProcess.StandardOutput.BaseStream);
     }
     catch
     {
     }
     return(null);
 }
Пример #3
0
 public bool MediaCut(string input, string output, TimeSpan start, TimeSpan?end = null)
 {
     try
     {
         if (!FFmpegService.FFmpegExists)
         {
             throw new FFmpegNotFoundException();
         }
         FFmpegArgsBuilder fFmpegArgsBuilder = new FFmpegArgsBuilder();
         fFmpegArgsBuilder.GlobalOptionArgs
         .OverwriteOutput()
         .SetThreadQueueSize(512);
         var inputOptionArgs = fFmpegArgsBuilder.SetInputFile(input)
                               .SetSeek(start);
         var outputOptionArgs = fFmpegArgsBuilder.SetOutputFile(input)
         ;
         if (end != null)
         {
             outputOptionArgs
             .SetSeekEnd(end.Value)
             .SetAudioCodec(Codecs.FFmpegAudioCodec.copy)
             .SetVideoCodec(Codecs.FFmpegVideoCodec.copy);
         }
         FFmpegService.StartFFmpeg(fFmpegArgsBuilder.Args);
         return(true);
     }
     catch
     {
         return(false);
     }
 }
        /// <inheritdoc />
        public void Dispose()
        {
            _ffMpegWriter.Dispose();

            var argsBuilder = new FFmpegArgsBuilder();

            argsBuilder.AddInputFile(_tempFileName);

            var output = argsBuilder.AddOutputFile(_args.FileName)
                         .AddArg(_args.VideoArgsProvider(_args.VideoQuality))
                         .SetFrameRate(_args.FrameRate);

            if (_args.AudioProvider != null)
            {
                output.AddArg(_args.AudioArgsProvider(_args.AudioQuality));
            }

            output.AddArg(_args.OutputArgs);

            var process = FFmpegService.StartFFmpeg(argsBuilder.GetArgs(), _args.FileName);

            process.WaitForExit();

            File.Delete(_tempFileName);
        }
Пример #5
0
        public Task GenerateSubTitles(
            string filePath,
            string subtitleFinalPath,
            double seconds,
            int index,
            double subsDelayInSeconds,
            CancellationToken token)
        {
            try
            {
                _fileService.DeleteFilesInDirectory(Path.GetDirectoryName(subtitleFinalPath));
                var builder = new FFmpegArgsBuilder();
                builder.AddInputFile(filePath).BeQuiet().SetAutoConfirmChanges().TrySetSubTitleEncoding(FileFormatConstants.AllowedSubtitleFormats);
                builder.AddOutputFile(subtitleFinalPath)
                .Seek(Math.Floor(seconds))
                .SetMap(index)
                .SetDelayInSeconds(subsDelayInSeconds)
                .SetFormat("webvtt");

                string cmd = builder.GetArgs();
                _logger.LogInformation($"{nameof(GenerateSubTitles)}: Generating subtitles for file = {filePath}. CMD = {cmd}");
                return(Task.Run(() =>
                {
                    var process = new Process
                    {
                        EnableRaisingEvents = true,
                        StartInfo = new ProcessStartInfo
                        {
                            FileName = _fileService.GetFFmpegPath(),
                            UseShellExecute = false,
                            CreateNoWindow = true,
                            WindowStyle = ProcessWindowStyle.Hidden
                        }
                    };
                    process.StartInfo.Arguments = cmd;
                    process.Start();
                    process.WaitForExit();

                    if (process.ExitCode > 0)
                    {
                        _logger.LogError($"{nameof(GenerateSubTitles)}: Could not generate subs for file = {filePath}.");
                    }
                    else if (process.ExitCode < 0)
                    {
                        _logger.LogInformation($"{nameof(GenerateSubTitles)}: Process was killed for file = {filePath}");
                    }
                    else
                    {
                        _logger.LogInformation($"{nameof(GenerateSubTitles)}: Subs where generated for file = {filePath}");
                    }
                }, token));
            }
            catch (Exception e)
            {
                _logger.LogError(e, $"{nameof(GenerateSubTitles)}: Unknown error");
                _telemetryService.TrackError(e);
                return(Task.CompletedTask);
            }
        }
Пример #6
0
        public string GetThumbnail(string mrl)
        {
            if (!_fileService.IsLocalFile(mrl))
            {
                _logger.LogWarning($"{nameof(GetThumbnail)}: Cant get thumbnail for file = {mrl}. Its not a local file");
                return(null);
            }

            var filename      = Path.GetFileName(mrl);
            var thumbnailPath = _fileService.GetFirstThumbnailFilePath(filename);

            if (File.Exists(thumbnailPath))
            {
                return(thumbnailPath);
            }

            var builder = new FFmpegArgsBuilder();

            builder.AddInputFile(mrl).BeQuiet().SetAutoConfirmChanges().DisableAudio();
            var outputArgs = builder.AddOutputFile(thumbnailPath);

            if (!_fileService.IsMusicFile(mrl))
            {
                outputArgs.WithVideoFilter(@"select=gt(scene\,0.4)")
                .SetVideoFrames(1)
                .WithVideoFilter("fps=1/60");
            }
            try
            {
                string cmd = builder.GetArgs();
                _logger.LogInformation($"{nameof(GetThumbnail)}: Generating first thumbnail for file = {mrl}. Cmd = {cmd}");
                _checkGenerateThumbnailProcess = true;
                _generateThumbnailProcess.StartInfo.Arguments = cmd;
                _generateThumbnailProcess.Start();
                _generateThumbnailProcess.WaitForExit();
                if (_generateThumbnailProcess.ExitCode != 0)
                {
                    _logger.LogWarning($"{nameof(GetThumbnail)}: Couldn't retrieve the first thumbnail for file = {mrl}.");
                    return(null);
                }
                _logger.LogInformation($"{nameof(GetThumbnail)}: First thumbnail was successfully generated for file = {mrl}");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"{nameof(GenerateThumbnails)}: Unknown error occurred");
                _telemetryService.TrackError(ex);
            }
            finally
            {
                _checkGenerateThumbnailProcess = false;
            }
            return(thumbnailPath);
        }
Пример #7
0
        /// <summary>
        /// 这个算法还没有完成 用来获取Duration还是可以的
        /// </summary>
        /// <param name="filePath"></param>
        public void Open(string filePath)
        {
            FFmpegArgsBuilder fFmpegArgsBuilder = new FFmpegArgsBuilder();

            fFmpegArgsBuilder.SetInputFile(filePath);
            StreamReader streamReader = FFmpegService.StartFFmpegErrorStream(fFmpegArgsBuilder.Args);
            string       line         = string.Empty;

            line = streamReader.ReadToEnd();
            string regexDuration = "Duration: (.*?), start: (.*?), bitrate: (\\d*) kb\\/s";
            string regexVideo    = "Video: (.*?), (.*?), (\\d*x\\d*).*?, (.*?) kb/s, (.*?)[,\\s]";
            string regexAudio    = "Audio: (.*?), (.*?) Hz, (.*?), (.*?), (.*?) kb/s";
            Regex  regex;
            Match  match;

            regex = new Regex(regexDuration);
            match = regex.Match(line);
            if (match.Groups.Count == 4)
            {
                if (TimeSpan.TryParse(match.Groups[1].Value, out TimeSpan timeSpan))
                {
                    this.Duration = timeSpan;
                }
                this.Bitrate = regex.Match(line).Groups[3].Value;
            }
            regex = new Regex(regexVideo);
            match = regex.Match(line);
            if (match.Groups.Count == 6)
            {
                this.VideoFormat  = regex.Match(line).Groups[1].Value;
                this.PixFormat    = regex.Match(line).Groups[2].Value;
                this.Width        = int.Parse(regex.Match(line).Groups[3].Value.Split('x')[0]);
                this.Height       = int.Parse(regex.Match(line).Groups[3].Value.Split('x')[1]);
                this.VideoBitrate = regex.Match(line).Groups[4].Value;
                if (double.TryParse(regex.Match(line).Groups[5].Value, out double framerate))
                {
                    this.Framerate = framerate;
                }
            }
            regex = new Regex(regexAudio);
            match = regex.Match(line);
            if (match.Groups.Count == 6)
            {
                this.AudioFormat = regex.Match(line).Groups[1].Value;
                if (int.TryParse(regex.Match(line).Groups[2].Value, out int audioFrequency))
                {
                    this.AudioFrequency = audioFrequency;
                }
                this.AudioBitrate = regex.Match(line).Groups[5].Value;
            }
        }
Пример #8
0
        private void GenerateGif(string paletteFile)
        {
            var argsBuilder = new FFmpegArgsBuilder();

            argsBuilder.AddInputFile(_tempFileName);

            argsBuilder.AddInputFile(paletteFile);

            argsBuilder.AddOutputFile(_args.FileName)
            .AddArg("-lavfi paletteuse")
            .SetFrameRate(_args.FrameRate);

            var process = FFmpegService.StartFFmpeg(argsBuilder.GetArgs(), _args.FileName);

            process.WaitForExit();
        }
Пример #9
0
 public bool Open(string filePath)
 {
     try
     {
         FFmpegArgsBuilder fFmpegArgsBuilder = new FFmpegArgsBuilder();
         fFmpegArgsBuilder.GlobalOptionArgs
         .OverwriteOutput()
         .SetThreadQueueSize(512);
         fFmpegArgsBuilder.SetInputPipe(videoPipeName)
         .SetFramerate(this.VideoWriterArgs.FrameRate)
         .SetVideoFormat(FFmpegVideoFormat.rawvideo)
         .SetPixFormat(FFmpegPixFormat.rgb32)
         .SetVideoSize(this.VideoWriterArgs.Width, this.VideoWriterArgs.Height)
         ;
         var outputOptionArgs = fFmpegArgsBuilder.SetOutputFile(filePath)
                                .SetFramerate(this.VideoWriterArgs.FrameRate)
                                .SetFileLength(CommonWriterArgs.FileLength ?? 0, () => CommonWriterArgs.FileLength != null)
                                .SetVideoSize((int)(this.VideoWriterArgs.Width * this.VideoWriterArgs.ScaleWidth), (int)(this.VideoWriterArgs.Height * this.VideoWriterArgs.ScaleHeight))
         ;
         ((VideoCodecBase)this.VideoWriterArgs.VideoCodec).Apply(this.VideoWriterArgs, outputOptionArgs);
         var videoBufferSize = this.VideoWriterArgs.Width * this.VideoWriterArgs.Height * 4;
         this.videoPipeWrite = new PipeServerWrite(videoPipeName, videoBufferSize);
         if (this.Audioable)
         {
             fFmpegArgsBuilder.SetInputPipe(audioPipeName)
             .SetAudioFormat(FFmpegAudioFormat.s16le)
             .SetAudioCodec(FFmpegAudioCodec.pcm_s16le)
             .SetAudioFrequency(16000)
             .SetAudioChannels(2);
             outputOptionArgs
             .SetAudioFrequency(this.AudioWriterArgs.AudioFrequency)
             .SetAudioChannels(this.AudioWriterArgs.AudioChannels)
             ;
             ((AudioCodecBase)this.AudioWriterArgs.AudioCodec).Apply(this.AudioWriterArgs, outputOptionArgs);
             var audioBufferSize = (int)((1000.0 / this.VideoWriterArgs.FrameRate) * (44100 / 100.0) * 2 * 2 * 2);
             this.audioPipeWrite = new PipeServerWrite(audioPipeName, audioBufferSize);
         }
         this.ffmpegProcess = FFmpegService.StartFFmpeg(fFmpegArgsBuilder.Args);
         return(true);
     }
     catch (Exception ex)
     {
         return(false);
     }
 }
Пример #10
0
        public FFmpegAudioWriter(string fileName, int audioQuality, FFmpegAudioArgsProvider audioArgsProvider, int frequency = 44100, int channels = 2)
        {
            var argsBuilder = new FFmpegArgsBuilder();

            argsBuilder.AddStdIn()
            .SetFormat("s16le")
            .SetAudioCodec("pcm_s16le")
            .SetAudioFrequency(frequency)
            .SetAudioChannels(channels)
            .DisableVideo();

            argsBuilder.AddOutputFile(fileName)
            .AddArg(audioArgsProvider(audioQuality));

            _ffmpegProcess = FFmpegService.StartFFmpeg(argsBuilder.GetArgs(), fileName);

            _ffmpegIn = _ffmpegProcess.StandardInput.BaseStream;
        }
Пример #11
0
        private string GenerateCmdForThumbnails(string mrl, string thumbnailPath, bool useHwAccel)
        {
            var builder    = new FFmpegArgsBuilder();
            var inputArgs  = builder.AddInputFile(mrl).SetAutoConfirmChanges().DisableAudio();
            var outputArgs = builder.AddOutputFile(thumbnailPath);

            if (useHwAccel)
            {
                //This might fail sometimes because the device does not support qsv or because the main display is not connected to the Intel GPU
                inputArgs.SetHwAccel(HwAccelDeviceType.Intel).SetVideoCodec(HwAccelDeviceType.Intel);
                outputArgs.SetVideoCodec("mjpeg_qsv").SetFilters($"fps=1/5,scale_qsv={ThumbnailScale}");
            }
            else
            {
                outputArgs.SetFilters($"fps=1/5,scale={ThumbnailScale}");
            }

            return(builder.GetArgs());
        }
Пример #12
0
        private string BuildAudioTranscodeCmd(string filePath, double seconds, int audioStreamIndex, bool audioNeedsTranscode)
        {
            var builder = new FFmpegArgsBuilder();

            builder.AddInputFile(filePath).BeQuiet().SetAutoConfirmChanges().Seek(seconds);
            var outputArgs = builder.AddOutputPipe().SetMap(audioStreamIndex).SetPreset("ultrafast");

            if (audioNeedsTranscode)
            {
                outputArgs.SetAudioCodec("aac").SetAudioBitrate(128);
            }
            else
            {
                outputArgs.SetAudioCodec("copy");
            }
            //To generate an aac output you need to set adts
            outputArgs.SetAudioChannels(2).SetFormat("adts");

            return(builder.GetArgs());
        }
Пример #13
0
        private string GeneratePalette()
        {
            var argsBuilder = new FFmpegArgsBuilder();

            argsBuilder.AddInputFile(_tempFileName);

            var tempFile    = Path.GetTempFileName();
            var paletteFile = Path.ChangeExtension(tempFile, "png");

            File.Move(tempFile, paletteFile);

            argsBuilder.AddOutputFile(paletteFile)
            .AddArg("-vf palettegen")
            .SetFrameRate(_args.FrameRate)
            .AddArg("-y");

            var process = FFmpegService.StartFFmpeg(argsBuilder.GetArgs(), paletteFile);

            process.WaitForExit();

            return(paletteFile);
        }
Пример #14
0
 public bool MediaConvertAuto(string input, string output)
 {
     try
     {
         if (!FFmpegService.FFmpegExists)
         {
             throw new FFmpegNotFoundException();
         }
         FFmpegArgsBuilder fFmpegArgsBuilder = new FFmpegArgsBuilder();
         fFmpegArgsBuilder.GlobalOptionArgs
         .OverwriteOutput()
         .SetThreadQueueSize(512);
         fFmpegArgsBuilder.SetInputFile(input);
         fFmpegArgsBuilder.SetOutputFile(output);
         FFmpegService.StartFFmpeg(fFmpegArgsBuilder.Args);
         return(true);
     }
     catch
     {
         return(false);
     }
 }
Пример #15
0
        private static string BuildVideoTranscodeCmd(
            TranscodeVideoFile options,
            double?from = null,
            double?to   = null)
        {
            var builder   = new FFmpegArgsBuilder();
            var inputArgs = builder.AddInputFile(options.FilePath)
                            .BeQuiet()
                            .SetVSync(0)
                            .SetAutoConfirmChanges()
                            .SetHwAccel(options.HwAccelDeviceType)
                            .SetVideoCodec(options.HwAccelDeviceType);
            var outputArgs = builder.AddOutputPipe()
                             .SetPreset(options.HwAccelDeviceType)
                             .AddArg("map_metadata", -1)
                             .AddArg("map_chapters", -1); //for some reason the chromecast doesnt like chapters o.o

            if (options.VideoStreamIndex >= 0)
            {
                outputArgs.SetMap(options.VideoStreamIndex);
            }

            if (options.AudioStreamIndex >= 0)
            {
                outputArgs.SetMap(options.AudioStreamIndex);
            }

            if (options.Seconds > 0 && !from.HasValue && !to.HasValue)
            {
                inputArgs.Seek(options.Seconds);
            }

            if (from.HasValue)
            {
                outputArgs.Seek(from.Value);
            }

            if (to.HasValue)
            {
                outputArgs.To(to.Value);
            }

            if (options.ForceVideoTranscode)
            {
                outputArgs.SetVideoCodec(options.HwAccelDeviceType).SetProfileVideo("main").SetLevel(4).SetPixelFormat(options.HwAccelDeviceType);
                if (options.VideoScaleType != VideoScaleType.Original)
                {
                    int videoScale = (int)options.VideoScaleType;
                    switch (options.HwAccelDeviceType)
                    {
                    case HwAccelDeviceType.Intel:
                        outputArgs.AddArg("global_quality", 25)
                        .AddArg("look_ahead", 1)
                        .SetFilters($"scale_qsv=trunc(oh*a/2)*2:{videoScale}");
                        break;

                    case HwAccelDeviceType.Nvidia:
                        string scale = options.VideoScaleType == VideoScaleType.Hd ? "1280x720" : "1920x1080";
                        if (scale != options.VideoWidthAndHeight && !string.IsNullOrWhiteSpace(options.VideoWidthAndHeight))
                        {
                            inputArgs.AddArg("resize", scale);
                        }
                        break;

                    case HwAccelDeviceType.None:
                        outputArgs.SetFilters($"scale=trunc(oh*a/2)*2:{videoScale}");
                        break;

                    case HwAccelDeviceType.AMD:
                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }
                }
            }
            else
            {
                outputArgs.CopyVideoCodec();
            }

            if (options.ForceAudioTranscode)
            {
                outputArgs.SetAudioCodec("aac").SetAudioBitrate(128).SetAudioChannels(2);
            }
            else
            {
                outputArgs.CopyAudioCodec();
            }

            outputArgs.SetMovFlagToTheStart().SetFormat("mp4");

            return(builder.GetArgs());
        }
Пример #16
0
        public IEnumerable <VideoFrameArgs> ReadVideoFrames(TimeSpan?seek = null, TimeSpan?seekEnd = null, Size?size = null, bool readByNativeFrame = true, CancellationToken?cancellationToken = null)
        {
            this.Dispose();
            TimeSpan          startSeek         = seek ?? TimeSpan.FromSeconds(0);
            FFmpegArgsBuilder fFmpegArgsBuilder = new FFmpegArgsBuilder();

            fFmpegArgsBuilder.GlobalOptionArgs
            .SetThreadQueueSize(512)
            .SetNoStandardInput()
            ;
            var inputOptionArgs = fFmpegArgsBuilder.SetInputFile(this.filePath)
                                  .SeekAccurate()
                                  .SetSeek(startSeek)
                                  .ReadByNativeFrame(() => readByNativeFrame)
            ;
            var outputOptionArgs = fFmpegArgsBuilder.SetOutputImagePipe(videoPipeName)
                                   .SetVideoFormat(FFmpegVideoFormat.image2pipe)
                                   .SetVideoCodec(FFmpegVideoCodec.rawvideo)
                                   .SetPixFormat(Formats.FFmpegPixFormat.rgb24)
                                   .SetFramerate(this.FPS)
                                   .SetSeekEnd(seekEnd ?? TimeSpan.MinValue, () => seekEnd != null)
                                   .SetVideoSize(this.GetSize(size))
            ;

            this.ffmpegProcess = FFmpegService.StartFFmpegStandardOutput(fFmpegArgsBuilder.Args);
            cancellationToken?.Register(() =>
            {
                this.Dispose();
            });
            int  frameIndex = (int)(startSeek.TotalMilliseconds / (1000.0 / this.FPS));
            Size bitmapSize = this.GetSize(size);

            byte[] frameDataBuffer = new byte[bitmapSize.Width * bitmapSize.Height * 3];
            byte[] buffer          = new byte[32768]; //ffmpeg的缓冲区大小被限定在32k 32768 似乎没有办法修改?
            int    read;
            int    readed = 0;

            while ((read = this.ffmpegProcess.StandardOutput.BaseStream.Read(buffer, 0, Math.Min(buffer.Length, frameDataBuffer.Length - readed))) > 0)
            {
                if (cancellationToken?.IsCancellationRequested ?? false)
                {
                    this.Dispose();
                    yield break;
                }
                Array.Copy(buffer, 0, frameDataBuffer, readed, read);
                readed += read;
                if (readed == frameDataBuffer.Length)
                {
                    //对每一个像素的颜色进行转化
                    for (int i = 0; i < frameDataBuffer.Length; i += 3)
                    {
                        byte temp = frameDataBuffer[i + 2];
                        frameDataBuffer[i + 2] = frameDataBuffer[i];
                        frameDataBuffer[i]     = temp;
                    }
                    yield return(new VideoFrameArgs(frameIndex++, frameDataBuffer));

                    readed = 0;
                }
            }
        }
Пример #17
0
        /// <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);
        }