You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
147 lines
3.9 KiB
147 lines
3.9 KiB
using System.Diagnostics;
|
|
using System.IO;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using System.Collections;
|
|
|
|
namespace FFmpegOut
|
|
{
|
|
// A stream pipe class that invokes ffmpeg and connect to it.
|
|
public class FFmpegPipe
|
|
{
|
|
#region Public properties
|
|
|
|
public enum Codec { ProRes, H264, VP8 }
|
|
|
|
public string Filename { get; private set; }
|
|
public string Error { get; private set; }
|
|
|
|
#endregion
|
|
|
|
|
|
List<byte[]> writeByteList;
|
|
static Thread thread;
|
|
|
|
#region Public methods
|
|
|
|
public FFmpegPipe(string name, int width, int height, int framerate, Codec codec)
|
|
{
|
|
//name += DateTime.Now.ToString(" yyyy MMdd HHmmss");
|
|
//Filename = name.Replace(" ", "_") + GetSuffix(codec);
|
|
Filename = name + GetSuffix(codec);
|
|
var opt = "-y -f rawvideo -vcodec rawvideo -pixel_format rgb24";
|
|
opt += " -video_size " + width + "x" + height;
|
|
opt += " -framerate " + framerate;
|
|
opt += " -loglevel warning -i - " + GetOptions(codec);
|
|
opt += " " + Filename;
|
|
|
|
if (writeByteList == null)
|
|
writeByteList = new List<byte[]>();
|
|
|
|
writeByteList.Clear();
|
|
GC.Collect();
|
|
recording = true;
|
|
|
|
var info = new ProcessStartInfo(FFmpegConfig.BinaryPath, opt);
|
|
info.UseShellExecute = false;
|
|
info.CreateNoWindow = true;
|
|
info.RedirectStandardInput = true;
|
|
info.RedirectStandardOutput = true;
|
|
info.RedirectStandardError = true;
|
|
|
|
_subprocess = Process.Start(info);
|
|
_stdin = new BinaryWriter(_subprocess.StandardInput.BaseStream);
|
|
thread = new Thread(() => WriteStdin());
|
|
thread.Start();
|
|
}
|
|
|
|
public void Write(byte[] data)
|
|
{
|
|
if (_subprocess == null) return;
|
|
|
|
lock (writeByteList)
|
|
writeByteList.Add(data);
|
|
|
|
//_stdin.Write(data);
|
|
//_stdin.Flush();
|
|
}
|
|
|
|
private static bool recording;
|
|
public void WriteStdin()
|
|
{
|
|
while (recording)
|
|
{
|
|
lock (_stdin)
|
|
{
|
|
lock (writeByteList)
|
|
{
|
|
while (writeByteList.Count > 0)
|
|
{
|
|
_stdin.Write(writeByteList[0]);
|
|
_stdin.Flush();
|
|
writeByteList.RemoveAt(0);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
Thread.CurrentThread.Abort();
|
|
}
|
|
|
|
public IEnumerator Close()
|
|
{
|
|
if (_subprocess == null) yield break;
|
|
recording = false;
|
|
while (thread.IsAlive)
|
|
{
|
|
yield return null;
|
|
}
|
|
_subprocess.StandardInput.Close();
|
|
_subprocess.WaitForExit();
|
|
|
|
var outputReader = _subprocess.StandardError;
|
|
Error = outputReader.ReadToEnd();
|
|
|
|
_subprocess.Close();
|
|
_subprocess.Dispose();
|
|
|
|
outputReader.Close();
|
|
outputReader.Dispose();
|
|
|
|
_subprocess = null;
|
|
_stdin = null;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Private members
|
|
|
|
Process _subprocess;
|
|
BinaryWriter _stdin;
|
|
|
|
static string [] _suffixes = {
|
|
".mov",
|
|
".mp4",
|
|
".webm"
|
|
};
|
|
|
|
static string [] _options = {
|
|
"-c:v prores_ks -pix_fmt yuv422p10le",
|
|
"-pix_fmt yuv420p",
|
|
"-c:v libvpx"
|
|
};
|
|
|
|
public static string GetSuffix(Codec codec)
|
|
{
|
|
return _suffixes[(int)codec];
|
|
}
|
|
|
|
static string GetOptions(Codec codec)
|
|
{
|
|
return _options[(int)codec];
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|
|
|