Skip to content

Instantly share code, notes, and snippets.

@aspiers
Last active January 5, 2019 10:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save aspiers/38eed5ea5fc1b7a98372 to your computer and use it in GitHub Desktop.
Save aspiers/38eed5ea5fc1b7a98372 to your computer and use it in GitHub Desktop.
# -*- mode: sh -*-
ffx-help () {
cat <<EOF
First run a command to choose which area of the screen to record:
ffx-full records the whole desktop
ffx-winselect lets you choose which window to record
ffx-rectselect lets you choose a rectangle to record
These all set the same two shell variables:
ffx_geometry=$ffx_geometry
ffx_viewport=$ffx_viewport
To resize a window to 1280x720 (say) to perfectly fit a 720p video
recording, you can use xdotool e.g.
xdotool windowselect windowsize 1280 720
but this will set the size of the content, excluding window
decorations (title/border), so if you want the decorations included in
the video you will need to use smaller dimensions, e.g.
$ xprop _NET_FRAME_EXTENTS # returns left/right/top/bottom borders
_NET_FRAME_EXTENTS(CARDINAL) = 1, 1, 20, 5
so in this case full window decorations are 2x25
# allow for window border of 1x23 with openbox
xdotool windowselect windowsize 1279 697
To produce a reference window of a given size:
c=red; xeyes +shape -bg $c -outline $c -fg $c -geometry 1280x720+50+50
but don't forget to undecorate the window since again decorations expand it!
By default, ffx-pulse is run to set audio source to pulseaudio. For ALSA:
ffx-alsa hw:0,0 # cat /proc/asound/pcm
Now you are ready to actually record the video! Use the following
command which gives you 2 seconds to switch to the right
desktop/window before recording starts. Hit Control-C to stop and it
will automatically play the result back:
# Make sure you have enough spare disk space!
file=foo.mp4; sleep 2; ffx [extra ffmpeg options] $file && mplayer $file
After, upscale to 1080p to prevent YouTube from destroying quality (doh!):
ffmpeg -i $file -vf scale=1920:1080 ${file%.*}-1080.${file##*.}
Optionally extract a frame to use as the video thumbnail:
ffmpeg -ss 00:01:23 -i $file -t 1 -r 1 frame%d.png
EOF
}
# Ideas stolen from https://github.com/lolilolicon/FFcast2
# https://github.com/gotbletu/shownotes/blob/master/ffmpeg_x11grab_screencast.txt
# Settings recommended for YouTube
# https://support.google.com/youtube/answer/1722171?hl=en
ffx_channels="1" # mono / stereo audio
ffx_fps="30" # frames per second
ffx_acodec="flac" # audio codec
#ffx_acodec="pcm_s16le"
# settings recommended for YouTube:
# https://support.google.com/youtube/answer/1722171?hl=en
ffx_vcodec="libx264"
ffx_preset="slow" # preset error? run 'x264 -h' replace with fast,superfast, slow ..etc
# - requires x264 installed.
ffx_crf="18" # quality for constant quality mode
ffx_profile="high" # h264 profile
#ffx_scale="scale=1280:720" # scale resolution, no black bars on sides of video on youtube
ffx_geometry=1280x720 # ideal for YouTube; overwritten by ffx-{full,winselect}
ffx_viewport=+0+0 # easy-to-use default
ffx-alsa () {
audio_input_opts=(
-f alsa
-i "$1"
)
}
ffx-pulse () {
# Needs to be compiled with --enable-libpulse
# https://www.ffmpeg.org/ffmpeg-devices.html#pulse
audio_input_opts=(
-f pulse
-i default # lots of people use 'pulse' but that doesn't work for me
)
}
#ffx-alsa hw:2,1
ffx-pulse
ffx-full () {
ffx_wininfo="$( xwininfo -root )"
ffx_viewport=
_ffx_geom_from_wininfo
_ffx_report_geom_viewport
}
ffx-winselect () {
ffx_wininfo="$(xwininfo -frame)"
ffx_top_left_x=$(
echo "$ffx_wininfo" | \
awk '/Absolute upper-left X: / { print $4 }'
)
ffx_top_left_y=$(
echo "$ffx_wininfo" | \
awk '/Absolute upper-left Y: / { print $4 }'
)
ffx_viewport="+$ffx_top_left_x+$ffx_top_left_y"
_ffx_geom_from_wininfo
_ffx_report_geom_viewport
}
ffx-rectselect () {
ffx_wininfo="$(xrectsel)"
ffx_geometry="${ffx_wininfo%%+*}"
ffx_viewport="+${ffx_wininfo#*+}"
_ffx_report_geom_viewport
}
_ffx_geom_from_wininfo () {
ffx_geometry=$(
echo "$ffx_wininfo" | \
awk '/-geometry/ {print $2}' | \
grep -oEe '[0-9]+x[0-9]+'
)
}
_ffx_report_geom_viewport () {
echo "Geometry: $ffx_geometry"
echo "Viewport: $ffx_viewport"
}
ffx () {
ffmpeg_opts=(
# audio options
"${audio_input_opts[@]}"
-ac $ffx_channels
-acodec $ffx_acodec
# video options
-f x11grab
-video_size $ffx_geometry # has to be after x11 grab and before -i!
-framerate $ffx_fps
-i $DISPLAY$ffx_viewport
#-vf $ffx_scale
-vcodec $ffx_vcodec # has to come after -i for some reason
-preset $ffx_preset
-profile:v $ffx_profile
-crf $ffx_crf # quality for constant quality mode
-pix_fmt yuv420p
-r $ffx_fps
# general options
"$@"
)
echo ffmpeg "${ffmpeg_opts[@]}"
ffmpeg "${ffmpeg_opts[@]}"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment