How to send written frames in real time/synchronized with FFmpeg and UDP?

For the developers that use FFmpeg in their software.
Post Reply
potu1304
Posts: 1
Joined: Wed Jun 20, 2018 11:15 am

How to send written frames in real time/synchronized with FFmpeg and UDP?

Post by potu1304 » Wed Jun 20, 2018 11:16 am

I wanted to nearly live stream my Unit game with FFmpeg to a simple client. I have one Unity game in which each frame is saved as an jpg image. These images are wrapped in ffmpeg and send over udp to a simple c# client where I use ffplay to play the stream. The problem is, that FFmpeg is wrapping the images way faster than the unity app can write them. So ffmpeg quits but Unity is still writing frames. Is there a way to set ffmpeg in a loop to wait for the next image or can I somehow make a for loop without call every time ffmpeg?

Here is my function from my capturing script in Unity:

Code: Select all

Process process;
    //BinaryWriter _stdin;
    public void encodeFrame()
    {


        ProcessStartInfo startInfo = new ProcessStartInfo();

        var basePath = Application.streamingAssetsPath + "/FFmpegOut/Windows/ffmpeg.exe";


        info.Arguments = "-re -i screen_%d.jpg -vcodec libx264 -r 24 -f mpegts udp://127.0.0.1:1100";
        info.RedirectStandardOutput = true;
        info.RedirectStandardInput = true;
        info.RedirectStandardError = true;
        info.CreateNoWindow = true;
        info.UseShellExecute = false;
        info.RedirectStandardError = true;
        UnityEngine.Debug.Log(string.Format(
            "Executing \"{0}\" with arguments \"{1}\".\r\n",
            info.FileName,
            info.Arguments));
        process = Process.Start(info);
        //_stdin = new BinaryWriter(process.StandardInput.BaseStream);
        process.WaitForExit();
        var outputReader = process.StandardError;
        string Error = outputReader.ReadToEnd();
        UnityEngine.Debug.Log(Error);

}
And here the function from my cs file from my simple windowsform application:

Code: Select all

private void xxxFFplay()
{
    text = "start";
    byte[] send_buffer = Encoding.ASCII.GetBytes(text);
    sock.SendTo(send_buffer, endPoint);
    ffplay.StartInfo.FileName = "ffplay.exe";
    ffplay.StartInfo.Arguments = "udp://127.0.0.1:1100";
    ffplay.StartInfo.CreateNoWindow = true;
    ffplay.StartInfo.RedirectStandardOutput = true;
    ffplay.StartInfo.UseShellExecute = false;

    ffplay.EnableRaisingEvents = true;
    ffplay.OutputDataReceived += (o, e) => Debug.WriteLine(e.Data ?? "NULL", "ffplay");
    ffplay.ErrorDataReceived += (o, e) => Debug.WriteLine(e.Data ?? "NULL", "ffplay");
    ffplay.Exited += (o, e) => Debug.WriteLine("Exited", "ffplay");
    ffplay.Start();

    Thread.Sleep(500); // you need to wait/check the process started, then...

    // child, new parent
    // make 'this' the parent of ffmpeg (presuming you are in scope of a Form or Control)
    //SetParent(ffplay.MainWindowHandle, this.panel1.Handle);

    // window, x, y, width, height, repaint
    // move the ffplayer window to the top-left corner and set the size to 320x280
    //MoveWindow(ffplay.MainWindowHandle, -5, -300, 320, 280, true);

}
Does have somebody some ideas? I am really stuck at this to create a somehow "live" stream.

Best regards

Post Reply
'