Live Coding with ffmpeg and justin.tv
Recently I've been experimenting with operating a live coding stream of my desktop. What this means in practice is that I focus on a single project or set of tasks for an hour or two, while streaming everything I do to my channel on justin.tv.
Here's a boring demonstration:
Watch live video from Live coding with @agentdero on Justin.tv
I'll save my thoughts on how the experiment is going for a later blog post, in this post I just wanted to share the how.
First I use this ~/bin/screenstream script:
#!/bin/sh -xe
INFO=$(xwininfo -frame)
API_KEY="YOUR_API_KEY_GOES_HERE"
WIN_GEO=$(echo $INFO | grep -oEe 'geometry [0-9]+x[0-9]+' | grep -oEe '[0-9]+x[0-9]+')
WIN_XY=$(echo $INFO | grep -oEe 'Corners:\s+\+[0-9]+\+[0-9]+' | grep -oEe '[0-9]+\+[0-9]+' | sed -e 's/\+/,/' )
FPS="15"
INRES='1680x1010'
OUTRES='1280x720'
ffmpeg -f x11grab -s "$INRES" -r "$FPS" -i :0.0+$WIN_XY \
-f alsa -ac 2 -i default -vcodec libx264 -s "$OUTRES" \
-acodec libmp3lame -ab 128k -ar 44100 -threads 0 \
-f flv "rtmp://live.justin.tv/app/$API_KEY"
There's a couple important things to mention about this:
- The
xwininfoinvocation just gives me a cross-hairs cursor so I can select which window area I want to record. This doesn't technically restrictffmpeg(1)to just that window, rather it just grabs the offset from the window and uses those. - The segment:
-f alsa -ac 2 -i defaultpertains to the audio input. According toarecord -L, the pulse audio sink I should use is called "default", on some machines it might be called "pulse", your mileage may vary. - I use the
pavucontrol(GUI) tool to direct my audio out to the pulseaudio input, this allows me to share what I'm listening to with whoever is watching the stream. - You'll notice the
$INRESand$OUTRESparameters, I am techically live-resizing the video on the fly, which takes up a lot of CPU power, you may or may not want to do this depending on your machine speed, size of your screen and the amount of desktop space you want to stream.
That's about all there is too it, I wish I could either take credit for the script or at least attribute it, but I can do neither because I found it on a forum some where and then quickly lost the link. Whoops.
academia activerecord ada amber android apture async bart bdd beer birthday blimpy brainfuck buzzwords c campdevops cheetah chrome ci cocoa conference continuousdeployment cucumber devops documentation drupal epoll europe evernote facebook family food fosdem fosdem2012 fosdem2013 ganglia gerrit git github gla graphite home homosex hubboard hudson identica javascript jekyll jenkins jenkinsci jenkinsconf jenkinsconf2012 juctokyo juggling justintv learnings linux literature livecoding lookout media meetups microblogging miscellaneous mono offtopic opbart opengrok openmoko opensource opinion ops parrots photos presentation programming protesting puppet puppetconf puppetconf2012 python ragequit rails rdoc redis resin ri roadtrip ruby running scale scale10x screencast security selenium slide smalltalk soapopera software development sonic ssh stupidhacks tablet tor tripdiary twitter twos usenet vagrant video voyeurism wtf
