Daniel Lip
Daniel Lip

Reputation: 11321

How to stop ffmpeg when recording the desktop to save the file to the hard disk?

I'm trying to record the desktop with the ffmpeg and save a video file to the hard disk.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Testings
{
    internal class FFmpeg_Capture
    {
        Process process;

        public FFmpeg_Capture()
        {
            process = new Process();
        }

        public void Start(string FileName, int Framerate)
        {
            process.StartInfo.FileName = @"D:\Captured Videos\ffmpeg.exe"; // Change the directory where ffmpeg.exe is.  
            process.EnableRaisingEvents = false;
            process.StartInfo.WorkingDirectory = @"D:\Captured Videos"; // The output directory  
            process.StartInfo.Arguments = @"-f gdigrab -framerate " + Framerate +
                " -i desktop -preset ultrafast - pix_fmt yuv420p " + FileName;
            process.Start();
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.CreateNoWindow = false;
            Stop();
        }

        public void Stop()
        {
            process.Close();
        }
    }
}

And using it in form1 :

private void btnRecord_Click(object sender, EventArgs e)
        {
            recordToggle = !recordToggle;

            if (recordToggle)
            {
                btnRecord.Text = "Stop";
                record.Start("Testing", 60);
            }
            else
            {
                btnRecord.Text = "Record";
                record.Stop();
            }
        }

but the file Testing never saved to the hard disk. my guess is that

process.Close();

is not like ctrl+ c and ctrl + c is what stopping the ffmpeg and save the file.

This is working but how to remove the black window of the ffmpeg ?

ffmpeg black window

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.IO.Pipes;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Testings
{
    internal class FFmpeg_Capture
    {
        Process process;

        public FFmpeg_Capture()
        {
            process = new Process();
        }

        public void Start(string FileName, int Framerate)
        {
            process.StartInfo.FileName = @"D:\Captured Videos\ffmpeg.exe"; // Change the directory where ffmpeg.exe is.  
            process.EnableRaisingEvents = false;
            process.StartInfo.WorkingDirectory = @"D:\Captured Videos\"; // The output directory  
            process.StartInfo.Arguments = @"-y -f gdigrab -framerate " + Framerate +
                " -i desktop -preset ultrafast -pix_fmt yuv420p " + FileName;
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.CreateNoWindow = false;
            process.StartInfo.RedirectStandardInput = true; //Redirect stdin
            process.Start();
        }

        public void Stop()
        {
            byte[] qKey = Encoding.GetEncoding("gbk").GetBytes("q"); //Get encoding of 'q' key
            process.StandardInput.BaseStream.Write(qKey, 0, 1); //Write 'q' key to stdin of FFmpeg sub-processs
            process.StandardInput.BaseStream.Flush(); //Flush stdin (just in case).
            process.Close();
        }
    }
}

Upvotes: 1

Views: 940

Answers (1)

Rotem
Rotem

Reputation: 32084

When we start recording, the following message appears:

Press [q] to stop, [?] for help.

Writing 'q' to stdin simulates pressing q key, and stops recording.


  • Start FFmpeg sub-process with RedirectStandardInput = true:

     process.StartInfo.RedirectStandardInput = true;
     process.Start();
    
  • Write q key to stdin pipe of FFmpeg sub-process:

     byte[] qKey = Encoding.GetEncoding("gbk").GetBytes("q");
     process.StandardInput.BaseStream.Write(qKey, 0, 1);
    

Complete code sample:

using System.Diagnostics;
using System.Text;

namespace Testings
{
    internal class FFmpeg_Capture
    {
        Process process;

        public FFmpeg_Capture()
        {
            process = new Process();
        }

        public void Start(string FileName, int Framerate)
        {
            process.StartInfo.FileName = @"C:\FFmpeg\bin\ffmpeg.exe"; // Change the directory where ffmpeg.exe is.  
            process.EnableRaisingEvents = false;
            process.StartInfo.WorkingDirectory = @"D:\"; // The output directory  
            process.StartInfo.Arguments = @"-y -f gdigrab -framerate " + Framerate +
                " -i desktop -preset ultrafast -pix_fmt yuv420p " + FileName;            
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.CreateNoWindow = false;
            process.StartInfo.RedirectStandardInput = true; //Redirect stdin
            process.Start();
            System.Threading.Thread.Sleep(3000);  //Wait 3 seconds (for testing).
            Stop();
        }

        public void Stop()
        {
            byte[] qKey = Encoding.GetEncoding("gbk").GetBytes("q"); //Get encoding of 'q' key
            process.StandardInput.BaseStream.Write(qKey, 0, 1); //Write 'q' key to stdin of FFmpeg sub-processs
            process.StandardInput.BaseStream.Flush(); //Flush stdin (just in case).
            process.Close();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            FFmpeg_Capture cap = new FFmpeg_Capture();
            cap.Start("vid.mp4", 5);
        }
    }
}

Upvotes: 1

Related Questions