chiark / gitweb /
Fix timelaps recording support
[cura.git] / Cura / gui / webcam.py
1 import os, glob, subprocess, platform\r
2 import wx\r
3 \r
4 try:\r
5         #Try to find the OpenCV library for video capture.\r
6         from opencv import cv\r
7         from opencv import highgui\r
8 except:\r
9         cv = None\r
10 \r
11 try:\r
12         #Use the vidcap library directly from the VideoCapture package. (Windows only)\r
13         #       http://videocapture.sourceforge.net/\r
14         # We're using the binary interface, not the python interface, so we don't depend on PIL\r
15         import vidcap as win32vidcap\r
16 except:\r
17         win32vidcap = None\r
18 \r
19 def hasWebcamSupport():\r
20         if cv == None and win32vidcap == None:\r
21                 return False\r
22         if not os.path.exists(getFFMPEGpath()):\r
23                 return False\r
24         return True\r
25 \r
26 def getFFMPEGpath():\r
27         if platform.system() == "Windows":\r
28                 return os.path.normpath(os.path.join(os.path.split(__file__)[0], "../ffmpeg.exe"))\r
29         elif os.path.exists('/usr/bin/ffmpeg'):\r
30                 return '/usr/bin/ffmpeg'\r
31         return os.path.normpath(os.path.join(os.path.split(__file__)[0], "../ffmpeg"))\r
32 \r
33 class webcam(object):\r
34         def __init__(self):\r
35                 self._cam = None\r
36                 if cv != None:\r
37                         self._cam = highgui.cvCreateCameraCapture(-1)\r
38                 elif win32vidcap != None:\r
39                         try:\r
40                                 self._cam = win32vidcap.new_Dev(0, False)\r
41                         except:\r
42                                 pass\r
43                 \r
44                 self._doTimelaps = False\r
45                 self._bitmap = None\r
46         \r
47         def hasCamera(self):\r
48                 return self._cam != None\r
49         \r
50         def propertyPages(self):\r
51                 if self._cam == None:\r
52                         return []\r
53                 if win32vidcap != None:\r
54                         return ['Image properties', 'Format properties']\r
55                 if cv != None:\r
56                         #TODO Make an OpenCV property page\r
57                         return []\r
58 \r
59         def openPropertyPage(self, pageType = 0):\r
60                 if self._cam == None:\r
61                         return\r
62                 if win32vidcap != None:\r
63                         if pageType == 0:\r
64                                 self._cam.displaycapturefilterproperties()\r
65                         else:\r
66                                 self._cam.displaycapturepinproperties()\r
67         \r
68         def takeNewImage(self):\r
69                 if self._cam == None:\r
70                         return\r
71                 if cv != None:\r
72                         frame = cv.QueryFrame(self._cam)\r
73                         cv.CvtColor(frame, frame, cv.CV_BGR2RGB)\r
74                         self._bitmap = wx.BitmapFromBuffer(frame.width, frame.height, frame.imageData)\r
75                 elif win32vidcap != None:\r
76                         buffer, width, height = self._cam.getbuffer()\r
77                         wxImage = wx.EmptyImage(width, height)\r
78                         wxImage.SetData(buffer[::-1])\r
79                         if self._bitmap != None:\r
80                                 del self._bitmap\r
81                         self._bitmap = wxImage.ConvertToBitmap()\r
82                         del wxImage\r
83                         del buffer\r
84 \r
85                 if self._doTimelaps:\r
86                         filename = os.path.normpath(os.path.join(os.path.split(__file__)[0], "../__tmp_snap", "__tmp_snap_%04d.jpg" % (self._snapshotCount)))\r
87                         self._snapshotCount += 1\r
88                         self._bitmap.SaveFile(filename, wx.BITMAP_TYPE_JPEG)\r
89 \r
90                 return self._bitmap\r
91         \r
92         def getLastImage(self):\r
93                 return self._bitmap\r
94         \r
95         def startTimelaps(self, filename):\r
96                 if self._cam == None:\r
97                         return\r
98                 self._cleanTempDir()\r
99                 self._timelapsFilename = filename\r
100                 self._snapshotCount = 0\r
101                 self._doTimelaps = True\r
102                 print "startTimelaps"\r
103         \r
104         def endTimelaps(self):\r
105                 if self._doTimelaps:\r
106                         ffmpeg = getFFMPEGpath()\r
107                         basePath = os.path.normpath(os.path.join(os.path.split(__file__)[0], "../__tmp_snap", "__tmp_snap_%04d.jpg"))\r
108                         subprocess.call([ffmpeg, '-r', '12.5', '-i', basePath, '-vcodec', 'mpeg2video', '-pix_fmt', 'yuv420p', '-r', '25', '-y', '-b:v', '1500k', '-f', 'vob', self._timelapsFilename])\r
109                 self._doTimelaps = False\r
110         \r
111         def _cleanTempDir(self):\r
112                 basePath = os.path.normpath(os.path.join(os.path.split(__file__)[0], "../__tmp_snap"))\r
113                 try:\r
114                         os.makedirs(basePath)\r
115                 except:\r
116                         pass\r
117                 for filename in glob.iglob(basePath + "/*.jpg"):\r
118                         os.remove(filename)\r