Skip to content

Instantly share code, notes, and snippets.

@ted80
Created May 19, 2015 08:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ted80/fca42fea86732ac860d9 to your computer and use it in GitHub Desktop.
Save ted80/fca42fea86732ac860d9 to your computer and use it in GitHub Desktop.
using UnityEngine;
using System;
using System.IO;
using System.Collections;
using System.Threading;
public class FFmpeg : MonoBehaviour
{
public delegate void OnProcessExit (FFmpeg _ffmpeg);
public delegate void OnProcessError (FFmpeg _ffmpeg, string _reason);
public event OnProcessExit OnProcessExitEvent = delegate {};
public event OnProcessError OnProcessErrorEvent = delegate {};
private string path;
private string arguments;
private bool createNoWindow;
public bool running = false;
public float progress = 0f;
private Thread thread;
private bool done = false;
private bool error = false;
private string errorMessage = "";
private string welp = "";
public bool convert(string _path, string _arguments, bool _createNoWindow = true)
{
if(!running && !done)
{
path = _path;
arguments = _arguments;
createNoWindow = _createNoWindow;
thread = new Thread(new ThreadStart(startProcess));
thread.Start();
running = true;
done = false;
error = false;
StartCoroutine(loop ());
OnProcessExitEvent += OnExit;
OnProcessErrorEvent += OnError;
return true;
}
return false;
}
void OnExit (FFmpeg _ffmpeg)
{
done = false;
error = false;
OnProcessExitEvent -= OnExit;
OnProcessErrorEvent -= OnError;
}
void OnError (FFmpeg _ffmpeg, string _reason)
{
done = false;
error = false;
OnProcessExitEvent -= OnExit;
OnProcessErrorEvent -= OnError;
}
protected void startProcess()
{
try
{
System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = createNoWindow;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.FileName = path;
process.EnableRaisingEvents = true;
process.StartInfo.Arguments = arguments;
if (!File.Exists(path))
{
setError("Path to bat does not exist!");
}
if (!process.Start())
{
setError("Error starting process!");
return;
}
StreamReader reader = process.StandardError;
string line;
int timeTotal = -1;
while ( ( line = reader.ReadLine() ) != null )
{
welp = line;
if (line.StartsWith("frame=") && timeTotal > -1)
{
progress = ((float)stringToMiliseconds(line, "time=", 11)) / ((float)timeTotal);
}
else if (line.StartsWith(" Duration:"))
{
timeTotal = stringToMiliseconds(line, "Duration: ", 11);
}
else if (line.IndexOf("Invalid argument") > -1)
{
setError("Invalid argument in ffmpeg arguments");
}
else if (line.IndexOf("No such file") > -1)
{
setError("File does not exist!");
}
}
process.Close();
if(!error)
{
done = true;
}
}
catch(Exception e)
{
setError(e.Message);
running = false;
}
Thread.CurrentThread.Abort();
}
private void setError(string _errorMessage)
{
error = true;
errorMessage = _errorMessage;
}
protected IEnumerator loop()
{
while(running)
{
yield return null;
if(done)
{
Debug.Log ("LAST: " + welp);
running = false;
progress = 1f;
OnProcessExitEvent(this);
break;
}
else if(error)
{
Debug.LogWarning("[FFMPEG]: " + errorMessage);
OnProcessErrorEvent(this, errorMessage);
break;
}
else
{
Debug.Log(progress);
}
}
}
private int stringToMiliseconds(string _line, string _index, int _length)
{
int index = _line.IndexOf(_index);
int indexLength = _index.Length;
if(index > -1)
{
string time = _line.Substring(index + indexLength, _length);
TimeSpan ts;
TimeSpan.TryParse(time, out ts);
return (int)ts.TotalSeconds;
}
return -1;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment