[chronojump] Added ffmpegCapture standalone program to test on all systems
- From: Xavier de Blas <xaviblas src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [chronojump] Added ffmpegCapture standalone program to test on all systems
- Date: Mon, 15 Oct 2018 18:00:19 +0000 (UTC)
commit e67233829a32a258e2324741b47f71fd839cc5f3
Author: Xavier de Blas <xaviblas gmail com>
Date: Mon Oct 15 19:57:43 2018 +0200
Added ffmpegCapture standalone program to test on all systems
testing-stuff/ffmpegCapture/commandLineEncoder.cs | 102 ++++++
testing-stuff/ffmpegCapture/compile.sh | 1 +
testing-stuff/ffmpegCapture/constants.cs | 38 +++
testing-stuff/ffmpegCapture/executeProcess.cs | 292 ++++++++++++++++
testing-stuff/ffmpegCapture/ffmpegCapture.exe | Bin 0 -> 17920 bytes
testing-stuff/ffmpegCapture/main.cs | 398 ++++++++++++++++++++++
testing-stuff/ffmpegCapture/util.cs | 133 ++++++++
testing-stuff/ffmpegCapture/utilAll.cs | 134 ++++++++
testing-stuff/ffmpegCapture/utilMultimedia.cs | 100 ++++++
9 files changed, 1198 insertions(+)
---
diff --git a/testing-stuff/ffmpegCapture/commandLineEncoder.cs
b/testing-stuff/ffmpegCapture/commandLineEncoder.cs
new file mode 100644
index 00000000..af2b81c2
--- /dev/null
+++ b/testing-stuff/ffmpegCapture/commandLineEncoder.cs
@@ -0,0 +1,102 @@
+// This file is copied and adapted from
https://raw.githubusercontent.com/ericpopivker/Command-Line-Encoder/master/CommandLineEncoder/CommandLineEncoder/Utils.cs
+
+using System;
+using System.Text.RegularExpressions;
+
+public class CommandLineEncoder
+{
+ private const string EscapedSlashN = "[SlashN]";
+
+ public static string EncodeArgText(string original)
+ {
+ var result = original;
+ result = TryEncodeNewLine(result);
+ result = TryEncodeSlashesFollowedByQuotes(result);
+ result = TryEncodeQuotes(result);
+ result = TryEncodeLastSlash(result);
+ return "\"" + result + "\"";
+ }
+
+ private static string TryEncodeNewLine(string original)
+ {
+ var result = original.Replace("\\n", EscapedSlashN);
+
+ result = result.Replace(Environment.NewLine, "\\n");
+ return result;
+ }
+
+ private static string TryEncodeSlashesFollowedByQuotes(string original)
+ {
+ var regexPattern = @"\\+""";
+
+ string result = Regex.Replace(original, regexPattern,
+ delegate(Match match)
+ {
+ string matchText = match.ToString();
+ string justSlashes = matchText.Remove(matchText.Length - 1);
+ return justSlashes + justSlashes + "\""; //double up the slashes
+ });
+
+ return result;
+ }
+
+ private static string TryEncodeQuotes(string original)
+ {
+ var result = original.Replace("\"", "\"\"");
+ return result;
+ }
+
+ private static string TryEncodeLastSlash(string original)
+ {
+ var regexPattern = @"\\+$";
+
+ string result = Regex.Replace(original, regexPattern,
+ delegate(Match match)
+ {
+ string matchText = match.ToString();
+ return matchText + matchText; //double up the slashes
+ });
+
+ return result;
+ }
+
+ public static string DecodeArgText(string original)
+ {
+ string decoded = original;
+
+ decoded = TryDecodeNewLine(decoded);
+
+ return decoded;
+ }
+
+
+ private static string TryDecodeNewLine(string original)
+ {
+ var result = original.Replace("\\n", Environment.NewLine);
+
+ result = result.Replace(EscapedSlashN, "\\n");
+
+ return result;
+ }
+
+
+
+ public static string EscapeBackSlashes(string text)
+ {
+ var regexPattern = "\\\\";
+ var result = text;
+ var regex = new Regex(regexPattern);
+ var matches = regex.Matches(text);
+
+ for (int i = matches.Count - 1; i >= 0; i--)
+ {
+ var match = matches[i];
+ var index = match.Index + match.Length;
+
+ if (index >= text.Length || text[index] == '\\')
+ result = result.Insert(match.Index, "\\");
+ }
+
+ return result;
+ }
+}
diff --git a/testing-stuff/ffmpegCapture/compile.sh b/testing-stuff/ffmpegCapture/compile.sh
new file mode 100755
index 00000000..b8eb3c77
--- /dev/null
+++ b/testing-stuff/ffmpegCapture/compile.sh
@@ -0,0 +1 @@
+mcs *.cs -out:ffmpegCapture.exe
diff --git a/testing-stuff/ffmpegCapture/constants.cs b/testing-stuff/ffmpegCapture/constants.cs
new file mode 100644
index 00000000..9435a4db
--- /dev/null
+++ b/testing-stuff/ffmpegCapture/constants.cs
@@ -0,0 +1,38 @@
+/*
+ * This file is part of ChronoJump
+ *
+ * ChronoJump is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * ChronoJump is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Copyright (C) 2004-2017 Xavier de Blas <xaviblas gmail com>
+ */
+
+using System;
+//do not use gtk or gdk because this class is used by the server
+//see UtilGtk for eg color definitions
+
+public class Constants
+{
+ public enum TestTypes { JUMP, JUMP_RJ, RUN, RUN_I, RT, PULSE, MULTICHRONOPIC, ENCODER }
+ public static string FileCopyProblem = "Error. Cannot copy file.";
+ public static string FileCannotSave = "Error. File cannot be saved.";
+ public static string VideoTemp = "chronojump-last-video";
+ public enum MultimediaItems {
+ PHOTO, PHOTOPNG, VIDEO
+ }
+
+ public const string ExtensionPhoto = ".jpg";
+ public const string ExtensionPhotoPng = ".png"; //used for Cairo resized images
+ public const string ExtensionVideo = ".mp4";
+}
diff --git a/testing-stuff/ffmpegCapture/executeProcess.cs b/testing-stuff/ffmpegCapture/executeProcess.cs
new file mode 100644
index 00000000..e0305286
--- /dev/null
+++ b/testing-stuff/ffmpegCapture/executeProcess.cs
@@ -0,0 +1,292 @@
+/*
+ * This file is part of ChronoJump
+ *
+ * ChronoJump is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * ChronoJump is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Copyright (C) 2016-2017 Carles Pina i Estany <carles pina cat>
+ * Copyright (C) 2017 Xavier de Blas <xaviblas gmail com>
+ */
+
+using System.Collections.Generic;
+using System.Diagnostics;
+using System;
+using System.IO; //FILE
+
+
+/* This class executes a process and returns the result. */
+class ExecuteProcess
+{
+ public struct Result
+ {
+ public const int ERROR_CANT_START = -1;
+
+ // Encapsulates the result of a run: stdout, stderr, exitCode if process couldn't start is
ERROR_CANT_START),
+ // success (if exitCode != 0) and errorMessage to be shown to the user.
+ public string stdout;
+ public string stderr;
+ public string allOutput;
+
+ public int exitCode;
+ public bool success;
+ public string errorMessage;
+
+ public Result(string stdout, string stderr, int exitCode, string errorMessage = "")
+ {
+ this.stdout = stdout;
+ this.stderr = stderr;
+ this.allOutput = stdout + stderr;
+ this.exitCode = exitCode;
+ this.success = (exitCode == 0);
+ this.errorMessage = errorMessage;
+ }
+ };
+
+ public static Result runShowErrorIfNotStarted(string file_name, List<string> parameters)
+ {
+ Result result = run(file_name, parameters);
+
+ if (result.exitCode == Result.ERROR_CANT_START) {
+ //new DialogMessage (Constants.MessageTypes.WARNING, result.errorMessage);
+ Console.WriteLine(result.errorMessage);
+ }
+
+ return result;
+ }
+
+ public static Result run(string file_name)
+ {
+ return runDo (file_name, new List<string>());
+ }
+ public static Result run(string file_name, List<string> parameters)
+ {
+ return runDo (file_name, parameters);
+ }
+
+ // Executes file_name without creating a Window and without using the shell
+ // with the parameters. Waits that it finishes it. Returns the stdout and stderr.
+ private static Result runDo(string file_name, List<string> parameters)
+ {
+ Process process = new Process();
+ ProcessStartInfo processStartInfo = new ProcessStartInfo();
+
+ processStartInfo.FileName = file_name;
+
+ string parameters_string = "";
+ foreach (string parameter in parameters)
+ {
+ parameters_string += CommandLineEncoder.EncodeArgText (parameter) + " ";
+ }
+
+ processStartInfo.Arguments = parameters_string;
+
+ Console.WriteLine ("ExecuteProcess FileName: " + processStartInfo.FileName);
+ Console.WriteLine ("ExecuteProcess Arguments: " + processStartInfo.Arguments);
+
+ processStartInfo.CreateNoWindow = true;
+ processStartInfo.UseShellExecute = false;
+ processStartInfo.RedirectStandardInput = false;
+ processStartInfo.RedirectStandardError = true;
+ processStartInfo.RedirectStandardOutput = true;
+
+ process.StartInfo = processStartInfo;
+
+ try {
+ process.Start();
+ }
+ catch(Exception e) {
+ string errorMessage = String.Format ("Cannot start:\n" +
+ "{0}\n" +
+ "with the parameters:" +
+ "{1}\n" +
+ "Exception:\n" +
+ "{2}",
+ processStartInfo.FileName, parameters_string,
e.Message);
+ Console.WriteLine (errorMessage);
+ return new Result ("", "", Result.ERROR_CANT_START, errorMessage);
+ }
+
+ string stdout = process.StandardOutput.ReadToEnd().TrimEnd ('\n');
+ string stderr = process.StandardError.ReadToEnd ().TrimEnd ('\n');
+
+ process.WaitForExit ();
+
+ if (stderr != "") {
+ Console.WriteLine(String.Format("Executed: {0} Parameters: {1} Stdout: {2} Stderr:
{3}", processStartInfo.FileName, parameters_string, stdout, stderr));
+ }
+
+ int exitCode = process.ExitCode;
+
+ return new Result (stdout, stderr, exitCode);
+ }
+
+ /*
+ * run a process on the background, eg: read rfid.
+ * don't call WaitForExit(), kill it on Chronojump exit
+ * returns false if there are problems calling it
+ */
+ public static bool RunAtBackground(ref Process process, string file_name, List<string> parameters,
bool redirectInput)
+ {
+ ProcessStartInfo processStartInfo = new ProcessStartInfo();
+
+ processStartInfo.FileName = file_name;
+
+ string parameters_string = "";
+ foreach (string parameter in parameters)
+ {
+ parameters_string += CommandLineEncoder.EncodeArgText (parameter) + " ";
+ }
+
+ processStartInfo.Arguments = parameters_string;
+
+ Console.WriteLine ("ExecuteProcess FileName: " + processStartInfo.FileName);
+ Console.WriteLine ("ExecuteProcess Arguments: " + processStartInfo.Arguments);
+
+ processStartInfo.CreateNoWindow = true;
+ processStartInfo.UseShellExecute = false;
+ processStartInfo.RedirectStandardInput = redirectInput; //note UseShellExecute has to be
false to be able to redirect
+ processStartInfo.RedirectStandardError = true;
+ processStartInfo.RedirectStandardOutput = true;
+
+ process.StartInfo = processStartInfo;
+
+ try {
+ process.Start();
+ }
+ catch(Exception e) {
+ string errorMessage = String.Format ("Cannot start:\n" +
+ "{0}\n" +
+ "with the parameters:" +
+ "{1}\n" +
+ "Exception:\n" +
+ "{2}",
+ processStartInfo.FileName, parameters_string,
e.Message);
+ Console.WriteLine (errorMessage);
+ return false;
+ }
+
+ return true;
+ }
+
+
+ //better method than below
+ //https://stackoverflow.com/a/262291
+ public static bool IsRunning2 (Process process, string executable)
+ {
+ Process[] pNameArray = Process.GetProcessesByName(process.ProcessName);
+ if (pNameArray.Length == 0)
+ return false;
+
+ foreach(Process p in pNameArray)
+ if(p.Id == process.Id)
+ return true;
+
+ return false;
+ }
+
+ //This seems is not working with ffmpeg capture, try method obove
+ public static bool IsRunning(Process process)
+ {
+ Console.WriteLine("calling Process.IsRunning()");
+ if(process == null) {
+ Console.WriteLine("process == null");
+ return false;
+ } else {
+ if(isRunningThisProcess(process))
+ return true;
+ }
+
+ return false;
+ }
+
+ private static bool isRunningThisProcess(Process p)
+ {
+ /*
+ * Process Id is not valid if the associated process is not running.
+ * Need to ensure that the process is running before attempting to retrieve the Id property.
+ */
+
+ try {
+ Console.WriteLine(string.Format("last pid id {0}", p.Id));
+ Process pid = Process.GetProcessById(p.Id);
+ if(pid == null)
+ return false;
+ } catch {
+ return false;
+ }
+
+ return true;
+ }
+
+ /*
+ * don't use this because in linux R script can be called by:
+ * "/usr/lib/R/bin/exec/R"
+ * and it will not be found passing "R" or "*R"
+ private bool isRunningThisProcess(string name)
+ {
+ Process [] pids = Process.GetProcessesByName(name);
+ foreach (Process myPid in pids) {
+ Console.WriteLine(string.Format("pids id: {0}", myPid.Id));
+ if (myPid.Id == Convert.ToInt32(p.Id))
+ return true;
+ }
+
+ return false;
+ }
+ */
+
+ /*
+ * The process.Responding only works on GUI processes
+ * So, here we send a "ping" expecting to see the result in short time
+ *
+ * TODO: maybe is good to kill the unresponsive processes
+ */
+ public static bool IsResponsive(Process p)
+ {
+ Random rnd = new Random();
+ int randomInt = rnd.Next(); //eg. 1234
+
+ string randomPingStr = "PING" + Path.Combine(Path.GetTempPath(), "chronojump" +
randomInt.ToString() + ".txt");
+ //eg Linux: 'PING/tmp/chronojump1234.txt'
+ //eg Windows: 'PINGC:\Temp...\chronojump1234.txt'
+
+ if (UtilAll.IsWindows()) {
+ //On win32 R understands backlash as an escape character and
+ //a file path uses Unix-like path separator '/'
+ randomPingStr = randomPingStr.Replace("\\","/");
+ }
+ //eg Windows: 'PINGC:/Temp.../chronojump1234.txt'
+
+ Console.WriteLine("Sending ping: " + randomPingStr);
+ try {
+ p.StandardInput.WriteLine(randomPingStr);
+ } catch {
+ Console.WriteLine("Catched waiting response");
+ return false;
+ }
+
+ //wait 250ms the response
+ System.Threading.Thread.Sleep(250);
+
+ //On Linux will be '/' on Windows '\'
+ if(File.Exists(Path.Combine(Path.GetTempPath(), "chronojump" + randomInt.ToString() +
".txt"))) {
+ Console.WriteLine("Process is responding");
+ return true;
+ }
+
+ Console.WriteLine("Process is NOT responding");
+ return false;
+ }
+
+}
diff --git a/testing-stuff/ffmpegCapture/ffmpegCapture.exe b/testing-stuff/ffmpegCapture/ffmpegCapture.exe
new file mode 100755
index 00000000..1e90a6cd
Binary files /dev/null and b/testing-stuff/ffmpegCapture/ffmpegCapture.exe differ
diff --git a/testing-stuff/ffmpegCapture/main.cs b/testing-stuff/ffmpegCapture/main.cs
new file mode 100644
index 00000000..eb35de53
--- /dev/null
+++ b/testing-stuff/ffmpegCapture/main.cs
@@ -0,0 +1,398 @@
+/*
+ * This file is part of ChronoJump
+ *
+ * ChronoJump is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * ChronoJump is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Copyright (C) 2018 Xavier de Blas <xaviblas gmail com>
+ */
+
+using System.Collections.Generic; //List
+using System.Diagnostics;
+using System;
+using System.IO;
+using System.Text.RegularExpressions; //Regex
+
+class FfmpegCapture
+{
+ private UtilAll.OperatingSystems os;
+ private string captureExecutable = "ffmpeg";
+ private StreamWriter streamWriter;
+ private Process process;
+ protected static internal string programFfmpegNotInstalled =
+ string.Format("Error. {0} is not installed.", "ffmpeg");
+ public bool Running;
+ private string videoDevice;
+
+
+
+
+ /*
+ public void WebcamFfmpeg (UtilAll.OperatingSystems os, string videoDevice)
+ {
+ this.os = os;
+ this.videoDevice = videoDevice;
+
+ captureExecutable = "ffmpeg";
+ if(os == UtilAll.OperatingSystems.WINDOWS)
+ captureExecutable = System.IO.Path.Combine(Util.GetPrefixDir(), "bin/ffmpeg.exe");
+
+ Running = false;
+ }
+ */
+
+ /*
+ * constructor for Play
+
+ public WebcamFfmpeg ()
+ {
+ }
+ */
+
+ // Result struct holds the output, error and success operations. It's used to pass
+ // errors from different layers (e.g. executing Python scripts) to the UI layer
+ public struct Result
+ {
+ public bool success;
+ public string output;
+ public string error;
+
+ public Result(bool success, string output, string error = "")
+ {
+ this.success = success;
+ this.output = output;
+ this.error = error;
+ }
+ }
+
+ public enum CaptureTypes { PHOTO, VIDEO }
+
+ public Result CapturePrepare (CaptureTypes captureType)
+ {
+ if(process != null)
+ return new Result (false, "");
+
+ return new Result (true, "");
+ }
+
+ public Result Play(string filename)
+ {
+ //only implemented on mplayer
+ return new Result (true, "");
+ }
+ public bool Snapshot()
+ {
+ //only implemented on mplayer
+ return true;
+ }
+
+
+ public static void Main(string[] args)
+ {
+ new FfmpegCapture(args);
+ }
+
+ public FfmpegCapture(string[] args)
+ {
+ if(args.Length != 1) {
+ Console.WriteLine("Need to pass the videoDevice");
+ return;
+ }
+
+ os = UtilAll.GetOSEnum();
+ videoDevice = args[0];
+
+ if(os == UtilAll.OperatingSystems.WINDOWS)
+ captureExecutable = System.IO.Path.Combine(Util.GetPrefixDir(), "bin/ffmpeg.exe");
+
+ process = new Process();
+ List<string> parameters = createParametersOnlyCapture();
+ //List<string> parameters = createParametersCaptureAndDelayedView();
+ bool success = ExecuteProcess.RunAtBackground (ref process, captureExecutable, parameters,
true); //redirectInput
+ if(! success)
+ {
+ streamWriter = null;
+ process = null;
+ //return new Result (false, "", programFfmpegNotInstalled);
+ return;
+ }
+
+ streamWriter = process.StandardInput;
+ Running = true;
+
+ Console.WriteLine("Recording 5 seconds ...");
+ for(int countA = 4; countA >= 0; countA --)
+ {
+ System.Threading.Thread.Sleep(1000);
+ Console.WriteLine(countA.ToString());
+ }
+
+ ExitAndFinish (0, Constants.TestTypes.RUN, 1);
+
+
+ //return new Result (true, "");
+ }
+
+ private List<string> createParametersOnlyCapture()
+ {
+ // ffmpeg -y -f v4l2 -framerate 30 -video_size 640x480 -input_format mjpeg -i /dev/video0
out.mp4
+ List<string> parameters = new List<string>();
+
+ int i = 0;
+ parameters.Insert (i ++, "-y"); //overwrite
+
+ parameters.Insert (i ++, "-f");
+ if(os == UtilAll.OperatingSystems.LINUX)
+ parameters.Insert (i ++, "v4l2");
+ else //windows
+ parameters.Insert (i ++, "dshow");
+
+ parameters.Insert (i ++, "-framerate");
+ parameters.Insert (i ++, "30");
+ parameters.Insert (i ++, "-video_size");
+ parameters.Insert (i ++, "640x480");
+
+ if(os == UtilAll.OperatingSystems.LINUX) {
+ parameters.Insert (i ++, "-input_format");
+ parameters.Insert (i ++, "mjpeg");
+ }
+
+ parameters.Insert (i ++, "-i");
+ if(os == UtilAll.OperatingSystems.LINUX)
+ parameters.Insert (i ++, videoDevice);
+ else //windows
+ parameters.Insert (i ++, "video=" + videoDevice);
+
+ parameters.Insert (i ++, Util.GetVideoTempFileName());
+
+ return parameters;
+ }
+
+ //Care: press q two times, one for each process on the tee
+ //or only one on the ffplay process
+ private List<string> createParametersCaptureAndDelayedView()
+ {
+ //ffmpeg -y -f v4l2 -i /dev/video0 -map 0 -c:v libx264 -f tee "output.mkv|[f=nut]pipe:" |
ffplay pipe:
+ List<string> parameters = new List<string>();
+
+ int i = 0;
+ parameters.Insert (i ++, "-y"); //overwrite
+
+ parameters.Insert (i ++, "-f");
+ if(os == UtilAll.OperatingSystems.LINUX)
+ parameters.Insert (i ++, "v4l2");
+ else //windows
+ parameters.Insert (i ++, "dshow");
+
+ parameters.Insert (i ++, "-i");
+ if(os == UtilAll.OperatingSystems.LINUX)
+ parameters.Insert (i ++, "\"" + videoDevice + "\"");
+ else //windows
+ parameters.Insert (i ++, "video=\"" + videoDevice + "\"");
+
+ parameters.Insert (i ++, "-map");
+ parameters.Insert (i ++, "0");
+ parameters.Insert (i ++, "-c:v");
+ parameters.Insert (i ++, "libx264");
+ parameters.Insert (i ++, "-f");
+ parameters.Insert (i ++, "tee");
+
+ //TODO: Think on the \" for windows and maybe also for other OSes
+ parameters.Insert (i ++, "'" + Util.GetVideoTempFileName() + "|[f=nut]pipe:'");
+ parameters.Insert (i ++, "|");
+ parameters.Insert (i ++, "ffplay");
+ parameters.Insert (i ++, "pipe:");
+
+ return parameters;
+ }
+
+ /*
+ * there are problems calling the process with the "|"
+ * better call a shell script like this:
+ * ffmpeg_capture_and_play.sh
+ *
+ * #!/bin/bash
+ * ffmpeg -y -f v4l2 -i /dev/video0 -map 0 -c:v libx264 -f tee
"/tmp/chronojump-last-video.mp4|[f=nut]pipe:" | ffplay pipe:
+ */
+
+
+ public Result ExitAndFinish (int sessionID, Constants.TestTypes testType, int testID)
+ {
+ ExitCamera();
+
+ //Copy the video to expected place
+ //if (! Util.CopyTempVideo(sessionID, testType, testID))
+ // return new Result (false, "", Constants.FileCopyProblem);
+
+ //Delete temp video
+ //deleteTempFiles();
+
+ return new Result (true, "");
+ }
+
+ public void ExitCamera()
+ {
+ Console.WriteLine("Exit camera");
+ Console.WriteLine("streamWriter is null: " + (streamWriter == null).ToString());
+ try {
+ streamWriter.Write('q'); //encara que hi hagi el process.Close() de sota, no es tanca
la càmera sense aquest 'q'
+ //streamWriter.Flush();
+// streamWriter.WriteLine("\x3");
+ //streamWriter.Flush();
+ //process.StandardInput.WriteLine("\x3");
+// streamWriter.WriteLine("q\n");
+ } catch {
+ //maybe Mplayer window has been closed by user
+ process = null;
+ Running = false;
+ return;
+ }
+
+ Console.WriteLine("closing ...");
+ process.Close();
+
+ //this does not work
+ //Console.WriteLine("waiting for exit ...");
+ //process.WaitForExit();
+
+ Console.WriteLine("done!");
+
+ //amb el process.Close(); tanca i tanca be pero es perden fotogrames inicials i finals, vaja
que no tanca massa be, no estic segur de si realment enviar la q serveix de algo, vaig a fer-ho sense la q
+ //si que tanca be pq ara he provat sense enviar el q, nomes amb el process.Close() i la
camera es queda oberta
+
+ /*
+ //System.Threading.Thread.Sleep(500);
+ //better check if process still exists to later copy the video
+ do {
+ Console.WriteLine("waiting 100 ms to end Ffmpeg");
+ System.Threading.Thread.Sleep(100);
+ } while(ExecuteProcess.IsRunning2(process, captureExecutable));
+ */
+
+ streamWriter = null;
+ process = null;
+ Running = false;
+ }
+
+ /*
+ * protected methods
+ */
+
+ protected void deleteTempFiles()
+ {
+ Console.WriteLine("Deleting temp video");
+ if(File.Exists(Util.GetVideoTempFileName()))
+ File.Delete(Util.GetVideoTempFileName());
+ }
+
+}
+
+public static class WebcamFfmpegGetDevicesWindows
+{
+ public static List<string> GetDevices()
+ {
+ string executable = "ffmpeg";
+ if(UtilAll.GetOSEnum() == UtilAll.OperatingSystems.WINDOWS)
+ executable = System.IO.Path.Combine(Util.GetPrefixDir(), "bin/ffmpeg.exe");
+
+ List<string> parameters = createParameters();
+
+ ExecuteProcess.Result execute_result = ExecuteProcess.run (executable, parameters);
+
+ Console.WriteLine("---- stdout: ----");
+ Console.WriteLine(execute_result.stdout);
+ Console.WriteLine("---- stderr: ----");
+ Console.WriteLine(execute_result.stderr);
+ Console.WriteLine("-----------------");
+
+ if(! execute_result.success)
+ {
+ Console.WriteLine("WebcamFfmpegGetDevicesWindows error: " + execute_result.stderr);
+
+ /*
+ * on Windows the -i dummy produces an error, so stderr exists and success is false
+ * stdout has the list of devices and stderr also
+ * check if in stdout there's the: "DirectShow video devices" string and if not
exists, really we have an error
+ */
+ if(execute_result.stdout != null && execute_result.stdout != "" &&
+ execute_result.stdout.Contains("DirectShow video devices"))
+ {
+ Console.WriteLine("Calling parse with stdout");
+ return parse(execute_result.stdout);
+ }
+
+ if(execute_result.stderr != null && execute_result.stderr != "" &&
+ execute_result.stderr.Contains("DirectShow video devices"))
+ {
+ Console.WriteLine("Calling parse with stderr");
+ return parse(execute_result.stderr);
+ }
+
+ return new List<string>();
+ }
+ else
+ return parse(execute_result.stdout);
+ }
+
+ private static List<string> createParameters()
+ {
+ //ffmpeg -list_devices true -f dshow -i dummy
+ List<string> parameters = new List<string>();
+
+ int i = 0;
+ parameters.Insert (i ++, "-list_devices");
+ parameters.Insert (i ++, "true");
+ parameters.Insert (i ++, "-f");
+ parameters.Insert (i ++, "dshow");
+ parameters.Insert (i ++, "-i");
+ parameters.Insert (i ++, "dummy");
+
+ return parameters;
+ }
+
+ private static List<string> parse(string devicesOutput)
+ {
+ Console.WriteLine("Called parse");
+
+ /*
+ * break the big string in \n strings
+ * https://stackoverflow.com/a/1547483
+ */
+ string[] lines = devicesOutput.Split(
+ new[] { Environment.NewLine },
+ StringSplitOptions.None
+ );
+
+ List<string> parsedList = new List<string>();
+ foreach(string l in lines)
+ {
+ Console.WriteLine("line: " + l);
+ foreach(Match match in Regex.Matches(l, "\"([^\"]*)\""))
+ {
+ //remove quotes from the match (at beginning and end) to add it in SQL
+ string s = match.ToString().Substring(1, match.ToString().Length -2);
+
+ Console.WriteLine("add match: " + s);
+ parsedList.Add(s);
+ }
+
+ //after the list of video devices comes the list of audio devices, skip it
+ if(l.Contains("DirectShow audio devices"))
+ break;
+ }
+
+ return parsedList;
+ }
+}
+
diff --git a/testing-stuff/ffmpegCapture/util.cs b/testing-stuff/ffmpegCapture/util.cs
new file mode 100644
index 00000000..b4786605
--- /dev/null
+++ b/testing-stuff/ffmpegCapture/util.cs
@@ -0,0 +1,133 @@
+/*
+ * This file is part of ChronoJump
+ *
+ * ChronoJump is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * ChronoJump is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Copyright (C) 2004-2017 Xavier de Blas <xaviblas gmail com>
+ */
+
+using System;
+//using System.Data;
+using System.Text; //StringBuilder
+using System.Collections; //ArrayList
+using System.Collections.Generic; //List<T>
+using System.Diagnostics; //for detect OS
+using System.IO; //for detect OS
+using System.Globalization; //Unicode
+
+//this class tries to be a space for methods that are used in different classes
+public class Util
+{
+ public static string GetManualDir() {
+ //we are on:
+ //lib/chronojump/ (Unix) or bin/ (win32)
+ //we have to go to
+ //share/doc/chronojump
+ return System.IO.Path.Combine(Util.GetPrefixDir(),
+ "share" + Path.DirectorySeparatorChar + "doc" + Path.DirectorySeparatorChar +
"chronojump");
+ }
+
+ public static string GetPrefixDir(){
+ string baseDirectory = System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory,
"..");
+ if (! Directory.Exists(Path.Combine(baseDirectory, "lib" + Path.DirectorySeparatorChar +
"chronojump"))) {
+ baseDirectory = System.IO.Path.Combine(baseDirectory, "..");
+ }
+ return baseDirectory;
+ }
+
+ public static string GetDataDir(){
+ return System.IO.Path.Combine(GetPrefixDir(),
+ "share" + Path.DirectorySeparatorChar + "chronojump");
+ }
+
+ public static string GetImagesDir(){
+ return System.IO.Path.Combine(GetDataDir(),"images");
+ }
+
+ public static string GetVideoTempFileName() {
+ return Path.Combine(
+ Path.GetTempPath(), Constants.VideoTemp +
+ GetMultimediaExtension(Constants.MultimediaItems.VIDEO));
+ }
+
+ public static bool CopyTempVideo(int sessionID, Constants.TestTypes type, int uniqueID) {
+ string origin = GetVideoTempFileName();
+ string destination = GetVideoFileName(sessionID, type, uniqueID);
+ Console.WriteLine("destination is: " + destination);
+ if(File.Exists(origin)) {
+ CreateVideoSessionDirIfNeeded(sessionID);
+ /*
+ * no more move it, just copy it, because maybe is still being recorded
+ try {
+ File.Move(origin, destination);
+ } catch {
+ */
+ File.Copy(origin, destination, true); //can be overwritten
+ //}
+ return true;
+ } else
+ return false;
+ }
+
+ public static void DeleteVideo(int sessionID, Constants.TestTypes type, int uniqueID) {
+ string fileName = GetVideoFileName(sessionID, type, uniqueID);
+ if(File.Exists(fileName))
+ File.Delete(fileName);
+ }
+ public static string GetMultimediaExtension (string filename)
+ {
+ if(UtilMultimedia.GetImageType(filename) == UtilMultimedia.ImageTypes.JPEG)
+ return Constants.ExtensionPhoto;
+ if(UtilMultimedia.GetImageType(filename) == UtilMultimedia.ImageTypes.PNG)
+ return Constants.ExtensionPhotoPng;
+
+ return "";
+ }
+
+ public static string GetMultimediaExtension (Constants.MultimediaItems multimediaItem) {
+ if(multimediaItem == Constants.MultimediaItems.VIDEO)
+ return Constants.ExtensionVideo;
+ else if(multimediaItem == Constants.MultimediaItems.PHOTO)
+ return Constants.ExtensionPhoto;
+ else //multimediaItem == Constants.MultimediaItems.PHOTOPNG
+ return Constants.ExtensionPhotoPng;
+ }
+
+ public static string GetVideoFileName (int sessionID, Constants.TestTypes testType, int
uniqueID) {
+ return GetVideoSessionDir(sessionID) + Path.DirectorySeparatorChar +
+ testType.ToString() + "-" + uniqueID.ToString() +
+ GetMultimediaExtension(Constants.MultimediaItems.VIDEO);
+ }
+
+ public static void CreateVideoSessionDirIfNeeded (int sessionID) {
+ string sessionDir = GetVideoSessionDir(sessionID);
+ if( ! Directory.Exists(sessionDir)) {
+ Directory.CreateDirectory (sessionDir);
+ Console.WriteLine ("created dir:", sessionDir);
+ }
+ }
+
+ public static string GetVideoSessionDir (int sessionID) {
+ return GetVideosDir() + Path.DirectorySeparatorChar + sessionID.ToString();
+ }
+
+ public static string GetVideosDir() {
+ return Path.Combine(
+ Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
+ "Chronojump" + Path.DirectorySeparatorChar + "multimedia" +
+ Path.DirectorySeparatorChar + "videos");
+ }
+
+}
diff --git a/testing-stuff/ffmpegCapture/utilAll.cs b/testing-stuff/ffmpegCapture/utilAll.cs
new file mode 100644
index 00000000..1f106f83
--- /dev/null
+++ b/testing-stuff/ffmpegCapture/utilAll.cs
@@ -0,0 +1,134 @@
+/*
+ * This file is part of ChronoJump
+ *
+ * ChronoJump is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * ChronoJump is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Copyright (C) 2004-2017 Xavier de Blas <xaviblas gmail com>
+ */
+
+using System;
+using System.Diagnostics; //for detect OS
+using System.IO; //for detect OS
+using System.Reflection; // Read Version
+
+//this class tries to be a space for methods that are used in different classes
+//in chronojump and chronojump_mini
+//we do not use util.cs in mini because it has lot of calls to other files
+public class UtilAll
+{
+ static bool printedOS = false;
+
+ //Eg. 1.6.2.0
+ public static string ReadVersion()
+ {
+ Version version = Assembly.GetExecutingAssembly().GetName().Version;
+ return version.ToString();
+ }
+
+
+ //Adapted from Mono. A developer's notebook. p 244
+
+ //this is used in chronojump for working with the ports,
+ //in chronojump we compile now for Linux with Mono and for Windows with .NET
+ //it should be something like IsDotNet()
+ public static bool IsWindows() {
+ string os = GetOS();
+ if(os.ToUpper().StartsWith("WIN"))
+ return true;
+ else
+ return false;
+ }
+
+ public static string GetOS() {
+ OperatingSystem os = Environment.OSVersion;
+ string platform = os.Platform.ToString();
+
+ //detect a Mac that seems an Unix
+ if(platform == "Unix" && GetOSEnum() == OperatingSystems.MACOSX)
+ platform = "Unix (MacOSX)";
+
+ string osString = string.Format("{0}, {1}", platform, os.Version);
+
+ if(! printedOS) {
+ Console.WriteLine("GetOS: " + osString);
+ printedOS = true;
+ }
+
+ return osString;
+ }
+
+ public enum OperatingSystems { WINDOWS, LINUX, MACOSX };
+
+ public static OperatingSystems GetOSEnum()
+ {
+
//http://stackoverflow.com/questions/10138040/how-to-detect-properly-windows-linux-mac-operating-systems
+ switch (Environment.OSVersion.Platform)
+ {
+ case PlatformID.Unix:
+ // Well, there are chances MacOSX is reported as Unix instead of MacOSX.
+ // Instead of platform check, we'll do a feature checks (Mac specific root
folders)
+ if (Directory.Exists("/Applications")
+ & Directory.Exists("/System")
+ & Directory.Exists("/Users")
+ & Directory.Exists("/Volumes"))
+ return OperatingSystems.MACOSX;
+ else
+ return OperatingSystems.LINUX;
+
+ case PlatformID.MacOSX:
+ return OperatingSystems.MACOSX;
+
+ default:
+ return OperatingSystems.WINDOWS;
+ }
+ }
+
+
+ public static string GetApplicationDataDir() {
+ return Path.Combine(
+ Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
+ "Chronojump");
+ }
+
+ public static string GetECapSimSignalFileName() {
+ return Path.Combine(GetApplicationDataDir() + Path.DirectorySeparatorChar +
"eCapSimSignal.txt");
+ }
+
+
+
+ //if passed (number=1, digits=4)
+ //takes 1 and returns "0001"
+ public static string DigitsCreate (int number, int digits)
+ {
+ string str = number.ToString();
+ while(str.Length < digits)
+ str = "0" + str;
+ return str;
+ }
+
+ // ----------- logs -----------------------
+
+
+ public static string GetTempDir() {
+ string path = Path.GetTempPath();
+
+ path = path.TrimEnd(Path.DirectorySeparatorChar);
+ //on Linux folder cannot be opened either with '/' at the end, or without it
+
+ return path;
+ }
+
+
+}
diff --git a/testing-stuff/ffmpegCapture/utilMultimedia.cs b/testing-stuff/ffmpegCapture/utilMultimedia.cs
new file mode 100644
index 00000000..0acb98b3
--- /dev/null
+++ b/testing-stuff/ffmpegCapture/utilMultimedia.cs
@@ -0,0 +1,100 @@
+/*
+ * This file is part of ChronoJump
+ *
+ * ChronoJump is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * ChronoJump is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Copyright (C) 2004-2017 Xavier de Blas <xaviblas gmail com>
+ */
+
+using System;
+using System.Text; //StringBuilder
+using System.Collections; //ArrayList
+using System.Collections.Generic; //List
+using System.Diagnostics; //for detect OS
+using System.IO; //for detect OS
+//using Cairo;
+//using Gdk;
+
+//this class tries to be a space for methods that are used in different classes
+public class UtilMultimedia
+{
+ /*
+ * VIDEO
+ */
+
+ public static List<string> GetVideoDevices ()
+ {
+ /*
+ * TODO: reimplement this with ffmpeg
+ *
+ List<LongoMatch.Video.Utils.Device> devices =
LongoMatch.Video.Utils.Device.ListVideoDevices();
+ string [] devicesStr = new String[devices.Count];
+ int count = 0;
+ LogB.Information("Searching video devices");
+ foreach(LongoMatch.Video.Utils.Device dev in devices) {
+ devicesStr[count++] = dev.ID.ToString();
+ LogB.Information(dev.ID.ToString());
+ }
+ return devicesStr;
+ */
+
+
+ //on Linux search for video0, video1, ...
+ if(UtilAll.GetOSEnum() == UtilAll.OperatingSystems.LINUX)
+ return GetVideoDevicesLinux();
+ else if(UtilAll.GetOSEnum() == UtilAll.OperatingSystems.WINDOWS)
+ return GetVideoDevicesWindows();
+ else
+ return new List<string>();
+ }
+
+ public static List<string> GetVideoDevicesLinux ()
+ {
+ List<string> list = new List<string>();
+ string prefix = "/dev/";
+ var dir = new DirectoryInfo(prefix);
+ foreach(var file in dir.EnumerateFiles("video*"))
+ /*
+ * return 0, 1, ...
+ if( file.Name.Length > 5 && //there's something more than
"video", like "video0" or "video1", ...
+ char.IsNumber(file.Name, 5) ) //and it's a number
+ list.Add(Convert.ToInt32(file.Name[5])); //0 or 1, or ...
+ */
+ //return "/dev/video0", "/dev/video1", ...
+ list.Add(prefix + file.Name);
+
+ return list;
+ }
+
+ public static List<string> GetVideoDevicesWindows ()
+ {
+ return WebcamFfmpegGetDevicesWindows.GetDevices();
+ }
+
+ /*
+ * IMAGES
+ */
+
+ public enum ImageTypes { UNKNOWN, PNG, JPEG }
+ public static ImageTypes GetImageType(string filename)
+ {
+ if(filename.ToLower().EndsWith("jpeg") || filename.ToLower().EndsWith("jpg"))
+ return ImageTypes.JPEG;
+ else if(filename.ToLower().EndsWith("png"))
+ return ImageTypes.PNG;
+
+ return ImageTypes.UNKNOWN;
+ }
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]