86 lines
4.7 KiB
Plaintext
86 lines
4.7 KiB
Plaintext
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
|
X11 Desktop + Camera Capture with ffmpeg
|
|
````````````````````````````````````````````````
|
|
This document is my minimalistic approach to recording my X11 desktop and camera simultaneously on Linux. The ``ffmpeg`` commands in this document use mouse following, as my multi-monitor setup is rather large and leaves some dead-space. Additionally, we want minimal processing, but not enormous files -- hence, we use x264 with minimal, near-lossless, encoding. Finally, we want to record at one frame per second so we can effectively timelapse 60 seconds into 1 second at 60 frames per second.
|
|
|
|
Do not expect a UI or anything of the sort. This is a hands-on approach using shell scripting. I prefer this.
|
|
|
|
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
|
Desktop Recording: The Command
|
|
````````````````````````````````
|
|
The basic command we want to issue is:
|
|
|
|
#ffmpeg -f x11grab -follow_mouse 428 -draw_mouse 1 -r 1 -video_size 1280x720 -i :0.0 -vcodec libx264 -preset ultrafast -qp 0 my_file.mkv
|
|
|
|
However, we will want to activate this command indirectly via a script that will be activated by the window manager or ``xbindkeys``. Additionally, we will want some audible indicator of starting and stopping.
|
|
|
|
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
|
Desktop Recording: The Script
|
|
````````````````````````````````
|
|
To make this script work, we will: have the file, ``~/.record_poll`` act as both the ``stdin`` redirection for ``ffmpeg`` and as a check for if we are recording. Our capture directory is assumed to exist at ``~/capture/``.
|
|
|
|
##!/bin/bash
|
|
#if [ -f ~/.record_poll ];
|
|
#then
|
|
# echo 'q' > ~/.record_poll
|
|
#else
|
|
# touch ~/.record_poll
|
|
# date=`date +%Y-%m-%d`
|
|
# play /usr/share/sounds/freedesktop/stereo/device-added.oga
|
|
# <~/.record_poll ffmpeg -f x11grab -follow_mouse 428 -draw_mouse 1 -r 1 -video_size 1280x720 -i :0.0 -vcodec libx264 -preset ultrafast -qp 0 ~/capture/$date/900_`date +%s`.mkv 2>>~/.record_log
|
|
# rm ~/.record_poll
|
|
# play /usr/share/sounds/freedesktop/stereo/device-removed.oga
|
|
#fi
|
|
|
|
To test this, open two terminals. Run ``record`` in one to start, then run ``record`` in the other to stop -- or use one terminal and append ``&`` to ``record``.
|
|
|
|
Alternatively, you could issue a SIGINT or SIGTERM to ffmpeg ((pkill -SIGINT ffmpeg)) to stop rather than polling a file. This behavior seems to vary depending on your ``ffmpeg`` version, so I used a more universal and safe method.
|
|
|
|
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
|
Camera Recording: The Command
|
|
````````````````````````````````
|
|
This command is similar to Desktop Recording, but uses the v4l device as the input. This __will__ vary depending on your camera setup.
|
|
|
|
#ffmpeg -f v4l2 -input_format mjpeg -r 5 -video_size 640x360 -i /dev/video0 -c:v copy -acodec null my_file.avi
|
|
|
|
Some technical notes must be made here. For this entire operation I wanted to avoid all unneeded CPU usage, so as to leave the actual desktop activity unhindered. As a result, I am using the camera's built-in encoding abilities to produce an mjpeg stream and almost no cost to the CPU. However, web cameras vary greatly in their capabilities, in terms of minimum and maximum framerate, built-in encoding, and video sizes. To get a basic listing of supported settings for your ``/dev/video0`` device, run:
|
|
|
|
#ffmpeg -f v4l2 -list_formats -all -i /dev/video0
|
|
|
|
To get extending information on FPS settings:
|
|
|
|
#v4l2-ctl --list-formats-ext
|
|
|
|
Finally, in the case of my camera, it only allowed a minimum of 5 frames per second - more than what I needed. To compensate, I had to run post-proccessing to drop the unneeded frames:
|
|
|
|
#ffmpeg -i my_file.avi -r 1 my_file_1fps.avi
|
|
|
|
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
|
Camera Recording: The Script
|
|
````````````````````````````````
|
|
This script follows the exact order of the Desktop Recording:
|
|
|
|
##!/bin/bash
|
|
#if [ -f ~/.camera_poll ];
|
|
#then
|
|
# echo 'q' > ~/.camera_poll
|
|
#else
|
|
# touch ~/.camera_poll
|
|
# date=`date +%Y-%m-%d`
|
|
# play /usr/share/sounds/freedesktop/stereo/device-added.oga
|
|
# <~/.camera_poll ffmpeg -f v4l2 -input_format mjpeg -r 5 -video_size 640x360 -i /dev/video0 -c:v copy -acodec null my_file.avi ~/capture/$date/camera_`data +%s`.avi 2>>~/.camera_log
|
|
# rm ~/.camera_poll
|
|
# play /usr/share/sounds/freedesktop/stereo/device-removed.oga
|
|
#fi
|
|
|
|
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
|
The Meta Script
|
|
````````````````````````````````
|
|
To finally tie them together, we just run them at (almost) the same time via a bash script:
|
|
|
|
##!/bin/bash
|
|
#~/bin/rec_camera &
|
|
#~/bin/rec_desktop &
|
|
|
|
Issue this command to start/stop recording as you wish. One note: You could combine these three scripts into one script or even use ffmpeg to pre-embed the camera recording into the desktop recording with some additional CPU usage.
|