[chronojump] Video capture/play with mplayer and ffmpeg for jumps, jumpsRj
- From: Xavier de Blas <xaviblas src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [chronojump] Video capture/play with mplayer and ffmpeg for jumps, jumpsRj
- Date: Tue, 17 Jul 2018 11:10:55 +0000 (UTC)
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]