Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@swarminglogic
Last active November 25, 2022 06:45
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save swarminglogic/8692569 to your computer and use it in GitHub Desktop.
Save swarminglogic/8692569 to your computer and use it in GitHub Desktop.
recordscreen: A bash script for timelapse recordinging two separate X displays, and creating a picture-in-picture overlay with one display
#!/bin/bash
if [ ! $# -eq 2 ] ; then
echo "Usage: ./recordscreen delay outputfolder"
exit
fi
if [ ! -d $outputFolder ] ; then
echo "Output folder does not exist"
exit
fi
# $1:output
function captureScreenDump {
xwd -root -out $1
}
# $1:input-file $2:output-file
function prepareThumbnail {
convert $1 -thumbnail 300x300 -bordercolor "#881111aa" -border 2 \
\( +clone -background black -shadow 100x3+2+2 \) \
+swap -background none -layers merge +repage $2
}
# $1:left-image $2:right-image $3:output-frame
function prepareFinalFrame {
pictureInPictureOffset=+1588+837
convert -composite $1 $2 -geometry $pictureInPictureOffset $3
}
# $1:counter $2:folderOuput
function doFrameCapture {
# Filenames for left and right screen
outfile=`printf '%.5d' $1`-`date +"%Y-%m-%d-%s"`
left=${2}/left/${outfile}
right=${2}/right/${outfile}
# Capture both screens at the same time
(DISPLAY=:0.0 captureScreenDump ${left}.xwd && pid1=$!) &
(DISPLAY=:0.1 captureScreenDump ${right}.xwd && pid2=$!)
wait $pid1 $pid2
# Prepare right screen as thumbnail
thumbnail=${right}-thumbnail
prepareThumbnail ${right}.xwd ${thumbnail}.png
# Create final frame from left frame and thumbnail of right frame
outfileFinal=${2}/frames/`printf '%.5d' $1`
prepareFinalFrame ${left}.xwd ${thumbnail}.png ${outfileFinal}.png
# Cleanup:
rm $left.xwd $right.xwd $thumbnail.png
}
################### PROGRAM CODE STARTS ###################
delay=$1
outputFolder=$2
mkdir $outputFolder/{left,right,frames}
curr=0
while sleep $delay;
do
((curr++))
(doFrameCapture $curr $outputFolder &)
done
#################### ----------------- ####################
#!/bin/bash
# Setup:
####################
# Automatic setup detection using xrandr
xrandrOutput=`xrandr --query`
leftGeometry=`echo "$xrandrOutput" | grep -P "\sconnected" \
| grep -oP '\d+x\d+\+0\+\d+'`
rightGeometry=`echo "$xrandrOutput" | grep -P "\sconnected" \
| grep -oP '\d+x\d+\+\d{2,}\+\d+'`
primaryGeomtry=`echo "$xrandrOutput" | grep -P "\sconnected primary" \
| grep -oP '\d+x\d+\+\d+\+\d+'`
if [[ "$primaryGeomtry" == "$leftGeometry" ]] ; then
mainMonitor=left
elif [[ "$primaryGeomtry" == "$rightGeometry" ]] ; then
mainMonitor=right
else
echo "Failed to detect main monitor"
fi
leftMonitor=${leftGeometry%%+*}
rightMonitor=${rightGeometry%%+*}
pipSize=340x340
pipOffset=+30+20
# Implicit variables
leftMonitorWidth=${leftMonitor%x*}
echo "leftMonitor: " $leftMonitor
echo "rightMonitor: " $rightMonitor
echo "pipSize: " $pipSize
echo "pipOffset: " $pipOffset
echo "mainMonitor: " $mainMonitor
########################
if [[ ! "$mainMonitor" == "left" ]] && \
[[ ! "$mainMonitor" == "right" ]] ; then
echo "Bad mainMonitor variable"
exit
fi
if [ ! $# -eq 2 ] ; then
echo "Usage: ./recordscreen delay outputfolder"
exit
fi
if [ ! -d $outputFolder ] ; then
echo "Output folder does not exist"
exit
fi
gsettings set org.gnome.desktop.sound event-sounds false
# $1:output
function captureScreenDump {
xwd -root -out $1
}
# $1:input-file $2:output-file
function prepareThumbnail {
if [[ "$mainMonitor" == "left" ]] ; then
geometry=${rightMonitor}+${leftMonitorWidth}+0
else
geometry=${leftMonitor}+0+0
fi
convert $1 -crop $geometry -thumbnail $pipSize \
-bordercolor "#881111aa" -border 2 \
\( +clone -background black -shadow 100x3+2+2 \) \
+swap -background none -layers merge +repage $2
}
# $1:captured-image $2:pip-thumbnail $3:output-frame
function prepareFinalFrame {
geometry=
if [[ "$mainMonitor" == "left" ]] ; then
geometry=${leftMonitor}+0+0
else
geometry=${rightMonitor}+${leftMonitorWidth}+0
fi
convert -crop $geometry ${1} ${1}.tmp.xwd
convert -composite ${1}.tmp.xwd $2 -gravity SouthEast \
-geometry $pipOffset $3
rm ${1}.tmp.xwd
}
# $1:counter $2:folderOuput
function doFrameCapture {
# Filenames for capture and right screen
outfile=`printf '%.5d' $1`-`date +"%Y-%m-%d-%s"`
capture=${2}/capture/${outfile}
pip=${2}/pip/${outfile}
# Capture both screens at the same time
captureScreenDump $capture.xwd
prepareThumbnail $capture.xwd $pip.png
# Create final frame from left frame and thumbnail of right frame
outfileFinal=${2}/frames/`printf '%.5d' $1`
prepareFinalFrame ${capture}.xwd ${pip}.png ${outfileFinal}.png
# Cleanup:
rm -f $capture.xwd $pip.png
}
function finalize() {
rm -f $outputFolder/{capture,pip}/*
rmdir $outputFolder/{capture,pip}
gsettings set org.gnome.desktop.sound event-sounds true
exit
}
trap finalize SIGINT SIGTERM
################### PROGRAM CODE STARTS ###################
delay=$1
outputFolder=$2
curr=0
if [ -e $outputFolder/frames ] ; then
lastFrame=`ls -1 $outputFolder/frames/ | tail -n 1`
curr=`echo ${lastFrame%.*} | sed 's/^0*//'`
while true; do
read -p "Recording in progress (currently $curr frames)
Do you wish to continue at frame "$((curr+1))"? [y/n] " yn
case $yn in
[Yy]* ) break;;
[Nn]* ) exit;;
* ) echo "Please answer yes or no.";;
esac
done
fi
if [ ! -e $outputFolder/capture ] ; then mkdir $outputFolder/capture ; fi
if [ ! -e $outputFolder/pip ] ; then mkdir $outputFolder/pip ; fi
if [ ! -e $outputFolder/frames ] ; then mkdir $outputFolder/frames ; fi
while sleep $delay;
do
((curr++))
(doFrameCapture $curr $outputFolder &)
done
#################### ----------------- ####################
@phiresky
Copy link

why don't you just ffmpeg -s 1280x720 -f x11grab -i :0.0+100,100 -filter:v "setpts=PTS/30" -r 30 though?

@anko
Copy link

anko commented Sep 11, 2014

@phiresky
Does that capture multiple screens?

There's a great script called ffcast that automates selecting an area and recording it, with x11grab as you mentioned. I summarised how to use it and convert the results to GIF here. (I don't know if my method works with multiple screens though...)

@denilsonsa
Copy link

Why using xwd -root -out foo.xwd instead of import -window root foobar.png? import is from ImageMagick, the same package that provides convert.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment