[chronojump] webcam: Big refactorization on GetDevices. Should work on all systems.



commit 8d26a1d6908ecbf44ad4a010911dcdd6170c1495
Author: Xavier de Blas <xaviblas gmail com>
Date:   Fri Apr 5 13:24:13 2019 +0200

    webcam: Big refactorization on GetDevices. Should work on all systems.

 glade/preferences_win.glade |   1 -
 src/constants.cs            |   1 +
 src/gui/preferences.cs      |   9 +-
 src/utilMultimedia.cs       |   6 +-
 src/webcamFfmpegDevices.cs  | 271 ++++++++++++++++++++++++++------------------
 5 files changed, 174 insertions(+), 114 deletions(-)
---
diff --git a/glade/preferences_win.glade b/glade/preferences_win.glade
index c366d83d..f1e0fc0d 100644
--- a/glade/preferences_win.glade
+++ b/glade/preferences_win.glade
@@ -3402,7 +3402,6 @@ Other</property>
                     <child>
                       <widget class="GtkLabel" id="label_no_cameras">
                         <property name="can_focus">False</property>
-                        <property name="label" translatable="yes">Sorry, no cameras found.</property>
                       </widget>
                       <packing>
                         <property name="expand">True</property>
diff --git a/src/constants.cs b/src/constants.cs
index f6749108..d897fd51 100644
--- a/src/constants.cs
+++ b/src/constants.cs
@@ -743,6 +743,7 @@ public class Constants
        public static string RunStartInitialSpeedNo = Catalog.GetString("Standing start. Started without 
initial speed.");
        
        public static string CameraNotFound = Catalog.GetString("Sorry, no cameras found.");
+       public static string FfmpegNotInstalled = "Software ffmpeg is not installed, please check 
instructions on chronojump website (software page)";
        
        public enum BellModes {
                JUMPS, RUNS, ENCODERGRAVITATORY, ENCODERINERTIAL
diff --git a/src/gui/preferences.cs b/src/gui/preferences.cs
index 98c64433..a658edff 100644
--- a/src/gui/preferences.cs
+++ b/src/gui/preferences.cs
@@ -583,17 +583,20 @@ public class PreferencesWindow
         * end of triggers stuff
         */
 
-       private void createComboCamera(List<string> devices, string current) {
+       private void createComboCamera(WebcamDeviceList wd_list, string current)
+       {
                combo_camera = ComboBox.NewText ();
 
-               if(devices.Count == 0) {
+               if(wd_list.Count() == 0) {
                        //devices = Util.StringToStringArray(Constants.CameraNotFound);
+                       label_no_cameras.Text = wd_list.Error;
                        label_no_cameras.Visible = true;
                        current = "";
                        return;
                }
                
-               UtilGtk.ComboUpdate(combo_camera, devices);
+               UtilGtk.ComboUpdate(combo_camera, wd_list.GetCodes());
+               //UtilGtk.ComboUpdate(combo_camera, wd_list.GetFullnames());
                hbox_combo_camera.PackStart(combo_camera, true, true, 0);
                hbox_combo_camera.ShowAll();
 
diff --git a/src/utilMultimedia.cs b/src/utilMultimedia.cs
index 9330cab7..b8a4d161 100644
--- a/src/utilMultimedia.cs
+++ b/src/utilMultimedia.cs
@@ -34,7 +34,7 @@ public class UtilMultimedia
         * VIDEO
         */
 
-       public static List<string> GetVideoDevices ()
+       public static WebcamDeviceList GetVideoDevices ()
        {
                WebcamFfmpegGetDevices w;
 
@@ -45,7 +45,9 @@ public class UtilMultimedia
                else
                        w = new WebcamFfmpegGetDevicesMac();
 
-               return w.GetDevices();
+               WebcamDeviceList wd_list = w.GetDevices();
+
+               return wd_list;
        }
 
 
diff --git a/src/webcamFfmpegDevices.cs b/src/webcamFfmpegDevices.cs
index 162ce5e2..c7ab69aa 100644
--- a/src/webcamFfmpegDevices.cs
+++ b/src/webcamFfmpegDevices.cs
@@ -25,24 +25,113 @@ using System.IO;
 using System.Text.RegularExpressions; //Regex
 
 
+public class WebcamDevice
+{
+       //on mac it is returned a code and a device, like:
+       //[0] FaceTime HD Camera        //this is the webcam
+       //[1] Capture screen 0          //this is to screencapture
+       //
+       //on Linux it is returned a filename (it will be the code)
+       //
+       //on windows ...
+       //
+       //object is a device and fullname
+       private string code;
+       private string fullname;
+
+       public WebcamDevice(string code, string fullname)
+       {
+               this.code = code;
+               this.fullname = fullname;
+       }
+
+       public string Code
+       {
+               get { return code; }
+       }
+
+       public string Fullname
+       {
+               get { return fullname; }
+       }
+}
+
+public class WebcamDeviceList
+{
+       private List<WebcamDevice> wd_list;
+       public string Error;
+
+       // constructors
+
+       public WebcamDeviceList()
+       {
+               Error = "";
+               wd_list = new List<WebcamDevice>();
+       }
+
+       public WebcamDeviceList(List<WebcamDevice> wd_list)
+       {
+               Error = "";
+               this.wd_list = wd_list;
+       }
+
+       // public methods
+
+       public void Add(WebcamDevice wd)
+       {
+               wd_list.Add(wd);
+       }
+
+       public int Count()
+       {
+               return wd_list.Count;
+       }
+
+       public List<string> GetCodes()
+       {
+               List<string> l = new List<string>();
+               foreach(WebcamDevice wd in wd_list)
+                       l.Add(wd.Code);
+
+               return l;
+       }
+
+       public List<string> GetFullnames()
+       {
+               List<string> l = new List<string>();
+               foreach(WebcamDevice wd in wd_list)
+                       l.Add(wd.Fullname);
+
+               return l;
+       }
+}
+
 public abstract class WebcamFfmpegGetDevices
 {
-       public abstract List<string> GetDevices();
+       //protected List<WebcamDevice> webcamDevice;
+       protected WebcamDeviceList wd_list;
 
-       protected abstract List<string> createParameters();
+       //update codes and names lists
+       public abstract WebcamDeviceList GetDevices();
 
-       protected abstract List<string> parse(string devicesOutput);
+       protected void initialize ()
+       {
+               LogB.Information(" called initialize ");
+               wd_list = new WebcamDeviceList();
+       }
 }
 
 public class WebcamFfmpegGetDevicesLinux : WebcamFfmpegGetDevices
 {
        public WebcamFfmpegGetDevicesLinux()
        {
+               initialize();
        }
 
-       public override List<string> GetDevices()
+       public override WebcamDeviceList GetDevices()
        {
-               List<string> list = new List<string>();
+               LogB.Information("GetDevices");
+               LogB.Information(string.Format("wd_list is null: ", wd_list == null));
                string prefix = "/dev/";
                var dir = new DirectoryInfo(prefix);
                foreach(var file in dir.EnumerateFiles("video*"))
@@ -53,32 +142,25 @@ public class WebcamFfmpegGetDevicesLinux : WebcamFfmpegGetDevices
                         list.Add(Convert.ToInt32(file.Name[5]));                       //0 or 1, or ...
                         */
                        //return "/dev/video0", "/dev/video1", ...
-                       list.Add(prefix + file.Name);
+                       wd_list.Add(new WebcamDevice(
+                                               prefix + file.Name,
+                                               prefix + file.Name + " default camera"));
 
-               return list;
-       }
-
-       protected override List<string> createParameters()
-       {
-               return new List<string>();
-       }
-
-       protected override List<string> parse(string devicesOutput)
-       {
-               return new List<string>();
+               return wd_list;
        }
 }
 
-
-public class WebcamFfmpegGetDevicesWindows : WebcamFfmpegGetDevices
+//Windows and mac share similar behaviour on ffmpeg get devices
+public abstract class WebcamFfmpegGetDevicesWinMac : WebcamFfmpegGetDevices
 {
-       public WebcamFfmpegGetDevicesWindows()
-       {
-       }
+       protected string executable;
+       protected string videoDevString;
+       protected string audioDevString;
 
-       public override List<string> GetDevices()
+       protected abstract List<string> createParameters();
+
+       public override WebcamDeviceList GetDevices()
        {
-               string executable = System.IO.Path.Combine(Util.GetPrefixDir(), "bin/ffmpeg.exe");
                List<string> parameters = createParameters();
 
                ExecuteProcess.Result execute_result = ExecuteProcess.run (executable, parameters, true, 
true);
@@ -89,52 +171,48 @@ public class WebcamFfmpegGetDevicesWindows : WebcamFfmpegGetDevices
                LogB.Information(execute_result.stderr);
                LogB.Information("-----------------");
 
+               LogB.Information("pre");
                if(! execute_result.success)
                {
-                       LogB.Information("WebcamFfmpegGetDevicesWindows error: " + execute_result.stderr);
+                       LogB.Information("no success");
+                       if( ! executableExists())
+                       {
+                               LogB.Information(string.Format("File {0} does not exists, but note execuble 
can be on path", executable));
+                               wd_list.Error = Constants.FfmpegNotInstalled;
+                               return wd_list;
+                       }
 
                        /*
                         * on Windows the -i dummy produces an error, so stderr exists and success is false
+                        * on Mac the -i "" 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
+                        * check if in stdout there's the: videoDevString and if not exists, really we have 
an error
                         */
                        if(execute_result.stdout != null && execute_result.stdout != "" &&
-                                       execute_result.stdout.Contains("DirectShow video devices"))
+                                       execute_result.stdout.Contains(videoDevString))
                        {
                                LogB.Information("Calling parse with stdout");
-                               return parse(execute_result.stdout);
+                               parse(execute_result.stdout);
+                               return wd_list;
                        }
 
                        if(execute_result.stderr != null && execute_result.stderr != "" &&
-                                       execute_result.stderr.Contains("DirectShow video devices"))
+                                       execute_result.stderr.Contains(videoDevString))
                        {
                                LogB.Information("Calling parse with stderr");
-                               return parse(execute_result.stderr);
+                               parse(execute_result.stderr);
+                               return wd_list;
                        }
 
-                       return new List<string>();
+                       wd_list.Error = Constants.CameraNotFound;
                }
                else
-                       return parse(execute_result.stdout);
-       }
-
-       protected override List<string> createParameters()
-       {
-               //ffmpeg -list_devices true -f dshow -i dummy
-               List<string> parameters = new List<string>();
+                       parse(execute_result.stdout);
 
-               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;
+               return wd_list;
        }
 
-       protected override List<string> parse(string devicesOutput)
+       protected void parse(string devicesOutput)
        {
                LogB.Information("Called parse");
 
@@ -147,7 +225,6 @@ public class WebcamFfmpegGetDevicesWindows : WebcamFfmpegGetDevices
                                StringSplitOptions.None
                                );
 
-               List<string> parsedList = new List<string>();
                foreach(string l in lines)
                {
                        LogB.Information("line: " + l);
@@ -157,48 +234,60 @@ public class WebcamFfmpegGetDevicesWindows : WebcamFfmpegGetDevices
                                string s = match.ToString().Substring(1, match.ToString().Length -2);
 
                                LogB.Information("add match: " + s);
-                               parsedList.Add(s);
+                               if(s.Length < 3)
+                                       break;
+
+                               wd_list.Add(new WebcamDevice(s[1].ToString(), s)); //code will be char 1: 
"[0] my device"
                        }
 
                        //after the list of video devices comes the list of audio devices, skip it
-                       if(l.Contains("DirectShow audio devices"))
+                       if(l.Contains(audioDevString))
                                break;
                }
+       }
 
-               return parsedList;
+       protected bool executableExists()
+       {
+               return File.Exists(executable);
        }
+
 }
 
-public class WebcamFfmpegGetDevicesMac : WebcamFfmpegGetDevices
+public class WebcamFfmpegGetDevicesWindows : WebcamFfmpegGetDevicesWinMac
 {
-       public WebcamFfmpegGetDevicesMac()
+       public WebcamFfmpegGetDevicesWindows()
        {
+               initialize();
+               executable = System.IO.Path.Combine(Util.GetPrefixDir(), "bin/ffmpeg.exe");
+               videoDevString = "DirectShow video devices";
+               audioDevString = "DirectShow audio devices";
        }
 
-       public override List<string> GetDevices()
+       protected override List<string> createParameters()
        {
-               string executable = "ffmpeg";
-               List<string> parameters = createParameters();
-
-               ExecuteProcess.Result execute_result = ExecuteProcess.run (executable, parameters, true, 
true);
+               //ffmpeg -list_devices true -f dshow -i dummy
+               List<string> parameters = new List<string>();
 
-               LogB.Information("---- stdout: ----");
-               LogB.Information(execute_result.stdout);
-               LogB.Information("---- stderr: ----");
-               LogB.Information(execute_result.stderr);
-               LogB.Information("-----------------");
+               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");
 
-               if(! execute_result.success)
-               {
-                       /*
-                       LogB.Information("WebcamFfmpegGetDevicesMac stdout: " + execute_result.stdout);
-                       LogB.Information("WebcamFfmpegGetDevicesMac error: " + execute_result.stderr);
-                       */
+               return parameters;
+       }
+}
 
-                       return new List<string>();
-               }
-               else
-                       return parse(execute_result.stdout);
+public class WebcamFfmpegGetDevicesMac : WebcamFfmpegGetDevicesWinMac
+{
+       public WebcamFfmpegGetDevicesMac()
+       {
+               initialize();
+               executable = "ffmpeg";
+               videoDevString = "AVFoundation video devices";
+               audioDevString = "AVFoundation audio devices";
        }
 
        protected override List<string> createParameters()
@@ -217,38 +306,4 @@ public class WebcamFfmpegGetDevicesMac : WebcamFfmpegGetDevices
 
                return parameters;
        }
-
-       protected override List<string> parse(string devicesOutput)
-       {
-               LogB.Information("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)
-               {
-                       LogB.Information("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);
-
-                               LogB.Information("add match: " + s);
-                               parsedList.Add(s);
-                       }
-
-                       //after the list of video devices comes the list of audio devices, skip it
-                       if(l.Contains("AVFoundation audio devices"))
-                               break;
-               }
-
-               return parsedList;
-       }
 }


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