Screen capture, recording, casting B - 2020
Continuing the screen recording from the previous chapter (, this time, we want to record only an active screen not the whole screen of a desktop running Ubuntu 13.1.
We'll use the FFmpeg's x11grab, a module for screen capture. This method known for giving the best results for capturing screen and is one of the the most flexible methods. It allows us to use a variety of inputs and output formats.
The following command will give us information about the currently active window:
$ xwininfo -id $(xprop -root | awk '/_NET_ACTIVE_WINDOW\(WINDOW\)/{print $NF}')
xwininfo can be used interactively. If we type in xwininfo on a terminal, it will prompt a request for our selection:
Please select the window about which you would like information by clicking the mouse in that window.
If we choose a window, it will give us lots of information about the selected window:
$ xwininfo xwininfo: Please select the window about which you would like information by clicking the mouse in that window. xwininfo: Window id: 0x402a18c "How to grab the desktop with FFmpeg " Absolute upper-left X: 94 Absolute upper-left Y: 337 Relative upper-left X: 0 Relative upper-left Y: 0 Width: 1272 Height: 605 Depth: 24 Visual: 0x21 Visual Class: TrueColor Border width: 0 Class: InputOutput Colormap: 0x20 (installed) Bit Gravity State: NorthWestGravity Window Gravity State: NorthWestGravity Backing Store State: NotUseful Save Under State: no Map State: IsViewable Override Redirect State: no Corners: +94+337 -0+337 -0--174 +94--174 -geometry 1272x605-0+337
We want to extract two information: top-left coordinates and width/height.
However, we can still use the xwininfo interactively with a pipe. The following command will wait for us to specify the window we want:
$ xwininfo | grep -e Width -e Height -e Absolute
Once we select the window, it gives us only the information we want to extract:
$ xwininfo | grep -e Width -e Height -e Absolute Absolute upper-left X: 66 Absolute upper-left Y: 52 Width: 1262 Height: 686
As shown in the example below, we can use the information from xwininfo, and make ffmpeg to get the right area to grab:
$ ffmpeg -video_size 798x400 -framerate 25 -f x11grab -i :0.0+492,210 -an xwininfo.mp4
Here is the code : scrcap.py:
# This code runs the following awk to get a window id for the currently active X11 window # xwininfo -id $(xprop -root | awk '/_NET_ACTIVE_WINDOW\(WINDOW\)/{print $NF}') # ffmpeg -video_size $resolution -framerate 25 -f x11grab # -i :0.0+originX,originY -f alsa -ac 2 -i pulse capture.mp4 import subprocess def capture(): origin, resolution = getWindowGeometry() originScreen = ':0.0+' + origin[0] + ',' + origin[1] cmd = ['ffmpeg','-video_size',resolution,'-framerate','25', '-f','x11grab','-i',originScreen,'-f', 'alsa','-ac','2','-i','pulse','capture.mp4'] cmd = map(lambda x: str(x), cmd) subprocess.call(cmd) def getWindowGeometry(): info = py_xwininfo() valid_info = [] winDict = {} for item in info.split('\n'): if item.count(':') == 1: (key, value) = item.split(':') winDict[key.strip()] = value.strip() origin = [] origin.append(winDict['Absolute upper-left X']) origin.append(winDict['Absolute upper-left Y']) width = winDict['Width'] height = winDict['Height'] if int(width) % 2 != 0: width = int(width) + 1 if int(height) % 2 != 0: height = int(height) + 1 resolution = str(width) + 'x' + str(height) return origin, resolution def py_xwininfo(): winId = getCurrentWinId() cmd = ['xwininfo','-id', winId] cmd = map(lambda x: str(x), cmd) p = subprocess.Popen(cmd, stdout = subprocess.PIPE) return p.communicate()[0] def getCurrentWinId(): cmd_1 = ['xprop', '-root'] cmd_2 = ['awk', '/_NET_ACTIVE_WINDOW\(WINDOW\)/{print $NF}'] p1 = subprocess.Popen(cmd_1, stdout = subprocess.PIPE) p2 = subprocess.Popen(cmd_2, stdin = p1.stdout, stdout=subprocess.PIPE) id = p2.communicate()[0] return id if __name__ == '__main__': origin, resolution = getWindowGeometry() print 'resolution = %s' %resolution print 'origin = %s' %origin capture()
The problem of the code is it always gets the capture for the terminal where we run the python code. So, we need to give the users a room for putting their selection of the window to capture.
Python needs to be able to capture mouse event before it captures screen.
Coming - capture with Python & OpenCV...
Ph.D. / Golden Gate Ave, San Francisco / Seoul National Univ / Carnegie Mellon / UC Berkeley / DevOps / Deep Learning / Visualization