Skip to content

Instantly share code, notes, and snippets.

@sertraline
Created April 8, 2021 21:08
Show Gist options
  • Save sertraline/14112ea51601b4086e87132e9b31272a to your computer and use it in GitHub Desktop.
Save sertraline/14112ea51601b4086e87132e9b31272a to your computer and use it in GitHub Desktop.
AMD FFMPEG+VAAPI screen recording with microphone input
#!/bin/bash
# AMD + FFMPEG VAAPI screen+alsa+pulseaudio recording script
# In your home directory create .asoundrc with following contents:
# pcm.!default pulse
# ctl.!default pulse
# This allows alsa to use pulseaudio as the input device.
# Bind any hotkey to the script.
# Launch once - recording starts. Launch twice - recording stops.
FRAMERATE="60"
# lower = better quality
QUANTIZATION="12"
# 2 == visually lossless
# 1 == lossless
QSCALE="2"
VIDEO_CODEC="h264_vaapi"
AUDIO_CODEC="libfdk_aac"
AUDIO_BITRATE="320k"
VIDEO_BITRATE="20k"
OUT=$(date +"%Y-%m-%d %T")
# Create temporary file indicating whether the record is running
# Check whether the file exists
if [ -f "/tmp/record" ]; then
echo "Recording is in process, stopping..."
pid=$(cat /tmp/record)
kill -15 $pid
rm /tmp/record
# send notification
#notify-send "Recording stopped"
elif [ ! -f "/tmp/record" ]; then
echo "Started recording"
exec ffmpeg -nostdin \
-hwaccel vaapi -hwaccel_output_format vaapi -vaapi_device /dev/dri/renderD128 \
-y -f alsa -i pulse -f alsa -i pulse -filter_complex amix=inputs=2:duration=longest \
-f x11grab -framerate $FRAMERATE -i :0.0 -vf 'format=nv12,hwupload' \
-c:v $VIDEO_CODEC -coder cavlc -profile:v constrained_baseline -movflags faststart -qp $QUANTIZATION \
-c:a $AUDIO_CODEC -b:a $AUDIO_BITRATE -b:v $VIDEO_BITRATE -q:v $QSCALE "$OUT.mp4" &
# launch ffmpeg separately from script to change stream sources
disown
# put ffmpeg PID into temp file
echo $! > /tmp/record
# wait for ffmpeg instance to initialize
sleep 1
# get a list of recording streams made by current ffmpeg instance
sinks=$(pactl list source-outputs | grep -B 18 "ffmpeg" | grep "Source Output" | cut -d '#' -f 2)
sink1=$(echo "$sinks" | head -n 1)
sink2=$(echo "$sinks" | tail -n 1)
# move first stream to the recording device (microphone)
pactl move-source-output $sink1 0
# move second stream to the playback device (speakers)
pactl move-source-output $sink2 1
# as a result ffmpeg streams capture microphone+speakers sound
# which then are being mixed together with "filter_complex amix"
notify-send "Recording started"
fi
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment