From: Einar Jørgen Haraldseid Date: Tue, 28 May 2013 21:46:40 +0000 (+0200) Subject: screencast.sh is a quick and dirty video screen recording script X-Git-Url: https://git.slaskete.net/einar-bin/commitdiff_plain/8e230a3828e95a6a33aff1d443f823f37688afd7?ds=sidebyside screencast.sh is a quick and dirty video screen recording script written in bash with zenity and gstreamer. It does a lot of things that other screen recorders don't. --- diff --git a/screencast.sh b/screencast.sh new file mode 100755 index 0000000..f1a2668 --- /dev/null +++ b/screencast.sh @@ -0,0 +1,87 @@ +#!/bin/bash +# WARNING: This is a terribly dirty and messy shellscript, written over a couple of late nights +# There was alcohol +# You probably need to install all the gstreamer-plugins (at least -ugly and -ffmpeg) to get this to work +# I wanted to make mp4 with x264, I didn't bother with free codecs + +# This script allows you to create screencasts on Linux, with optional sound inputs (both Mic and system sounds) +# You also get to choose to record from the whole screen or just a specified window. It has only been tested +# on Fedora 18. + +# Written by Einar Jørgen Haraldseid (http://einar.slaskete.net) +# License: http://sam.zoy.org/wtfpl/COPYING + +# Get device names and pretty names for playback sinks: +PLAYSINKLIST=$(pacmd list-sinks | grep -e "name: " -e "device.description = " | cut -d " " -f "2-" | sed -e "s/name: \|= //g" -e "s/<\|>\|\x22//g") + +# Display playback monitor chooser +PLAYMON=$(echo "${PLAYSINKLIST} +none +Don't capture system sounds" | zenity --list --title "Choose Output Device" --text "Choose a sound device to capture system sound from:" --column "device" --column "Name" --print-column=1 --hide-column=1 2>/dev/null) + +if [ -z ${PLAYMON} ]; then + echo "No choice made on output device, assuming cancel." + exit 1 +fi + +if [ ${PLAYMON} != "none" ]; then + # Unmute monitor of the playback sink (if set): + PLAYMON="${PLAYMON}.monitor" + + pacmd set-source-mute ${PLAYMON} false >/dev/null +fi + +# Get device names and pretty names for microphones: +MICLIST=$(pacmd list-sources | grep -e "name: " -e "device.description = " | grep -v -i "monitor" | cut -d " " -f "2-" | sed -e "s/name: \|= //g" -e "s/<\|>\|\x22//g") + +# Display device chooser +MIC=$(echo "${MICLIST} +none +Don't use a microphone" | zenity --list --title "Choose Microphone" --text "Choose a microphone to capture voice from:" --column "device" --column "Name" --print-column=1 --hide-column=1 2>/dev/null) + +if [ -z ${MIC} ]; then + echo "No choice made on microphone, assuming cancel." + exit 1 +fi + +# Get target window for recording: +TARGET=$(echo "root +Whole screen +window +Specific window" | zenity --list --title "Choose recording mode" --text "Do you want to record the whole screen, or record a specific window?" --column "target" --column "Mode" --print-column=1 --hide-column=1 2>/dev/null) + +if [ -z ${TARGET} ]; then + echo "No choice for recording target, assuming cancel." + exit 1 +fi + +if [ ${TARGET} = "root" ]; then + echo "Root chosen" + XWININFO=$(xwininfo -root) +else + echo "custom chosen" + XWININFO=$(xwininfo) +fi + +# Get Window ID and dimensions, make sure dimensions are divisible by two, or else the encoder will fail +WID=$(echo "${XWININFO}" | grep "Window id:" | awk '{print $4}') +WIDTH=$(echo "${XWININFO}" | grep "Width: " | cut -d ":" -f 2 | awk '{print $1+$1%2}') +HEIGHT=$(echo "${XWININFO}" | grep "Height: " | cut -d ":" -f 2 | awk '{print $1+$1%2}') + +# Calculate a suitable bitrate based on window dimensions +BITRATE=$(echo "${WIDTH} * ${HEIGHT} * 0.006" | bc | cut -d "." -f 1 ) + +# Enable inputs as suitable +if [ ${PLAYMON} != "none" ]; then + MONITORARG="pulsesrc device=${PLAYMON} slave-method=0 provide-clock=false ! audiorate ! audioconvert ! ffenc_aac bitrate=256000 ! queue2 ! mux." +fi +if [ ${MIC} != "none" ]; then + MICARG="pulsesrc device=${MIC} slave-method=0 provide-clock=false ! audiorate ! audioconvert ! ffenc_aac bitrate=256000 ! queue2 ! mux." +fi + +# Launch gstreamer +gst-launch -e ximagesrc xid="${WID}" do-timestamp=1 use-damage=0 ! video/x-raw-rgb,framerate=30/1 \ + ! ffmpegcolorspace ! videoscale method=0 ! video/x-raw-yuv,width=${WIDTH},height=${HEIGHT} \ + ! x264enc speed-preset=ultrafast bitrate=${BITRATE} ! queue2 \ + ! mp4mux name="mux" ! filesink location="output.mp4" $MONITORARG $MICARG +