[chronojump] Video capture/play with mplayer and ffmpeg for jumps, jumpsRj



commit 9663d916fadd6e9ed2333db81b1db6dfe7681024
Author: Xavier de Blas <xaviblas gmail com>
Date:   Tue Jul 17 13:07:42 2018 +0200

    Video capture/play with mplayer and ffmpeg for jumps, jumpsRj

 src/constants.cs      |   3 +-
 src/gui/chronojump.cs |  30 ++++++++-----
 src/gui/person.cs     |   4 +-
 src/util.cs           |  15 +++++++
 src/webcam.cs         | 121 +++++++++++++++++++++++++++++++++++++++++++++-----
 5 files changed, 149 insertions(+), 24 deletions(-)
---
diff --git a/src/constants.cs b/src/constants.cs
index 6113ca6d..494df3c5 100644
--- a/src/constants.cs
+++ b/src/constants.cs
@@ -724,7 +724,8 @@ public class Constants
        public enum MultimediaItems {
                PHOTO, PHOTOPNG, VIDEO
        }
-       public const string ExtensionVideo = ".avi";
+       //public const string ExtensionVideo = ".avi";
+       public const string ExtensionVideo = ".mp4";
        public const string ExtensionPhoto = ".jpg";
        public const string ExtensionPhotoPng = ".png"; //used for Cairo resized images
        public const string SmallPhotoDir = "small";
diff --git a/src/gui/chronojump.cs b/src/gui/chronojump.cs
index 413216ed..306d4d1e 100644
--- a/src/gui/chronojump.cs
+++ b/src/gui/chronojump.cs
@@ -4209,6 +4209,8 @@ public partial class ChronoJumpWindow
         */
 
        
+       Webcam webcam;
+
        //suitable for all jumps not repetitive
        private void on_normal_jump_activate (bool canCaptureC)
        {
@@ -4291,6 +4293,9 @@ public partial class ChronoJumpWindow
 
                //UtilGtk.ChronopicColors(viewport_chronopics, label_chronopics, label_connected_chronopics, 
chronopicWin.Connected);
 
+               webcam = new Webcam();
+               Webcam.Result result = webcam.MplayerCapture();
+               webcam.RecordStart();
 
                if (! canCaptureC)
                        currentEventExecute.SimulateInitValues(rand);
@@ -4330,12 +4335,6 @@ public partial class ChronoJumpWindow
                                                currentJump.UniqueID, currentJump.Description);
                        }
 
-                       //move video file if exists
-                       if(preferences.videoOn)
-                               if (! Util.CopyTempVideo(currentSession.UniqueID, Constants.TestTypes.JUMP, 
currentJump.UniqueID))
-                                       new DialogMessage(Constants.MessageTypes.WARNING, 
-                                                       Catalog.GetString("Sorry, video cannot be stored."));
-
                        myTreeViewJumps.PersonWeight = currentPersonSession.Weight;
                        myTreeViewJumps.Add(currentPerson.Name, currentJump);
                        
@@ -4361,6 +4360,10 @@ public partial class ChronoJumpWindow
                        execute_auto_select();
                        sensitiveGuiAutoExecuteOrWait (false);
                }
+
+               if(! webcam.RecordEnd (currentSession.UniqueID, Constants.TestTypes.JUMP, 
currentJump.UniqueID))
+                       new DialogMessage(Constants.MessageTypes.WARNING,
+                                       Catalog.GetString("Sorry, video cannot be stored."));
        }
 
        private void chronopicDisconnectedWhileExecuting() {
@@ -4594,6 +4597,9 @@ public partial class ChronoJumpWindow
                                repetitiveConditionsWin, progressbarLimit, egd
                                );
                
+               webcam = new Webcam();
+               Webcam.Result result = webcam.MplayerCapture();
+               webcam.RecordStart();
                
                //suitable for limited by jump and time
                //simulated always simulate limited by jumps
@@ -4618,11 +4624,6 @@ public partial class ChronoJumpWindow
                if ( ! currentEventExecute.Cancel ) {
                        currentJumpRj = (JumpRj) currentEventExecute.EventDone;
                        
-                       //move video file if exists
-                       if(preferences.videoOn)
-                               if(! Util.CopyTempVideo(currentSession.UniqueID, Constants.TestTypes.JUMP_RJ, 
currentJumpRj.UniqueID))
-                                       new DialogMessage(Constants.MessageTypes.WARNING, 
Catalog.GetString("Sorry, video cannot be stored."));
-
                        //if user clicked in finish earlier
                        if(currentEventExecute.Finish) {
                                currentJumpRj.Jumps = Util.GetNumberOfJumps(currentJumpRj.TvString, false);
@@ -4659,6 +4660,10 @@ public partial class ChronoJumpWindow
                
                //delete the temp tables if exists
                Sqlite.DeleteTempEvents("tempJumpRj");
+
+               if(! webcam.RecordEnd (currentSession.UniqueID, Constants.TestTypes.JUMP_RJ, 
currentJumpRj.UniqueID))
+                       new DialogMessage(Constants.MessageTypes.WARNING,
+                                       Catalog.GetString("Sorry, video cannot be stored."));
        }
 
        /* ---------------------------------------------------------
@@ -5923,6 +5928,9 @@ LogB.Debug("X");
        //Not used on encoder   
        private bool playVideo(string fileName, bool play) 
        {
+               webcam = new Webcam();
+               Webcam.Result result = webcam.MplayerPlay(fileName);
+
                /*
                 * TODO: reimplement this with ffmpeg
                 *
diff --git a/src/gui/person.cs b/src/gui/person.cs
index 9238e298..0520d7c2 100644
--- a/src/gui/person.cs
+++ b/src/gui/person.cs
@@ -1081,7 +1081,7 @@ public class PersonAddModifyWindow
 
                // B) start if it's not running
                webcam = new Webcam();
-               Webcam.Result result = webcam.MplayerCall();
+               Webcam.Result result = webcam.MplayerCapture();
                if (! result.success)
                {
                        LogB.Debug ("Webcam Mplayer error: ", result.error);
@@ -1137,7 +1137,7 @@ public class PersonAddModifyWindow
                if(webcam == null)
                        return;
 
-               if(webcam.DoSnapshot())
+               if(webcam.Snapshot())
                {
                        File.Copy(Util.GetMplayerPhotoTempFileNamePost(), Util.GetPhotoPngFileName(false, 
currentPerson.UniqueID), true); //overwrite
 
diff --git a/src/util.cs b/src/util.cs
index 2964198c..5011b03c 100644
--- a/src/util.cs
+++ b/src/util.cs
@@ -1027,6 +1027,8 @@ public class Util
                }
        }
 
+//TODO: now using mp4, ensure old avi can be also retrieved
+
        //returns absolute path, but in encoder this URL is stored in database as relative to be able to move 
data between computers
        //see SqliteEncoder.removeURLpath
        public static string GetVideoFileName (int sessionID, Constants.TestTypes testType, int uniqueID) {
@@ -1140,6 +1142,19 @@ public class Util
                } else
                        return false;
        }
+
+       public static void DeleteTempPhotosAndVideo()
+       {
+               LogB.Information("Deleting temp files");
+               var dir = new DirectoryInfo(Path.GetTempPath());
+               foreach(var file in dir.EnumerateFiles(Constants.PhotoTemp + "*" +
+                                       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);
diff --git a/src/webcam.cs b/src/webcam.cs
index ef6c5d31..3cedd1ac 100644
--- a/src/webcam.cs
+++ b/src/webcam.cs
@@ -47,12 +47,20 @@ class Webcam
                }
        }
 
+       /*
+        * constructor
+        */
+
        public Webcam()
        {
                Running = false;
        }
 
-       public Result MplayerCall()
+       /*
+        * public methods
+        */
+
+       public Result MplayerCapture()
        {
                if(process != null)
                        return new Result (false, "");
@@ -63,7 +71,7 @@ class Webcam
                //TODO: check /dev/video0 or video1 or nothing
                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/ChronojumpPhoto
+               //-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'
                parameters.Insert (1, "-nosound");
                parameters.Insert (2, "-tv");
@@ -82,18 +90,43 @@ class Webcam
                }
 
                streamWriter = process.StandardInput;
+
+               Running = true;
+               return new Result (true, "");
+       }
+
+       public Result MplayerPlay(string filename)
+       {
+               if(process != null || filename == "")
+                       return new Result (false, "");
+
+               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/ChronojumpPhoto
+               parameters.Insert (0, filename);
+               //parameters.Insert (0, "-noborder"); //on X11 can be: title "Chronojump"". -noborder makes 
no accept 's', or 'q'
+
+               process = new Process();
+               bool success = ExecuteProcess.RunAtBackground (process, executable, parameters, false);
+               if(! success)
+               {
+                       process = null;
+                       return new Result (false, "", Constants.MplayerNotInstalled);
+               }
+
                Running = true;
                return new Result (true, "");
        }
 
-       public bool DoSnapshot()
+
+       public bool Snapshot()
        {
                if(process == null || streamWriter == null)
                        return false;
 
                bool exitAtFirstSnapshot = true;
 
-               if(! doSnapshot())
+               if(! snapshotDo())
                        return false;
 
                if(exitAtFirstSnapshot)
@@ -105,14 +138,39 @@ class Webcam
                return true;
        }
 
-       private bool doSnapshot()
+       public bool RecordStart()
        {
-               try {
-                       streamWriter.Write('s');
-               } catch {
-                       //maybe Mplayer window has been closed by user
+               if(process == null || streamWriter == null)
                        return false;
-               }
+
+               if(! recordStartOrEndDo())
+                       return false;
+
+               return true;
+       }
+
+       public bool RecordEnd(int sessionID, Constants.TestTypes testType, int testID)
+       {
+               if(process == null || streamWriter == null)
+                       return false;
+
+               //System.Threading.Thread.Sleep(2000); //TODO: play with this to see if cut better video at 
end
+               if(! recordStartOrEndDo())
+                       return false;
+
+               ExitCamera();
+
+               //Convert video to the name and format expected
+               if(! convertImagesToVideo())
+                       return false;
+
+               //Copy the video to expected place
+               if (! Util.CopyTempVideo(sessionID, testType, testID))
+                       return false;
+
+               //Delete temp photos and video
+               Util.DeleteTempPhotosAndVideo();
+
                return true;
        }
 
@@ -133,4 +191,47 @@ class Webcam
                process = null;
                Running = false;
        }
+
+       /*
+        * private methods
+        */
+
+       private bool snapshotDo()
+       {
+               try {
+                       streamWriter.Write('s');
+               } catch {
+                       //maybe Mplayer window has been closed by user
+                       return false;
+               }
+               return true;
+       }
+
+       private bool recordStartOrEndDo()
+       {
+               try {
+                       streamWriter.Write('S');
+               } catch {
+                       //maybe Mplayer window has been closed by user
+                       return false;
+               }
+               return true;
+       }
+
+       private bool convertImagesToVideo()
+       {
+               string executable = "ffmpeg";
+               List<string> parameters = new List<string>();
+               //ffmpeg -framerate 20 -y -i chronojump-last-photo%04d.png output.mp4
+               parameters.Insert (0, "-framerate");
+               parameters.Insert (1, "20");
+               parameters.Insert (2, "-y"); //force overwrite without asking
+               parameters.Insert (3, "-i"); //input files
+               parameters.Insert (4, Util.GetMplayerPhotoTempFileNamePre() + "%04d.png");
+               parameters.Insert (5, Util.GetVideoTempFileName());
+
+               ExecuteProcess.Result execute_result = ExecuteProcess.run (executable, parameters);
+               return execute_result.success;
+       }
+
 }


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