Stream from Desktop to XBMC with x11grab

Here I will explain what I did to stream my Desktop via WLAN to my raspberry pi box. My raspberry pi runs xbmc and is connected to a television. So the goal of this setup is to have the view of my computer displayed on the television.

This seems to be a very new subject since it was very hard to find ressources online. But now I succeeded and want to tell the internet :).

Available methods

While researching I think there are basically two methods available recording a video stream and watch it inside xbmc or use vnc.

The first idea was to use ffmpeg to create a video of my desktop and make a stream to xbmc. I preferred this idea very much because the stream is accessible from within xbmc. The problem I had was the video quality and the delay which got over 5seconds at least.

The other method is to use vnc. The desktop-pc is the server and the pi is the client. Because of my xbmc setup there is no X installed on the pi so the client should work without X. As far as I know this allows just one client: directvnc.

The video streaming method

As I said, this didn't work so good. But I'm also not good with ffmpeg and maybe I just misconfigured something. So I want to share what I did because some hurdles weren't so easy to figure out.

Setup the raspberry pi

Setting up XBMC was very straight forward. You just have to create a file test.strm with the content http://192.168.178.25:8090/stream.flv (the IP is of your desktop computer). And also a test.nfo file with the content

<movie>
    <title>ZZZ STREAM</title>
</movie>

so that it can be indexed in your moviedb. I called the title ZZZ so I can access it faster :).

Setup the desktop pc

Now the ffmpeg command for creating a playable .avi file:

ffmpeg -an -f x11grab -s 1366x768 -r 30 -i :0.0 -vcodec libx264 -profile:v main -pix_fmt yuv420p -threads 0 stream.avi

For 1366x768 you should insert your screen resolution. The hard part to figure out was -pix_fmt yuv420p because it will use yuv444 otherwise - which xbmc/raspberry pi can't play.

You could already stream with this when you have a webserver on your desktop pc. Just put it in the webfolder, correct the port and name in the test.strm above and start watching this .avi. Of course xbmc will always start from the beginning of the file so this doesn't work if you want to have input and output synchronized.

To solve this I use the ffserver command, which also comes with ffmpeg and has the purpose to stream the videodata. The setup of ffserver is done in /etc/ffserver.conf with following content

Port 8090
BindAddress 0.0.0.0
MaxHTTPConnections 5
MaxClients 5
CustomLog -

<feed stream.ffm>
  File /tmp/stream.ffm
  FileMaxSize 16M
</Feed>

<stream stream.flv>
  Feed stream.ffm
  Format flv

  NoAudio

  VideoCodec libx264
  VideoSize 1376x768
  # this PixelFormat setting only works in ffmpeg-2.x
  PixelFormat yuv420p
    AVOptionVideo flags +global_header
  AVOptionVideo me_range 16
  AVOptionVideo qmin 50
  AVOptionVideo qmax 51
</Stream>

To use ffserver I had to install ffmpeg 2.x because in all versions before the yuv420p setting couldn't be passed #1 #2.

After this configuration you start in one console ffserver without any arguments. And in another console you start ffmpeg: ffmpeg -an -f x11grab -s 1366x768 -r 30 -i :0.0 -vcodec libx264 http://localhost:8090/stream.ffm

With this setup you still get a delay of about 10 seconds. Perhaps you can reduce the buffer somehow. But then there is still the problem of the very bad videoquality.

Use VNC for streaming

I must say vnc works quite good. The only problem is, that it can't be started from inside xbmc.

Setup the desktop pc

I use x11vnc which seemed to be the easiest vnc-server. You start it with: x11vnc -viewonly And you are done :) A small sidenote: my setup is inside a trusted local network and I don't use a password for the vnc-server. But because vnc also allows one to use the mouse and keyboard or read sensitive information this shouldn't be done.

Setup the raspberry pi

To display something besides xbmc I think you have to shut it down. So first /etc/init.d/xbmc stop I use directvnc there. Which you ideally start with: directvnc 192.168.178.25 where you just need to insert the ip of your desktop-pc.

Bugs in raspbian directvnc package

But the raspbian installation for this tool is quite buggy. If you get Couldn't parse the keyboard mapping file (null). Exiting then it is this bug and you just need to add -m /nonexistant to the commandline.

I got further the error Couldnt resolve host! even when I entered my (existing) IP. This caused me to recompile directvnc and solve the -m bug and the host-bug.

So a short guide on how to compile it:

aptitude install autoconf libdirectfb-dev libjpeg8-dev zlib1g-dev
git clone https://github.com/drinkmilk/directvnc.git
cd directvnc
aclocal ; autoheader; automake ; autoconf
automake --add-missing ; automake ; autoconf
./configure
make
./src/directvnc 192.168.178.25

This was done on the raspberry pi and doesn't take long :)

Set the screensize

Per default directvnc displayed my desktop with 640x480. To change this open /etc/fb.modes. The first entry is which directvnc will automatically chose. So I copied another entry to the top. If you have problems with the margin here is a documentation. The margin are on the timings line.

Commentaires: