, 3 min read
Streaming Desktop with Audio to the Internet
Task at hand: You want to show your desktop including audio to a person in another country.
This task is similar to watching YouTube with multiple people using w2g.tv.
1. Terms used.
- FFmpeg, initially developed by Fabrice Bellard. Name comes from "Fast Forward MPEG".
- HLS or "HTTP Live Streaming"
- Native HLS Playback by Gaetan Hervouet
- m3u8, a simple file format providing the list of media files available for download
- AAC, successor of MP3 audio codec
Using information from
- ArchWiki on FFmpeg
- Martin Riedl on HLS streaming server
- FFmpeg Trac entry regarding pulseaudio
- FFmpeg Trac entry regarding capturing your desktop
2. Solution. The command on the server side, machine trying to offer its desktop, is:
ffmpeg -f x11grab -s 1280x720 -framerate 15 -i $DISPLAY \
-f pulse -i default -c:v libx264 \
-crf 21 -preset veryfast -g 25 -sc_threshold 0 \
-c:a aac -b:a 128k -ac 2 \
-f hls -hls_time 4 -hls_list_size 3 -hls_flags delete_segments \
stream.m3u8
This way ffmpeg will continuously produce streamXXXX.ts files, thereby continuously updating stream.m3u8
, for example:
$ ls stream*
stream1579.ts stream1580.ts stream1581.ts stream1582.ts stream.m3u8
By using delete_segments
they are deleted all the time. In above example 3+1 files are kept. See ffmpeg(1) and ffmpeg-all(1). Without delete_segments
you would stay with 1582 files, taking the above list as an example.
The directory, where all these stream-files are produced, must now be "published" via any web-server. There is no need for any extra plugin or module on the web-server side.
Assume all streamXXXX.ts files are in /tmp
. From your web-server root you symlink to /tmp
via
cd /srv/http
ln -s /tmp ffmpeg
Then the URL in the web-browser is
http://<YourAddress>/ffmpeg/stream.m3u8
x11grab
allows to specify a specific window (window_id
), or part of the screen, see x11grab. Use the xwininfo
program to find the window-id. Use xdpyinfo
to find resolution of your display. Streaming a particular window is thus:
ffmpeg -f x11grab -window_id 0xa00002 -framerate 15 -i $DISPLAY ...
3. Client side. According the HLS wiki Apple devices support HLS out of the box. Google Chrome does not. For Google Chrome you have to use the HLS extension. On Android I had no luck with Google Chrome, but with VLC for Android you can then watch HLS.
4. Unsuccessful attempts. I was not able to get RTP working using different machines.
ffmpeg -f x11grab -s 1280x720 -framerate 15 -i $DISPLAY -f rtp rtp://0.0.0.0:1234
Client side:
ffplay -i sdp -protocol_whitelist file,udp,rtp
Content of the sdp file is the output of above ffmpeg
command.