# How to set up VLC for web streaming (X11 only)

## Abstract

VLC is a separate application which can either read a plain file or a TS network stream. Using XSwallow, it is possible to incorporate VLC video output window right into the window of a browser. With additional tricks, it is also possible to launch a VLMS (VideoLAN MiniServer) on the server-side, and have the client read a live network stream. This document, intended for expert users only, describes the ways to do it.

## Installing and configuring XSwallow for plain MPEG files

XSwallow is a software which allows any X11 window to be "swallowed" (technically, just reparented, so that it has no effet on performance anyhow) into the window of a netscape-compatible browser (Navigator, Mozilla, Konqueror, Galeon, Opera...). This is indeed a trick in the X11 windowing model, and don't even expect to port this behaviour to any non-X11-based operating system, even supported by VLC (MS Windows, MacOS X, BeOS, QNX, ...).

Download it here : http://www.csn.ul.ie/~caolan/docs/XSwallow.html. Compilation is really straightforward, it basically boils down to some :

     make -f makefile.linux

Place the resulting xswallow.so in a directory scanned by your browser for plug-ins (for instance, /usr/lib/netscape/plugins, this scan path can with some browsers be read in $NPX_PLUGIN_PATH) and xswallow.conf in the directory indicated by the environment variable $MOZILLA_HOME. If it is currently unset, set it with for instance :

     export MOZILLA_HOME=/etc

Of course your mileage may vary. The last step is to customize xswallow.conf so that it launches VLC to handle MPEG files. Comment out all lines you don't need, and add :

    video/mpeg; mpeg,mpg,vob;   vlc -I dummy -V xvideo %s; VLC (XVideo output); VideoLAN

Notes :

- This assumes vlc is in your $PATH, if it is not the case, adapt it.
- If nothing shows up, it might be because VLC cannot find its plug-ins. Please check that they are in an appropriate place (such as /usr/lib/videolan/vlc). You can try to add -vvvvv to the arguments to see where it fails.
- The third field on the line is the actual name of the window to swallow. This is currently annoying, you will have to guess the name of the video output window, ie. changing the version number and the output plug-in (to SDL for instance if you use SDL). At present there is no way to force VLC to use a definite name, but it will be added by 0.2.90.
- When the window is first spawned, it will appear on screen and then be quicky reparented, making some flickering. The usual workaround is to make the window appear at offset +10000+10000 using the --geometry switch, but it is not currently supported by VLC. The will be addressed by 0.2.90 too.
- If your window manager isn't configured for automatic placement of new windows, it may ask you to manually place the window before XSwallow can swallow it. This is annoying, too. The only workaround is to disable the functionality (for instance with twm, add RandomPlacement in .twmrc). It will be addressed at the same time with --geometry.
- XSwallow will first download the file, and then launch VLC. There is no way to begin reading the stream before it is complete, à la QuickTime plug-in. This will be addressed in a future version of VLC (0.4). If you want to do live streaming, proceed to the next chapter.

From now on, if you have your browser reload its plug-in list, it will display VideoLAN as application handler for video/mpeg. You should now try and see what it yields.

## Tricks for live web streaming using VLMS

With a little trick, it is possible to stream a video using VLC and VLMS, and make it appear in a Web browser (without having a local copy of the file). This will only work if there is no firewall (nor masquerading) between the server and the client. It requires to have a CGI support built into the Web server.

Here is the sketch :

- The client requests a specific page, say video.html. This page contains an image tag to a file vlc.ts, AND launches a VLMS through a CGI script.
- The client receives the vlc.ts file which contains the address of the VLMS server, and through a special mime-type in XSwallow spawns a VLC.
- As soon as VLC begins to receive the stream, it is swallowed by XSwallow and appears in the browser's window.

### Configuring the Web server

In this section I will only give configuration directives for Apache. You need to add a new MIME type for TS stream in httpd.conf :

     AddType video/x-mpeg-ts .ts

And relaunch your Web server (apachectl reload). Next, create the vlc.html page. You need two specific lines, one to load vlc.ts, the other to start the VLMS server ; for instance in PHP (adapt it for Perl, Java, or whatever) :

    <img src="vlc.ts">
    <?php system("/var/www/cgi-bin/stream.sh $REMOTE_ADDR mystream.mpg > /dev/null 2>&1 &"); ?>

Where stream.sh is a simple shell script :

    #!/bin/sh
    vlms -d $1 -a mpeg $2

VLMS starts streaming mystream.mpg to $REMOTE_ADDR (the IP address fetched by the server, this is why you cannot do it through firewalls) on port 1234. Notes :

- The -a mpeg option may surprise you ; the VLMS doesn't preparse the stream and thus cannot know which audio channel to send. If you had an AC3 audio track, you could have put -a ac3. You can also activate subtitles with -s.
- VLMS only reads MPEG-1 files from version 0.2 on. If you have an older version, you may want to upgrade.
- It is possible that, due to the client latency, the client misses the first frames of the stream. I have no ideal workaround for this.
- Some streams (especially MPEG-1) only have one sequence header at the beginning of the stream. Since the client risks missing it, it may be completely unable to decode the stream _at all_. If you only get a blank screen, please try with another stream, such as one test stream on ftp://ftp.videolan.org/pub/videolan/streams before issuing a bug report.
- You should be careful that the stream.sh script is indeed launched in the background. If your CGI program waits for it, it doesn't hang up the connection until it finishes, and Web browsers wait for the connection to be closed before launching plug-ins. In that case you have nothing on screen, not even a Click to abort swallow message.

Finally, create the vlc.ts file. It just contains the address of the server, so that VLC can bind on it (you can't retrieve that from XSwallow). For instance :

     streaming.idealx.com

### Configuring XSwallow

You need to add an entry video/x-mpeg-ts in you xswallow.conf :

     video/x-mpeg-ts; ts; video-streaming.sh %s; VLC (XVideo output); VideoLAN

The same provisions as before apply here. The video-streaming.sh file is a simple shell script which retrieves the server's name and spawns VLC :

    #!/bin/sh
    SERVER=$( cat $@ )
    vlc -I dummy -V xvideo ts://$SERVER

Here you go. This is quite a hack, but it will hold until the next major release of VLC.

## Acknowledgements

This page has been written by Christophe Massiot for IDEALX S.A.S.
$Id$