itÃNew post: webstreaming with ffmpeg - monochromatic - monochromatic blog: http://blog.z3bra.org Err z3bra.org 70 hgit clone git://z3bra.org/monochromatic URL:git://z3bra.org/monochromatic z3bra.org 70 1Log /scm/monochromatic/log.gph z3bra.org 70 1Files /scm/monochromatic/files.gph z3bra.org 70 1Refs /scm/monochromatic/refs.gph z3bra.org 70 i--- Err z3bra.org 70 1commit ea5d78639c0ec73e577163083b8e0502c85e198e /scm/monochromatic/commit/ea5d78639c0ec73e577163083b8e0502c85e198e.gph z3bra.org 70 1parent 42c232ef2987b0e735909c75ee4c6b7139231d94 /scm/monochromatic/commit/42c232ef2987b0e735909c75ee4c6b7139231d94.gph z3bra.org 70 hAuthor: z3bra URL:mailto:willyatmailoodotorg z3bra.org 70 iDate: Tue, 30 Aug 2016 14:13:13 +0200 Err z3bra.org 70 i Err z3bra.org 70 iÃNew post: webstreaming with ffmpeg Err z3bra.org 70 i Err z3bra.org 70 iDiffstat: Err z3bra.org 70 i A 2016/08/desktop-streaming.txt | 179 +++++++++++++++++++++++++++++++ Err z3bra.org 70 i M config.mk | 3 ++- Err z3bra.org 70 i M index.txt | 1 + Err z3bra.org 70 i Err z3bra.org 70 i3 files changed, 182 insertions(+), 1 deletion(-) Err z3bra.org 70 i--- Err z3bra.org 70 1diff --git a/2016/08/desktop-streaming.txt b/2016/08/desktop-streaming.txt /scm/monochromatic/file/2016/08/desktop-streaming.txt.gph z3bra.org 70 it@@ -0,0 +1,179 @@ Err z3bra.org 70 i+# [Desktop streaming](#) Err z3bra.org 70 i+## — 30 August, 2016 Err z3bra.org 70 i+ Err z3bra.org 70 i+For teaching purposes (and cool internet points!) I recently needed Err z3bra.org 70 i+to share my screen and microphone online. Being the unix enthusiast Err z3bra.org 70 i+that I am, I looked into how I could do it "simple" command-line Err z3bra.org 70 i+tools. Err z3bra.org 70 i+ Err z3bra.org 70 i+And here comes [`ffmpeg`](http://ffmpeg.org). `ffmpeg` is the swiss Err z3bra.org 70 i+army knife for everything related to audio and video decoding/encoding. Err z3bra.org 70 i+I've been using it for multiple tasks already, from converting .ogg Err z3bra.org 70 i+to .mp3, to recording GIFs of my desktop. Err z3bra.org 70 i+ Err z3bra.org 70 i+### Server part Err z3bra.org 70 i+ Err z3bra.org 70 i+I started looking into how I could "stream" my desktop online, and Err z3bra.org 70 i+quickly found about the `ffserver` utility (which is part of the Err z3bra.org 70 i+`ffmpeg` package). Err z3bra.org 70 i+ Err z3bra.org 70 i+`ffserver` provides a service to do the following: Err z3bra.org 70 i+ Err z3bra.org 70 i+* Receive a "Feed" sent by one user Err z3bra.org 70 i+* Send a "Stream" to multiple users Err z3bra.org 70 i+ Err z3bra.org 70 i+A "Feed", from `ffserver` point, is a URL that a user will pass to Err z3bra.org 70 i+ffmpeg as the output media, to start "uploading" or "streaming" a Err z3bra.org 70 i+video to. `ffserver` will then start bufferizing this input locally, Err z3bra.org 70 i+and expose this raw buffer via a "Stream". A stream will read from Err z3bra.org 70 i+this buffer, and encode it in the specified format, with a bunch Err z3bra.org 70 i+of options. Err z3bra.org 70 i+ Err z3bra.org 70 i+One can specify multiple output streams for a single feed, eg, to Err z3bra.org 70 i+use different encoding formats. Err z3bra.org 70 i+ Err z3bra.org 70 i+Enough shittalks, here is what my `/etc/ffserver.conf` looked like: Err z3bra.org 70 i+ Err z3bra.org 70 i+ # Port 80 was taken by the webserver Err z3bra.org 70 i+ HTTPPort 8090 Err z3bra.org 70 i+ HTTPBindAddress 0.0.0.0 Err z3bra.org 70 i+ MaxHTTPConnections 64 Err z3bra.org 70 i+ MaxClients 28 Err z3bra.org 70 i+ MaxBandwidth 10000 Err z3bra.org 70 i+ Err z3bra.org 70 i+ CustomLog /var/log/ffserver.log Err z3bra.org 70 i+ Err z3bra.org 70 i+ # Where to send data. Err z3bra.org 70 i+ # URL will be: http://10.0.0.2:8090/0.ffm Err z3bra.org 70 i+ Err z3bra.org 70 i+ # buffer file and max size Err z3bra.org 70 i+ File /tmp/ffserver/0.ffm Err z3bra.org 70 i+ FileMaxSize 200K Err z3bra.org 70 i+ Err z3bra.org 70 i+ # Only allow this IP to send streaming data ACL Err z3bra.org 70 i+ allow 10.0.0.3 Err z3bra.org 70 i+ Err z3bra.org 70 i+ Err z3bra.org 70 i+ # How to expose the stream Err z3bra.org 70 i+ # URL will be: http://10.0.0.2:8090/0.flv Err z3bra.org 70 i+ Err z3bra.org 70 i+ # The feed to encode data from Err z3bra.org 70 i+ Feed 0.ffm Err z3bra.org 70 i+ Err z3bra.org 70 i+ # Video encoding options Err z3bra.org 70 i+ Format flv Err z3bra.org 70 i+ VideoCodec libx264 Err z3bra.org 70 i+ VideoFrameRate 5 Err z3bra.org 70 i+ VideoSize 1440x900 Err z3bra.org 70 i+ VideoBitRate 512 Err z3bra.org 70 i+ AVOptionVideo tune zerolatency Err z3bra.org 70 i+ AVOptionVideo flags +global_header Err z3bra.org 70 i+ Err z3bra.org 70 i+ # Audio encoding options Err z3bra.org 70 i+ AudioCodec aac Err z3bra.org 70 i+ AVOptionAudio flags +global_header Err z3bra.org 70 i+ Err z3bra.org 70 i+ Err z3bra.org 70 i+I limited my research for the perfect stream to either Err z3bra.org 70 i+[x264](https://wikipedia.org/wiki/X264) or Err z3bra.org 70 i+[vp8](https://wikipedia.org/wiki/Vp8) video encoding. At first, vp8 Err z3bra.org 70 i+seemed appealing, being a royalty-free format. The WEBM container Err z3bra.org 70 i+also seems to be pretty good for online videos. But x264 turned out Err z3bra.org 70 i+to be faster, and of higher quality (especially thanks to the Err z3bra.org 70 i+"zerolatency" setting). I had to switch to x264 also because I Err z3bra.org 70 i+couldn't get the libvorbis codec for audio to synchronize well with Err z3bra.org 70 i+the vp8 video stream. Err z3bra.org 70 i+ Err z3bra.org 70 i+The above configuration is the best quality/rapidity ratio I could Err z3bra.org 70 i+get. Err z3bra.org 70 i+ Err z3bra.org 70 i+When the config is ready, you just need to fire up the server with Err z3bra.org 70 i+ Err z3bra.org 70 i+ /usr/bin/ffserver -f /etc/ffserver.conf Err z3bra.org 70 i+ Err z3bra.org 70 i+### Watcher part Err z3bra.org 70 i+ Err z3bra.org 70 i+In order to watch the stream, one has to use the URL defined by the Err z3bra.org 70 i+ tag. I personally use `mplayer` to watch it, but one can Err z3bra.org 70 i+use the `ffplay` command provided by `ffmpeg`: Err z3bra.org 70 i+ Err z3bra.org 70 i+ ffplay http://10.0.0.2:8090/0.flv Err z3bra.org 70 i+ Err z3bra.org 70 i+And that's *ALL*. You can hardly do simpler to watch a stream, Err z3bra.org 70 i+right? Err z3bra.org 70 i+ Err z3bra.org 70 i+### Feeder part Err z3bra.org 70 i+ Err z3bra.org 70 i+In order to feed yor stream to the `ffserver`, you can use `ffmpeg` Err z3bra.org 70 i+directly. The format of the command is pretty simple. We have 2 Err z3bra.org 70 i+inputs: the video and the audio. We also have 1 output: the FFM Err z3bra.org 70 i+feed. The simplest command we can use is thus (recording our desktop, Err z3bra.org 70 i+and microphone): Err z3bra.org 70 i+ Err z3bra.org 70 i+ ffmpeg -f x11grab -i :0.0 -f alsa -i default http://10.0.0.2:8090/0.ffm Err z3bra.org 70 i+ Err z3bra.org 70 i+Let's break it down a bit: Err z3bra.org 70 i+ Err z3bra.org 70 i+* `-f x11grab -i :0.0`: Record the desktop, using `$DISPLAY` :0.0 Err z3bra.org 70 i+* `-f alsa -i default`: Record the microphone, using ALSA's default input device Err z3bra.org 70 i+* `http://10.0.0.2:8090/0.ffm`: Feed location Err z3bra.org 70 i+ Err z3bra.org 70 i+This should start recording, and sending data to the stream. If you Err z3bra.org 70 i+look at it, the output will not look really great, and we need to Err z3bra.org 70 i+pass a few more flags to get a nice looking output that will record Err z3bra.org 70 i+the full screen in a decent way: Err z3bra.org 70 i+ Err z3bra.org 70 i+ ffmpeg -f x11grab -r 5 -s 1440x900 -thread_queue_size 1024 -i :0.0 \ Err z3bra.org 70 i+ -f alsa -ac 1 -thread_queue_size 1024 -i default \ Err z3bra.org 70 i+ -af 'highpass=f=200, lowpass=f=2000' \ Err z3bra.org 70 i+ -fflags nobuffer \ Err z3bra.org 70 i+ http://10.0.0.2:8090/0.ffm Err z3bra.org 70 i+ Err z3bra.org 70 i+Ok, that was odd. no worries, I'm no wizard and didn't came up with Err z3bra.org 70 i+all these flags out of nowhere! Let's review them: Err z3bra.org 70 i+ Err z3bra.org 70 i+ -f x11grab -r 5 -s 1440x900 -i :0.0 Err z3bra.org 70 i+ Err z3bra.org 70 i+Record our X11 desktop with a framerate (`-r`) of 5 FPS, and record Err z3bra.org 70 i+the screen at size (`-s`) 1440x900 (my screen size). Err z3bra.org 70 i+ Err z3bra.org 70 i+ -f alsa -ac 1 -i default Err z3bra.org 70 i+ Err z3bra.org 70 i+Record from the default ALSA capture device, using MONO input Err z3bra.org 70 i+(`-ac`). Err z3bra.org 70 i+ Err z3bra.org 70 i+ -thread_queue_size 1024 Err z3bra.org 70 i+ Err z3bra.org 70 i+For both input, this is to increase the max number of queued packets Err z3bra.org 70 i+`ffmpeg` can handle. If the thread queue is full, `ffmpeg` will Err z3bra.org 70 i+start dropping packets, which can lower the stream quality. Err z3bra.org 70 i+ Err z3bra.org 70 i+ -af 'highpass=f=200, lowpass=f=2000' Err z3bra.org 70 i+ Err z3bra.org 70 i+Add an audio filter. My microphone is utter shit, and records a lot Err z3bra.org 70 i+of white noise. This filters out frequencies below 200Hz and above Err z3bra.org 70 i+2000Hz (that's the typical voice range). Err z3bra.org 70 i+ Err z3bra.org 70 i+ -fflags nobuffer Err z3bra.org 70 i+ Err z3bra.org 70 i+Avoid buffering frames when possible, so the stream is available Err z3bra.org 70 i+as it is recorded. Err z3bra.org 70 i+ Err z3bra.org 70 i+And that's pretty much it! Note that ffmpeg can have multiple Err z3bra.org 70 i+outputs, so you can record to the feed AND to a local file at the Err z3bra.org 70 i+same time. Err z3bra.org 70 i+ Err z3bra.org 70 i+For instance, this is my `ffstream` script: Err z3bra.org 70 i+ Err z3bra.org 70 i+ #!/bin/sh Err z3bra.org 70 i+ Err z3bra.org 70 i+ STREAM=${1:-http://10.0.0.2:8090/0.ffm} Err z3bra.org 70 i+ ffmpeg -f x11grab -r 5 -s 1440x900 -thread_queue_size 1024 -i :0.0 \ Err z3bra.org 70 i+ -f alsa -ac 1 -thread_queue_size 1024 -i default \ Err z3bra.org 70 i+ -af 'highpass=f=200, lowpass=f=2000' \ Err z3bra.org 70 i+ -fflags nobuffer ${STREAM} \ Err z3bra.org 70 i+ -af 'highpass=f=200, lowpass=f=2000' \ Err z3bra.org 70 i+ -c:v libvpx -b:v 5M -c:a libvorbis webcast-$(date +%Y%m%d%H%M%S).webm Err z3bra.org 70 i+ Err z3bra.org 70 i+That's all folks! Err z3bra.org 70 i+ Err z3bra.org 70 1diff --git a/config.mk b/config.mk /scm/monochromatic/file/config.mk.gph z3bra.org 70 it@@ -31,7 +31,8 @@ PAGES = index.html \ Err z3bra.org 70 i 2015/08/cross-compiling-with-pcc-and-musl.html \ Err z3bra.org 70 i 2015/08/install-alpine-at-onlinenet.html \ Err z3bra.org 70 i 2016/01/make-your-own-distro.html \ Err z3bra.org 70 i- 2016/03/hand-crafted-containers.html Err z3bra.org 70 i+ 2016/03/hand-crafted-containers.html \ Err z3bra.org 70 i+ 2016/08/desktop-streaming.html Err z3bra.org 70 i Err z3bra.org 70 i FEEDS = rss/feed.xml Err z3bra.org 70 i EXTRA = css img vid data errors favicon.ico Err z3bra.org 70 1diff --git a/index.txt b/index.txt /scm/monochromatic/file/index.txt.gph z3bra.org 70 it@@ -1,3 +1,4 @@ Err z3bra.org 70 i+* 0x001c - [Desktop streaming](/2016/08/desktop-streaming.html) Err z3bra.org 70 i * 0x001b - [Hand-crafted containers](/2016/03/hand-crafted-containers.html) Err z3bra.org 70 i * 0x001a - [Make your own distro](/2016/01/make-your-own-distro.html) Err z3bra.org 70 i * 0x0019 - [Install Alpine at online.net](/2015/08/install-alpine-at-onlinenet.html) Err z3bra.org 70 .