Skip to content

Instantly share code, notes, and snippets.

@tokland
Created November 15, 2017 21:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tokland/dd840deda1557220fc03897bb15e4f93 to your computer and use it in GitHub Desktop.
Save tokland/dd840deda1557220fc03897bb15e4f93 to your computer and use it in GitHub Desktop.
#!/bin/bash
#
# Record a video of a mod/s3m/xm tracker song played using milkytracker.
#
# Dependencies with versions used in parenthesis:
#
# schismtracker / milkytracker
# pulseaudio
# vnc2flv
# turbovnc
# ffmpeg
set -e -u -o pipefail
trap "trap - SIGTERM && kill -- -$$ && sleep 0.1 && kill -9 -- -$$" SIGINT SIGTERM
debug() { echo "$@" >&2; }
get_track_duration() { local file=$1
ffprobe -v quiet -show_format "$file" | grep "duration=" | cut -d"=" -f2 | sed "s/\..*$//"
}
get_metadata() { local file=$1
ffprobe "$file" |& awk '/Metadata:/{flag=1;next}/Duration:/{flag=0}flag' | sed "s/^ //"
}
record_track() { local track=$@
local duration output_dir info_file
duration=$(get_track_duration $track)
output_dir="output"
mkdir -p "$output_dir"
debug "Duration: $duration"
info_file="$output_dir/$(basename "$track").txt"
get_metadata "$track" > "$info_file"
record_video "$output_dir" "$duration" "640x480" milkytracker -nosplash "$track"
#record_video "$output_dir" "$duration" "640x480" schismtracker --classic --play "$track"
echo "$info_file"
}
record_video() { local output_dir=$1 duration=$2 geometry=$3; shift 3; command=$@
local display output_dir vnc_password video_file random
local pid_xvnc pid_tracker pid_flvrec
local pulse_sink pulse_source sink_index
vnc_password="123123"
random=$RANDOM
display=":1"
pulse_sink="vnc-$random"
pulse_source="$pulse_sink.monitor"
# Setup Pulseaudio
sink_index=$(pactl load-module module-null-sink sink_name=$pulse_sink \
sink_properties=device.description=$pulse_sink)
pacmd load-module module-loopback sink=$pulse_sink >&2
# Start VNC server
echo "$vnc_password" | tightvncpasswd -f > .vncpasswd
Xvnc -rfbport 5901 $display -rfbauth .vncpasswd -geometry "$geometry" >&2 &
pid_xvnc=$!
sleep 2
# Start GUI command
DISPLAY=$display PULSE_SINK=$pulse_sink $command >&2 &
pid_tracker=$!
# Record video & audio
flvrec.py -C "$geometry+0-0" -o "out-$random.flv" -r 30 -P <(echo "$vnc_password") \
-S "PULSE_SOURCE=$pulse_source parecord out-$random.wav" $display >&2 &
pid_flvrec=$!
sleep $((duration + 1))
#sleep 10
# Stop all tasks
kill -INT $pid_flvrec $pid_xvnc $pid_tracker || true
sleep 0.1
kill -TERM $pid_flvrec $pid_xvnc $pid_tracker || true
wait
pactl unload-module $sink_index >&2
# Merge video and & video
video_file="$output_dir/$(basename "$track").mp4"
ffmpeg -i "out-$random.flv" -i "out-$random.wav" -filter:v "crop=640:400:0:0" -s "854x480" \
-shortest -map 0:0 -map 1:0 -ss 0.2 -y "$video_file"
rm -f "out-$random.flv" "out-$random.wav"
echo "$video_file"
}
if test $# -new 1; then
echo "Usage: $(basename $0) TRACK_FILE"
exit 2
else
record_track "$@"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment