3 # WARNING: This is a terribly dirty and messy shellscript, written over a
4 # couple of late nights. There was alcohol …
5 # You probably need to install all the gstreamer-plugins (at least -ugly
6 # and -ffmpeg) as well as gstreamer-tools to get this to work. I wanted to
7 # make mp4 files with x264, I didn't bother with free codecs.
9 # So this script allows you to create screencasts on Linux, with optional
10 # sound inputs (both Microphone and system sounds). It stores system sounds
11 # and microphone in separate audio streams.
13 # You also get to choose to record from the whole screen or just a specified
14 # window. It has been tested on Fedora 18 and CrunchBang Waldorf (and thus
15 # should work on Debian Wheezy as well).
17 # It dumps the recording in your $HOME directory with a filename like
18 # screencast-YYYY-MM-DD-HH-MM-SS.mp4
20 # Written by Einar Jørgen Haraldseid (http://einar.slaskete.net)
21 # License: http://sam.zoy.org/wtfpl/COPYING
23 # Get device names and pretty names for enumerating playback sinks:
24 PLAYSINKLIST
=$
(pacmd list-sinks | \
25 grep -e "name: " -e "device.description = " | cut
-d " " -f "2-" | \
26 sed -e "s/name: \|= //g" -e "s/<\|>\|\x22//g")
28 # Display playback monitor chooser
29 PLAYMON
=$
(echo "${PLAYSINKLIST}
31 Don't capture system sounds" | \
32 zenity
--list --title "Choose Output Device" \
33 --text "Choose a sound device to capture system sound from:" \
34 --column "device" --column "Name" --print-column=1 \
35 --hide-column=1 2>/dev
/null
)
38 if [ -z ${PLAYMON} ]; then
39 echo "No choice made on output device, assuming cancel."
43 if [ ${PLAYMON} != "none" ]; then
44 # Unmute monitor of the playback sink (if set):
45 PLAYMON
="${PLAYMON}.monitor"
46 pacmd set-source-mute
${PLAYMON} false
>/dev
/null
47 echo "Recording system sounds from ${PLAYMON}"
49 echo "Not recording system sounds."
52 # Get device names and pretty names for microphones:
53 MICLIST
=$
(pacmd list-sources | \
54 grep -e "name: " -e "device.description = " | \
55 grep -v -i "monitor" | cut
-d " " -f "2-" | \
56 sed -e "s/name: \|= //g" -e "s/<\|>\|\x22//g")
58 # Display device chooser
59 MIC
=$
(echo "${MICLIST}
61 Don't use a microphone" | \
62 zenity
--list --title "Choose Microphone" \
63 --text "Choose a microphone to capture voice from:" \
64 --column "device" --column "Name" --print-column=1 \
65 --hide-column=1 2>/dev
/null
)
67 if [ -z ${MIC} ]; then
68 echo "No choice made on microphone, assuming cancel."
72 if [ ${MIC} != "none" ]; then
73 echo "Recording voice from ${MIC}"
75 echo "Not recording voice."
78 # Get target window for recording:
83 zenity
--list --title "Choose recording mode" \
84 --text "Do you want to record the whole screen,\
85 or record a specific window?" --column "target" \
86 --column "Mode" --print-column=1 --hide-column=1 2>/dev
/null
)
88 if [ -z ${TARGET} ]; then
89 echo "No choice for recording target, assuming cancel."
93 if [ ${TARGET} = "root" ]; then
94 echo "Root window chosen."
95 XWININFO
=$
(xwininfo
-root)
97 echo "Custom window chosen."
101 # Get Window ID and dimensions, make sure X and Y dimensions are
102 # divisible by two, or else the encoder will fail
103 WID
=$
(echo "${XWININFO}" |
grep "Window id:" |
awk '{print $4}')
104 WIDTH
=$
(echo "${XWININFO}" |
grep "Width: " | \
105 cut
-d ":" -f 2 |
awk '{print $1+$1%2}')
106 HEIGHT
=$
(echo "${XWININFO}" |
grep "Height: " | \
107 cut
-d ":" -f 2 |
awk '{print $1+$1%2}')
109 # Calculate a suitable bitrate based on window dimensions
110 BITRATE
=$
(echo "${WIDTH} * ${HEIGHT} * 0.0075" |
bc | cut
-d "." -f 1 )
113 FILENAME
="screencast-$(date +%F-%H-%M-%S).mp4"
115 # Enable inputs as suitable
116 if [ ${PLAYMON} != "none" ]; then
117 MONITORARG
="pulsesrc device=${PLAYMON} slave-method=0 provide-clock=false \
118 ! audiorate ! audioconvert ! ffenc_aac bitrate=256000 ! queue2 ! mux."
120 if [ ${MIC} != "none" ]; then
121 MICARG
="pulsesrc device=${MIC} slave-method=0 provide-clock=false \
122 ! audiorate ! audioconvert ! ffenc_aac bitrate=256000 ! queue2 ! mux."
126 gst-launch
-q -e ximagesrc xid
="${WID}" do-timestamp
=1 use-damage
=0 \
127 ! video
/x-raw-rgb
,framerate
=30/1 ! ffmpegcolorspace
! videoscale method
=0 \
128 ! video
/x-raw-yuv
,width
=${WIDTH},height
=${HEIGHT} \
129 ! x264enc speed-preset
=veryfast bitrate
=${BITRATE} ! queue2 \
130 ! mp4mux name
="mux" \
131 ! filesink location
="${HOME}/${FILENAME}" $MONITORARG $MICARG
133 echo "Recording done, file is ${FILENAME}"