[TriLUG] Streaming to Twitch.tv on Linux
Barry Peddycord III
bwpeddyc at ncsu.edu
Thu Jan 9 23:18:51 EST 2014
At dinner tonight, someone indicated interest in how to stream to
Twitch.tv on Linux. Below (quoted) is a Bash script my brother uses to
stream on Ubuntu (the avconv scripts on the internet no longer work as
of the new Xbox One PS4 livestreaming upgrades). All you have to do is
store your Twitch broadcast key in a file called ~/.twitch_key and set
the variables in the script correctly.
Twitch uses the same system as justin.tv, so you should be able to fix
the variables below with some hackery.
Sharing because I was asked to. No warranty of particular
merchantability porpoises.
> #!/bin/bash
> ## Stream the desktop (and webcam) to livestream.com or twitch.tv!
> ## stream v0.4.0 by haarp
> ## Distributed under the terms of the GNU General Public License v3
> ##
> ## Dependencies: ffmpeg (mandatory, libav may not work!), xwininfo (mandatory)
> ## notify-send (if GUI is desired), pavucontrol (if pulseaudio shall transmit audio)
> ## !! libav users must define an audio device !!
> ##
> ## Uses x264 to encode the stream, which requires a lot of CPU power - the stream will lag
> ## or fall behind if the CPU can't keep up - tweak FPS, PRESET and HALFRES to combat this
>
> ### SETTINGS
> FFMPEG="ffmpeg" # ffmpeg binary to use, usually "ffmpeg" or "avconv"
> FPS="30" # frames per second. default: "30"
> PRESET="ultrafast" # encoder preset, tweaks encoder speed against quality. default: "medium", possible values:
> # ultrafast, superfast, veryfast, faster, fast, medium, slow, slower, veryslow, placebo
> # faster = less cpu
> TUNE="" # encoder tuning options. default: "" (none), possible values:
> # film, animation, grain, stillimage, psnr, ssim, fastdecode, zerolatency(avoid)
> BITRATE="128k" # video stream bit/s, should be below network upload bandwidth. default: "" (no limit, may lag)
> HALFRES="true" # halve the output resolution, reducing processer load. default: "false"
> WEBCAM="" # webcam device to use (overlaid in upper right corner), e.g. "/dev/video0". default: "" (disabled)
> WEBCAMWIDTH="480" # camera picture width to use (in pixels). default: "480"
> AUDIO="default" # ALSA device to use, adds 64kbit/s to the stream, "" to disable. options: "default", "pulse", etc.
> # for "pulse" (recommended), run pavucontrol after starting the stream to set an input device
>
> ## -----------------------------------------------------------------------------
> ### TWITCH.TV
> STREAM_KEY=$(cat ~/.twitch_key)
> CHANNEL="channelname"
> ## -----------------------------------------------------------------------------
> OUTPUT="rtmp://live.twitch.tv/app/$STREAM_KEY"
> URL="http://www.twitch.tv/$CHANNEL"
> STREAMURL="http://www.twitch.tv/$CHANNEL/popout"
> CHATURL="http://www.twitch.tv/chat/embed?channel=$CHANNEL&popout_chat=true"
>
> ### OTHER
> #OUTPUT=-
>
> ## -----------------------------------------------------------------------------
> ### DON'T MESS BELOW THIS LINE
> print() {
> if [[ $gui == "1" ]]; then
> notify-send -i video "$(basename "$0")" "$1"
> else
> echo -e "$1" >&2
> fi
> }
> [[ $TERM == "linux" || $TERM == "dumb" ]] && {
> if which notify-send &>/dev/null; then
> gui=1
> else
> gui=0
> echo "notify-send not found, using stderr!" >&2
> fi
> }
>
> for program in $FFMPEG xwininfo; do
> which $program &>/dev/null || {
> print "$program not found, aborting!"; exit 9; }
> done
>
> if [[ $WEBCAM ]]; then
> if [[ -c "$WEBCAM" ]]; then
> print "Using webcam $WEBCAM"
> webcamarg1="-vf"
> webcamarg2="movie=$WEBCAM:f=video4linux2, scale=$WEBCAMWIDTH:-1, fps, setpts=PTS-STARTPTS [movie]; [in][movie] overlay=main_w-overlay_w-2:2 [out]"
> else
> print "Device $WEBCAM not found, aborting!"; exit 2
> fi
> else
> webcamarg1=""
> webcamarg2="-stats" # this is a pointless dummy
> fi
> if [[ $AUDIO ]]; then
> print "Using audio device $AUDIO"
> audioarg_i="-f alsa -i $AUDIO"
> audioarg_o="-acodec libmp3lame -ar 44100 -ab 64k"
> else
> audioarg_i="-f lavfi -i aevalsrc=0" # generate silence (presence of audio track fixes many bugs)
> # but causes time and bitrate to be shown all wrong (ffmpeg-1.2.4)
> audioarg_o="-acodec libmp3lame -ar 44100 -ab 1k -ac 1" # make damn sure it's 44100!
> fi
>
> if [[ $1 == "-f" ]]; then
> print "Using entire screen."
> frame_info=$(xwininfo -root)
> else
> print "Select an area by clicking on a window! Use -f for fullscreen."
> frame_info=$(xwininfo -frame)
> root_info=$(xwininfo -root)
> fi
> frame_coords_x=$(echo "$frame_info" | awk '/Absolute upper-left X:/{print $4}')
> frame_coords_y=$(echo "$frame_info" | awk '/Absolute upper-left Y:/{print $4}')
> frame_geo_x=$(echo "$frame_info" | awk '/Width:/{print $2}')
> frame_geo_y=$(echo "$frame_info" | awk '/Height:/{print $2}')
>
> echo "DEBUG: Input coords: $frame_coords_x,$frame_coords_y; input size: ${frame_geo_x}x${frame_geo_y}" >&2
>
> if [[ $1 != "-f" ]]; then # clip at screen borders
> root_geo_x=$(echo "$root_info" | awk '/Width:/{print $2}')
> root_geo_y=$(echo "$root_info" | awk '/Height:/{print $2}')
> [[ $(($frame_coords_x + $frame_geo_x)) -gt $root_geo_x ]] && \
> frame_geo_x=$(( $root_geo_x - $frame_coords_x ))
> [[ $(($frame_coords_y + $frame_geo_y)) -gt $root_geo_y ]] && \
> frame_geo_y=$(( $root_geo_y - $frame_coords_y ))
> fi
> until [[ $(( $frame_geo_x % 4 )) == 0 ]]; do ((frame_geo_x--)); done # some versions of x264 can't
> until [[ $(( $frame_geo_y % 4 )) == 0 ]]; do ((frame_geo_y--)); done # deal with uneven values
>
> if [[ $BITRATE ]]; then bitarg="-vb $BITRATE"
> else bitarg=""
> fi
> if [[ $HALFRES == "true" ]]; then
> res_x=$(( $frame_geo_x / 2 ))
> res_y=$(( $frame_geo_y / 2 ))
> resarg="-s ${res_x}x${res_y}"
> echo "DEBUG: Cropping input to ${frame_geo_x}x${frame_geo_y}; outputting ${res_x}x${res_y}" >&2
> else
> resarg=""
> echo "DEBUG: Cropping input to ${frame_geo_x}x${frame_geo_y}" >&2
> fi
>
> print "Starting stream in 5 seconds..."
> sleep 5
>
> $FFMPEG \
> -f x11grab -s ${frame_geo_x}x${frame_geo_y} -r $FPS -i :0.0+${frame_coords_x},${frame_coords_y} \
> $audioarg_i \
> $webcamarg1 "$webcamarg2" \
> -vcodec libx264 -pix_fmt yuv420p -preset "$PRESET" -tune "$TUNE" $bitarg \
> $audioarg_o \
> -f flv -r $FPS $resarg -y "$OUTPUT"
>
> [[ $? == 0 ]] || print "$FFMPEG terminated!"
> exit
Most sincerely,
Barry Peddycord III
More information about the TriLUG
mailing list