With a few open source tools, you can stream a playlist of videos in real-time over RTMP, MPEG-DASH, and HLS in a fully automated manner.

In this case, we’ll be using several software packages:

GStreamer/Libav for decoding and encoding

Liquidsoap for playlist management

nginx for the server

nginx-rtmp-module for providing HLS/MPEG-DASH/RTMP streaming

Using Ubuntu 14.XX (or possibly anything Debian-based) will be your shortest path of resistance, as compiling these packages by hand is a considerable chore and other distributions will likely lack many of these packages. If you want to use a different OS, you can virtualize Ubuntu, possibly with a lightweight container. You will not get very far with older versions of Ubuntu (such as 12.04) as they will also lack many of these packages.

GStreamer and Liquidsoap

GStreamer is a multimedia framework similar to DirectShow, in that it allows the linking together of components such as decoders, encoders, and so on to handle media. You’ll want to install the entirety of GStreamer if you want to play a wide variety of video formats. In addition, the “gstreamer1.0-libav” package enables you to make use of the Libav library to decode media.

Note: Libav is a hostile fork of the FFmpeg project and the relevant package maintainer for Debian/Ubuntu has chosen to distribute Libav rather than FFmpeg (which is still alive and kicking).

Then you’ll want to install Liquidsoap. Liquidsoap provides a powerful language to tie together multimedia components, and we’ll need it for playlist support. (It does a lot more though.)

sudo apt-get -y install liquidsoap liquidsoap-plugin-all

Be aware that you’ll also be installing all of LiquidSoap’s plugins (and dependencies). In reality, you do not need the whole package to simply stream a playlist, but you’ll have more freedom to play with LiquidSoap’s various features if you choose to install everything.

nginx and nginx-rtmp

Nginx is most well known to be a high-performance web server and reverse proxy, but the nginx-rtmp-module turns nginx into a streaming media server capable of speaking RTMP, MPEG-DASH, and Apple HTTP Live Streaming (HLS) protocols.

Flash-based video players will use RTMP, but HTML5/mobile players will use MPEG-DASH or HLS. The latter two protocols provide adaptive streaming, where videos are spliced into small chunks in real-time, allowing the client to switch to a lower quality “stream” in the middle of a video (see: YouTube).

Compiling from source

While nginx is readily available in the repositories on Debian/Ubuntu, it does not come with the nginx-rtmp-module, so we’ll have to compile nginx ourselves.

Configuring nginx

You’ll want to edit /etc/nginx/nginx.conf in your favorite editor and add the following section to the end of the file. Note that my snippet below will only configure nginx to provide a RTMP stream, but check out nginx-rtmp-module’s wiki to learn how to setup MPEG-DASH or HLS support.

Run your script file by executing liquidsoap stream.liq in your terminal. If all goes well, you should be able to watch your video by connecting to nginx as you had done before with the gst-launch tool.

Setting up a playlist

In conclusion

While the method I have outlined does work, it is not the only way to go about doing this. For example, you could concatenate a list of videos together with FFmpeg and send it off to your media server using the -realtime flag, skipping half of the steps in this article. You could even use one of those “screen streaming” programs with playlist support.

Remember also that video encoding (and to a smaller degree with most formats, decoding) is a CPU-intensive task. If you do not provide enough resources, the stream will stutter.

WorldEdit provides an easy-to-use API for Bukkit plugins to access the player’s current region selection.

A large part of WorldEdit uses an abstract internal API for easy portability For your convenience, we provide a Bukkit-native selection API that makes it easier to work with that part of WorldEdit. It is possible to “reach through” to access to the internal features of WorldEdit, but if you are interested in only getting selections, that shouldn’t be needed.

The game logic loop

The most important part of Minecraft is the game loop. In there is a clock keeping everything synchronized, going tick-tock at an ideally constant rate: twenty times per second, with each tick or tock lasting hopefully at most 50 milliseconds. During each cycle, game elements have to do their work — skeletons have to figure out where to walk, minecarts have to travel forward, grass has to spread, and light problems have to be checked. That’s a lengthy to-do list, considering how many blocks and entities are on a loaded world at at time (thousands). This tick-tock interval is called the tick rate or “TPS,” and you can get some mod or plugin to give you your server’s rate.

Quite a few things are on the to-do list, but as far as the “main game elements” go, those items are blocks, entities, and tile entities. Blocks include simple things such as sandstone, cobble, sugar cane, and things of that nature. Entities are your standard animals and monsters, in addition to paintings, item drops, and “objects that don’t fit perfectly on a grid.” Tile entities are a special kind of block, as they can hold any type of data (think storing an inventory, something sugar cane doesn’t have to do), and sometimes they must think separately. As previously mentioned, each loop has a budget of 50ms and each portion consumes some part of this pie. Any leftover time is considered idle.

Update: The man-in-the-middle attack described in this post is now ineffective as it was fixed in Minecraft 1.3, but the solution still works if you desire extra security.

A “session stealer” exploit in Minecraft is now being used increasingly widely to gain operator privileges on a target server. Anyone with the ability (or the freely available tools) can impersonate another user, which comes in handy to gain elevated privileges on a given server. The underlying exploit is actually extremely old, and while a small number of people have long been aware of it, news broke to the greater community recently and now it is a real relevant concern. On the flip side, the bug will finally be fixed (after three years) with the release of Minecraft 1.3. Hooray public disclosure.

But I don’t want to wait for a fix

If you run a server, it’s understandable that you would want a fix now. You can ensure that you don’t expose your own account, but you also have to ensure that your own moderators do not either. That can be harder than it sounds, especially depending on who you are working with, and so some — even minor — protection to use would be nice. Unfortunately, it is not possible to fix the problem from just the server’s side, and so people have attempted to work around the problem by using a mix of some rather inconvenient solutions (mostly involving a /login command). Instead, I decided on a different novel way to protect the accounts of my moderators, described below.

There’s this interesting exploit in Minecraft that lets you login under someone’s name without ever needing to know the person’s password. All the attacker needs to do is get you to join his/her server once. This client-side fix patches your game so that it won’t let your server tell you to authenticate against a “blank” server ID. Lymia and I reported it to Mojang a while ago, and while Jeb just put a fix in 1.8, there’s a mistake with the fix. You can download a ZIP to install it like any other mod (put the files into minecraft.jar), or Windows users can use the setup program to automatically install the fix:

A server-side fix has recently made it into a Bukkit, but your account can still be abused to join unpatched servers. This client-side patch prevents any server from exploiting your account. To understand how the exploit works, here’s a review of how Minecraft would authenticate for “Frank”:

Client->Server: Your game tells the server that it wants to join as “Frank”

Server->Client: The server responds with the ID “afe93b31c” (randomized)

Your game tells Minecraft.net that “Frank” is joining “afe93b31c”

Client->Server: The client tells the server that it’s ready

The server asks Minecraft.net to see if “Frank” has joined “afe93b31c” (if not, then the real Frank never joined the server)

Here’s how the exploit works: You get your victim to join your custom server that sends a blank ID. Frank’s game tells Minecraft.net that Frank is joining “” (a blank ID). Frank joins your server, plays around, and has no clue about what’s going on. You then join Frank’s server where Frank is an administrator, but you immediately skip to step #4: You tell the server that you already did step #3 and you get in. Why does this work? On the server, the server ID is blank if you never complete step 1, so in step #5, Frank’s server asks Minecraft.net if “Frank” has joined “”, which Frank did earlier but on your server.

From a more technical perspective, the hacked client never sends the initial handshake packet. The server ID starts out as a blank string, and it’s only initialized if you send the handshake packet. If you skip the handshake packet and just jump to the login packet, then the server ID stays as a blank string. Before 1.8, your client would freely accept a blank server ID. 1.8 prevents a server from giving you a blank server ID, but Lymia noticed that the game doesn’t URL-escape the server ID, so a server ID of “&” is essentially blank. The patch makes the routine URL-escapes the ID.

Addendum: Someone mentioned a “man-in-the-middle” attack that allows for name spoofing, but that’s a different issue that can only be fixed with significant changes to how Minecraft handles authentication. (A MITM is also more difficult to pull off well.)

Streams is a feature of PHP that was introduced in PHP 4.3 to unify the methods for working on files, sockets, and other similar resources. PHP 4.3 came out a long time ago, but many PHP developers never learned how to properly use streams in PHP, much to my dismay. Many use cURL for accessing HTTP resources, but I’m not a huge fan of cURL, because it has an awful interface in PHP and it presents yet another dependency. While the HTTP stream handler in PHP isn’t perfect, it works very well for most situations.

To begin, let’s consider what examples of streams could be:

A file on a hard drive

A HTTP connection to a website

A UDP connection to a server

A ZIP file

A SSH tunnel

A Vorbis/OGG file

What are some common operations on all of those? Primarily, they share the ability to be read from and written to. The power of PHP’s streams is that you can access all of them using the same set of functions, and if there’s something you wish to “stream-ify,” you can write your own “stream wrapper.” In addition to reading and writing, the streams framework in PHP also allows for other operations, such as renaming and deleting.

I had some videos I needed to work in batch, but I needed to resize them and keep their aspect ratio. AviSynth is a great video post-production utility, but its resize functions won’t add black bars. I’ve written the following AviSynth script to fix that. The following functions will also try to use an even width/height if the format requires it.