예제 #1
0
        /// <summary>
        /// Opens output audio file for writing. This will delete any existing file. Call this before writing samples.
        /// </summary>
        /// <param name="showFFmpegOutput">Show output to terminal. Error stream will not be redirected if this is set to true.</param>
        public void OpenWrite(bool showFFmpegOutput = false)
        {
            if (OpenedForWriting)
            {
                throw new InvalidOperationException("File was already opened for writing!");
            }

            var cmd = $"-f s{BitDepth}le -channels {Channels} -sample_rate {SampleRate} -i - " +
                      $"-c:a {EncoderOptions.EncoderName} {EncoderOptions.EncoderArguments} -f {EncoderOptions.Format}";

            if (UseFilename)
            {
                if (File.Exists(Filename))
                {
                    File.Delete(Filename);
                }

                InputDataStream = FFmpegWrapper.OpenInput(ffmpeg, $"{cmd} \"{Filename}\"", out ffmpegp, showFFmpegOutput);
            }
            else
            {
                csc = new CancellationTokenSource();

                // using stream
                (InputDataStream, OutputDataStream) = FFmpegWrapper.Open(ffmpeg, $"{cmd} -", out ffmpegp, showFFmpegOutput);
                _ = OutputDataStream.CopyToAsync(DestinationStream, csc.Token);
            }

            OpenedForWriting = true;
        }
예제 #2
0
        /// <summary>
        /// Open player for writing samples for playing.
        /// </summary>
        /// <param name="sampleRate">Sample rate</param>
        /// <param name="channels">Number of channels</param>
        /// <param name="bitDepth">Bits per sample (16, 24, 32)</param>
        /// <param name="showWindow">Show player graphical window</param>
        /// <param name="showFFplayOutput">Show FFplay output for debugging purposes.</param>
        public void OpenWrite(int sampleRate, int channels, int bitDepth = 16, bool showWindow = false, bool showFFplayOutput = false)
        {
            if (bitDepth != 16 && bitDepth != 24 && bitDepth != 32)
            {
                throw new InvalidOperationException("Acceptable bit depths are 16, 24 and 32");
            }
            if (OpenedForWriting)
            {
                throw new InvalidOperationException("Player is already opened for writing samples!");
            }
            try
            {
                if (ffplayp != null && !ffplayp.HasExited)
                {
                    ffplayp.Kill();
                }
            }
            catch { }

            InputDataStream = FFmpegWrapper.OpenInput(ffplay, $"-f s{bitDepth}le -channels {channels} -sample_rate {sampleRate} -i -"
                                                      + (showWindow ? "" : " -nodisp"),
                                                      out ffplayp, showFFplayOutput);

            OpenedForWriting = true;
        }
예제 #3
0
        /// <summary>
        /// Prepares for writing.
        /// </summary>
        /// <param name="showFFmpegOutput">Show output to terminal. Error stream will not be redirected if this is set to true.</param>
        public void OpenWrite(bool showFFmpegOutput = false)
        {
            if (OpenedForWriting)
            {
                throw new InvalidOperationException("File was already opened for writing!");
            }

            var cmd = $"-f rawvideo -video_size {Width}:{Height} -r {Framerate} -pixel_format rgb24 -i - " +
                      $"-c:v {EncoderOptions.EncoderName} {EncoderOptions.EncoderArguments} -f {EncoderOptions.Format}";

            if (UseFilename)
            {
                if (File.Exists(Filename))
                {
                    File.Delete(Filename);
                }

                InputDataStream = FFmpegWrapper.OpenInput(ffmpeg, $"{cmd} \"{Filename}\"", out ffmpegp, showFFmpegOutput);
            }
            else
            {
                csc = new CancellationTokenSource();

                // using stream
                (InputDataStream, OutputDataStream) = FFmpegWrapper.Open(ffmpeg, $"{cmd} -", out ffmpegp, showFFmpegOutput);
                _ = OutputDataStream.CopyToAsync(DestinationStream, csc.Token);
            }

            OpenedForWriting = true;
        }
예제 #4
0
        /// <summary>
        /// Opens output file for writing and returns the input stream.
        /// </summary>
        /// <param name="outputFilename">Output video file name/path</param>
        /// <param name="options">Output options</param>
        /// <param name="process">FFmpeg process</param>
        /// <param name="inputArguments">Input arguments (such as -f, -v:c, -video_size, -ac, -ar...)</param>
        /// <param name="showOutput">Show output to terminal. Error stream will not be redirected if this is set to true.</param>
        /// <param name="ffmpegExecutable">Name or path to the ffmpeg executable</param>
        public static Stream StreamToFile(string outputFilename, EncoderOptions options, out Process process,
                                          string inputArguments = "", bool showOutput = false, string ffmpegExecutable = "ffmpeg")
        {
            var input = FFmpegWrapper.OpenInput(ffmpegExecutable, $"{inputArguments} -i - " +
                                                $"-c:v {options.EncoderName} {options.EncoderArguments} -f {options.Format} \"{outputFilename}\"", out process, showOutput);

            return(input);
        }
예제 #5
0
        /// <summary>
        /// Get stream for writing and playing video in custom format.
        /// </summary>
        /// <param name="format">Custom video format</param>
        /// <param name="arguments">Custom FFmpeg arguments for the specified video format</param>
        /// <param name="showFFplayOutput">Show FFplay output for debugging purposes.</param>
        public static Stream GetStreamForWriting(string format, string arguments, out Process ffplayProcess,
                                                 bool showFFplayOutput = false, string ffplayExecutable = "ffplay")
        {
            var str = FFmpegWrapper.OpenInput(ffplayExecutable, $"-f {format} {arguments} -i -",
                                              out ffplayProcess, showFFplayOutput);

            return(str);
        }
예제 #6
0
        /// <summary>
        /// Prepares for writing.
        /// </summary>
        /// <param name="showFFmpegOutput">Show output to terminal. Error stream will not be redirected if this is set to true.</param>
        /// <param name="thread_queue_size">Max. number of queued packets when reading from file/stream.
        /// Should be set to higher when dealing with high rate/low latency streams.</param>
        public void OpenWrite(bool showFFmpegOutput = false, int thread_queue_size = 4096)
        {
            if (OpenedForWriting)
            {
                throw new InvalidOperationException("File/Stream was already opened for writing!");
            }

            var manual = new ManualResetEvent(false);

            socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
            socket.Bind(new IPEndPoint(IPAddress.Loopback, 0));
            socket.Listen(4);
            var port = ((IPEndPoint)socket.LocalEndPoint).Port;

            socket.BeginAccept(r =>
            {
                connected_socket     = socket.EndAccept(r);
                InputDataStreamAudio = new NetworkStream(connected_socket);
                manual.Set();
            }, null);

            var cmd = $"-f s{AudioBitDepth}le -channels {AudioChannels} -sample_rate {AudioSampleRate} " +
                      $"-thread_queue_size {thread_queue_size} -i \"tcp://{IPAddress.Loopback}:{port}\" " +
                      $"-f rawvideo -video_size {VideoWidth}:{VideoHeight} -r {VideoFramerate} " +
                      $"-thread_queue_size {thread_queue_size} -pixel_format rgb24 -i - " +
                      $"-map 0 -c:a {AudioEncoderOptions.EncoderName} {AudioEncoderOptions.EncoderArguments} " +
                      $"-map 1 -c:v {VideoEncoderOptions.EncoderName} {VideoEncoderOptions.EncoderArguments} " +
                      $"-f {VideoEncoderOptions.Format}";

            if (UseFilename)
            {
                if (File.Exists(Filename))
                {
                    File.Delete(Filename);
                }

                InputDataStreamVideo = FFmpegWrapper.OpenInput(ffmpeg, $"{cmd} \"{Filename}\"", out ffmpegp, showFFmpegOutput);
            }
            else
            {
                csc = new CancellationTokenSource();

                // using stream
                (InputDataStreamVideo, OutputDataStream) = FFmpegWrapper.Open(ffmpeg, $"{cmd} -", out ffmpegp, showFFmpegOutput);
                _ = OutputDataStream.CopyToAsync(DestinationStream, csc.Token);
            }

            manual.WaitOne();
            OpenedForWriting = true;
        }
예제 #7
0
        /// <summary>
        /// Save frame as an image
        /// </summary>
        /// <param name="output">Output image</param>
        /// <param name="encoder">Encoder for image ('png', 'libwebp')</param>
        /// <param name="ffmpegExecutable">Name or path to the ffmpeg executable</param>
        public void Save(string output, string encoder = "png", string extraParameters = "", string ffmpegExecutable = "ffmpeg")
        {
            if (File.Exists(output))
            {
                File.Delete(output);
            }

            using (var inp = FFmpegWrapper.OpenInput(ffmpegExecutable, $"-f rawvideo -video_size {Width}:{Height} -pixel_format rgb24 -i - " +
                                                     $"-c:v {encoder} {extraParameters} -f image2pipe \"{output}\"",
                                                     out _, false))
            {
                // save it
                inp.Write(RawData.Span);
            }
        }
예제 #8
0
        /// <summary>
        /// Open player for writing frames for playing.
        /// </summary>
        /// <param name="width">Video frame width</param>
        /// <param name="height">Video frame height</param>
        /// <param name="framerateFrequency">Video framerate (frequency form)</param>
        /// <param name="showFFplayOutput">Show FFplay output for debugging purposes.</param>
        public void OpenWrite(int width, int height, string framerateFrequency, bool showFFplayOutput = false)
        {
            if (OpenedForWriting)
            {
                throw new InvalidOperationException("Player is already opened for writing frames!");
            }
            try
            {
                if (ffplayp != null && !ffplayp.HasExited)
                {
                    ffplayp.Kill();
                }
            }
            catch { }

            InputDataStream = FFmpegWrapper.OpenInput(ffplay, $"-f rawvideo -video_size {width}:{height} -framerate {framerateFrequency} -pixel_format rgb24 -i -",
                                                      out ffplayp, showFFplayOutput);

            OpenedForWriting = true;
        }