Implementing HTTP Live Streaming using a Dropcam
I’m posting this up as a helpful reference guide for anyone who is looking to implement HTTP Live Streaming using a Dropcam. This technique opens up Dropcam live streams to people on iOS devices without them being required to download and install a separate application.
Last week we got a WiFi-capable webcam from dropcam.com delivered to the office, as we wanted to have a method of people interacting with a Little Printer via the HTTP API, and for them to be able to see the results on the hardware itself.
Experiment… Text our Little Printer w code at the bottom here http://t.co/3In2wYZwhj then watch live https://t.co/7NMEmVGC25 — needs Flash
— Matt Webb 🌸🌼🌸 (@genmon) March 13, 2014
As a fun interaction system this worked very well, and we’ve had a lot of people send us notes, but I was a little frustrated because Dropcam require you to download an app if you want to view it on mobile iOS devices. Apple’s HTTP Live Streaming protocol has been around for a while now, and still represents one of the more sane methods to standardise live streaming on the web (along with MPEG-DASH). Wouldn’t it be good if we could somehow construct a media pipeline to convert the raw Dropcam RTMP stream into a live stream, I thought.
The first step was to find details of the stream that the Flash player interacts with, and luckily this is already solved by the Dropcam Ruby gem. Firing this up in irb allows us to find exactly what we need.
dropcam = Dropcam::Dropcam.new("YOUR_USERNAME", "YOUR_PASSWORD")
camera = dropcam.cameras.first
puts camera.stream.rtmp_details
{:app=>"nexus", :host=>"stream.dropcam.com", :playpath=>"93475eb827f8ac7392a3c83a99241c433", :variables=>{"S:"=>"2747ca2b38f93475eb8277392a3ac4941339c832f8ac"}}
Looking at the information we get back we now we have an application name, a host, a path and some sort of session token. Having found this information it’s worth checking if the stream credentials are valid by piping the output of rtmpdump into VLC.
$ rtmpdump --live --app nexus --host stream.dropcam.com --playpath 93475eb827f8ac7392a3c83a99241c433 --conn S:2747ca2b38f93475eb827f8ac7392a3c83a99241c4 | /Applications/VLC.app/Contents/MacOS/VLC
Once the information gives us a valid RTMP stream from Dropcam’s servers, we can move onto constructing a ffmpeg invocation which will open the RTMP stream, transcode to h.264 and output video in HTTP live streaming format. After some research on the ffmpeg mailing list, the resulting command line is:
ffmpeg -rtmp_app nexus -rtmp_conn S:2747ca2b38f93475eb827f8ac7392a3c83a99241c433 -rtmp_playpath 93475eb827f8ac7392a3c83a99241c4 -i rtmp://stream.dropcam.com/ -s 400x224 -c:v libx264 -b:v 300000 -vprofile baseline -preset medium -x264opts level=41 -hls_time 3 -hls_list_size 10 -hls_wrap 30 -start_number 1 stream.m3u8
This opens the RTMP stream, re-encodes the video as a 300 x 224px h.264 stream at a data rate of 300k and automatically creates a filed called stream.m3u8
which will continually be updated by the streaming process to point to the most recent video files.
The last step is to create a master m3u8 playlist file and an HTML page which will implement the video
tag to point at the master playlist. They look like:
master.m3u8
#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=300000
stream.m3u8
index.html
HTTP Live Streaming Example
<video width="400" height="224" src="master.m3u8" controls="controls">
</video>
If you ensure that the directory you’re creating the video files in is served over HTTP, then if you browse to the index.html file on your iOS device you should be able to hit the play button and start watching, app free.
There’s more detail to be found on HLS in ffmpeg from this thread on the ffmpeg mailing list http://ffmpeg.org/pipermail/ffmpeg-user/2013-May/014932.html.