[chronojump] Implemented webcam ffmpeg capture



commit 96cd1cb582c93b267ef5c32359cd12bfc69026cb
Author: Xavier de Blas <xaviblas gmail com>
Date:   Wed Aug 1 16:07:49 2018 +0200

    Implemented webcam ffmpeg capture

 src/Makefile.am      |   1 +
 src/util.cs          |  14 -----
 src/webcam.cs        |   8 ++-
 src/webcamFfmpeg.cs  | 162 +++++++++++++++++++++++++++++++++++++++++++++++++++
 src/webcamMplayer.cs |  32 +++++++---
 5 files changed, 193 insertions(+), 24 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 77eafd03..404b53a8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -216,6 +216,7 @@ SOURCES = \
        oldCodeNeedToDBConvert/sqlite/personSession.cs\
        oldCodeNeedToDBConvert/sqlite/session.cs\
        webcam.cs\
+       webcamFfmpeg.cs\
        webcamMplayer.cs
 
 RESOURCES = \
diff --git a/src/util.cs b/src/util.cs
index 959493dc..f246cb97 100644
--- a/src/util.cs
+++ b/src/util.cs
@@ -1148,20 +1148,6 @@ public class Util
                        return false;
        }
 
-       public static void DeleteTempPhotosAndVideo(string videoDevice)
-       {
-               LogB.Information("Deleting temp files");
-               var dir = new DirectoryInfo(Path.GetTempPath());
-               foreach(var file in dir.EnumerateFiles(
-                                       Constants.PhotoTemp + "-" + videoDevice + "-" + "*" +
-                                       GetMultimediaExtension(Constants.MultimediaItems.PHOTOPNG)))
-                       file.Delete();
-
-               LogB.Information("Deleting temp video");
-               if(File.Exists(GetVideoTempFileName()))
-                       File.Delete(GetVideoTempFileName());
-       }
-       
        public static void DeleteVideo(int sessionID, Constants.TestTypes type, int uniqueID) {
                string fileName = GetVideoFileName(sessionID, type, uniqueID);
                if(File.Exists(fileName)) 
diff --git a/src/webcam.cs b/src/webcam.cs
index 40dc427a..fb0f2d8b 100644
--- a/src/webcam.cs
+++ b/src/webcam.cs
@@ -40,6 +40,9 @@ public abstract class Webcam
 
        protected Process process;
        protected string videoDevice;
+       protected StreamWriter streamWriter;
+       protected string captureExecutable = "";
+
 
        // 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
@@ -88,6 +91,7 @@ public abstract class Webcam
                return Util.ChangeChars(videoDevice, "/", "_");
        }
 
+       protected abstract void deleteTempFiles();
 }
 
 /*
@@ -131,7 +135,8 @@ public class WebcamManage
                //w = new Webcam(preferences.videoDevice);
                LogB.Information("wRS at gui chronojump.cs 0, videoDevice: " + videoDevice);
 
-               w = new WebcamMplayer (videoDevice);
+               //w = new WebcamMplayer (videoDevice);
+               w = new WebcamFfmpeg (videoDevice);
                Webcam.Result result = w.CapturePrepare (Webcam.CaptureTypes.VIDEO);
 
                LogB.Information("wRS at gui chronojump.cs 1, videoDevice: " + videoDevice);
@@ -190,5 +195,4 @@ public class WebcamManage
        {
                return webcam.ExitAndFinish (sessionID, testType, testID);
        }
-
 }
diff --git a/src/webcamFfmpeg.cs b/src/webcamFfmpeg.cs
new file mode 100644
index 00000000..1ad7ac47
--- /dev/null
+++ b/src/webcamFfmpeg.cs
@@ -0,0 +1,162 @@
+/*
+ * 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;
+
+public class WebcamFfmpeg : Webcam
+{
+       public WebcamFfmpeg (string videoDevice)
+       {
+               this.videoDevice = videoDevice;
+               captureExecutable = "ffmpeg";
+               Running = false;
+       }
+
+       /*
+        * constructor for Play
+
+       public WebcamFfmpeg ()
+       {
+       }
+        */
+
+       public override Result CapturePrepare (CaptureTypes captureType)
+       {
+               if(process != null)
+                       return new Result (false, "");
+
+               return new Result (true, "");
+       }
+
+       public override Result Play(string filename)
+       {
+               //only implemented on mplayer
+               return new Result (true, "");
+       }
+       public override bool Snapshot()
+       {
+               //only implemented on mplayer
+               return true;
+       }
+
+       public override Result VideoCaptureStart()
+       {
+               List<string> parameters = new List<string>();
+
+               /*
+                * A) only capture
+                * ffmpeg -y -f v4l2 -framerate 30 -video_size 640x480 -input_format mjpeg -i /dev/video0 
out.mp4
+                *
+                * B) capture while watching delayed video
+                * ffmpeg -f v4l2 -i /dev/video0 -map 0 -c:v libx264 -f tee "output.mkv|[f=nut]pipe:" | 
ffplay pipe:
+                */
+
+               //A)
+               int i = 0;
+               parameters.Insert (i ++, "-y"); //overwrite
+               parameters.Insert (i ++, "-f");
+               parameters.Insert (i ++, "v4l2");
+               parameters.Insert (i ++, "-framerate");
+               parameters.Insert (i ++, "30");
+               parameters.Insert (i ++, "-video_size");
+               parameters.Insert (i ++, "640x480");
+               parameters.Insert (i ++, "-input_format");
+               parameters.Insert (i ++, "mjpeg");
+               parameters.Insert (i ++, "-i");
+               parameters.Insert (i ++, videoDevice);
+               parameters.Insert (i ++, Util.GetVideoTempFileName());
+
+               process = new Process();
+               bool success = ExecuteProcess.RunAtBackground (process, captureExecutable, parameters, true); 
//redirectInput
+               if(! success)
+               {
+                       streamWriter = null;
+                       process = null;
+                       return new Result (false, "", programFfmpegNotInstalled);
+               }
+
+               streamWriter = process.StandardInput;
+               Running = true;
+
+               return new Result (true, "");
+       }
+
+       public override Result VideoCaptureEnd()
+       {
+               //on ffmpeg capture ends on exit: 'q' done at ExitAndFinish()
+               return new Result (true, "");
+       }
+
+
+       public override 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 override void ExitCamera()
+       {
+               LogB.Information("Exit camera");
+               LogB.Information("streamWriter is null: " + (streamWriter == null).ToString());
+               try {
+                       streamWriter.Write('q');
+                       streamWriter.Flush();
+               } catch {
+                       //maybe Mplayer window has been closed by user
+                       process = null;
+                       Running = false;
+                       return;
+               }
+
+               //System.Threading.Thread.Sleep(500);
+               //better check if process still exists to later copy the video
+               do {
+                       LogB.Information("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 override void deleteTempFiles()
+       {
+               LogB.Information("Deleting temp video");
+               if(File.Exists(Util.GetVideoTempFileName()))
+                       File.Delete(Util.GetVideoTempFileName());
+       }
+
+}
diff --git a/src/webcamMplayer.cs b/src/webcamMplayer.cs
index 60c1e14e..ba09d304 100644
--- a/src/webcamMplayer.cs
+++ b/src/webcamMplayer.cs
@@ -25,8 +25,6 @@ using System.IO;
 
 public class WebcamMplayer : Webcam
 {
-       private StreamWriter streamWriter;
-
        public WebcamMplayer (string videoDevice)
        {
                this.videoDevice = videoDevice;
@@ -34,11 +32,12 @@ public class WebcamMplayer : Webcam
        }
 
        /*
-        * constructor for play
+        * constructor for Play
         */
 
        public WebcamMplayer ()
        {
+               captureExecutable = "mplayer";
        }
 
        public override Result CapturePrepare (CaptureTypes captureType)
@@ -49,7 +48,6 @@ public class WebcamMplayer : Webcam
                string tempFile = Util.GetMplayerPhotoTempFileNamePost(videoDeviceToFilename());
                Util.FileDelete(tempFile);
 
-               string executable = "mplayer";
                List<string> parameters = new List<string>();
                //-noborder -nosound -tv 
driver=v4l2:gain=1:width=400:height=400:device=/dev/video0:fps=10:outfmt=rgb16 tv:// -vf 
screenshot=/tmp/chronojump-last-photo
                //parameters.Insert (0, "-noborder"); //on X11 can be: title "Chronojump"". -noborder makes 
no accept 's', or 'q'
@@ -73,7 +71,7 @@ public class WebcamMplayer : Webcam
                parameters.Insert (i ++, "screenshot=" + 
Util.GetMplayerPhotoTempFileNamePre(videoDeviceToFilename()));
 
                process = new Process();
-               bool success = ExecuteProcess.RunAtBackground (process, executable, parameters, true); 
//redirectInput
+               bool success = ExecuteProcess.RunAtBackground (process, captureExecutable, parameters, true); 
//redirectInput
                if(! success)
                {
                        streamWriter = null;
@@ -89,7 +87,7 @@ public class WebcamMplayer : Webcam
                   parametersB[4] = 
"driver=v4l2:gain=1:width=400:height=400:device=/dev/video1:fps=10:outfmt=rgb16";
                   parametersB[7] = "screenshot=/tmp/b/chronojump-last-photo";
                   Process processB = new Process();
-                  ExecuteProcess.RunAtBackground (processB, executable, parametersB, true); //redirectInput
+                  ExecuteProcess.RunAtBackground (processB, captureExecutable, parametersB, true); 
//redirectInput
                   */
                /*
                 * experimental double camera end
@@ -97,8 +95,8 @@ public class WebcamMplayer : Webcam
 
 
                streamWriter = process.StandardInput;
-
                Running = true;
+
                return new Result (true, "");
        }
 
@@ -190,7 +188,7 @@ public class WebcamMplayer : Webcam
                        return new Result (false, "", Constants.FileCopyProblem);
 
                //Delete temp photos and video
-               Util.DeleteTempPhotosAndVideo(videoDeviceToFilename());
+               deleteTempFiles();
 
                return new Result (true, "");
        }
@@ -213,6 +211,24 @@ public class WebcamMplayer : Webcam
                Running = false;
        }
 
+       /*
+        * protected methods
+        */
+
+       protected override void deleteTempFiles()
+       {
+               LogB.Information("Deleting temp files");
+               var dir = new DirectoryInfo(Path.GetTempPath());
+               foreach(var file in dir.EnumerateFiles(
+                                       Constants.PhotoTemp + "-" + videoDeviceToFilename() + "-" + "*" +
+                                       Util.GetMultimediaExtension(Constants.MultimediaItems.PHOTOPNG)))
+                       file.Delete();
+
+               LogB.Information("Deleting temp video");
+               if(File.Exists(Util.GetVideoTempFileName()))
+                       File.Delete(Util.GetVideoTempFileName());
+       }
+
        /*
         * private methods
         */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]