Archive for March, 2012

NGINX RTMP: Introducing asynchronous HTTP callbacks

This week I have finally implemented an extremely important feature – HTTP callbacks. The callbacks let move business logic away from RTMP server (for example to PHP).

The AMF handler implementation has been changed again since the last update to make callbacks really asynchronous. Now AMF call handlers are not stored in one place but chained by NGINX modules. Each module saves the last handler in a static variable and substitutes it with its own. The previous handler is called in the end of this module’s handler. That gives great power to tear handler chain at any node. If for example a handler makes an HTTP request (using async send/recv handlers) it simply saves the handler context and returns from handler. When HTTP reply comes back it parses the result and invokes the next handler with the context saved.

Currently there are two modules implementing such callbacks: netcall module & notify module. The former provides basic (NGINX HTTP upstream-like) implementation of network AMF handler. It needs two handlers – one for creating request data and another for parsing the reply. Remember there’s nothing about HTTP in this module. Any request-response network protocol is compatible with this module. The notify module is built on top of netcall module. It provides the following ready-to-use HTTP callbacks:

  • on_publish
  • on_play
  • on_record_done

The request is made with HTTP POST method and content-type of application/x-www-form-urlencoded. All session data as well as handler arguments are passed to HTTP server with this calls. The first and the second callbacks use HTTP result code to make decision about further AMF handler processing. On success (2xx) the next AMF handler is called. On error (anything but 2xx) the AMF handler returns error and RTMP connection is closed. Remember the third call (on_record_done) does not expect any result. It only notifies you about flv file ready passing its full path along with other call arguments.

Leave a comment

New features in NGINX RTMP module: apps, flvs, dispatcher

Coding at night and morning have brought a great improvement! I have finally got application support. It looks similar to NGINX’s locations but much simpler (no partial matches, no regex etc). According to Adobe’s docs that’s exactly what RTMP protocol was designed for.

The next fix in writing FLVs. As it turned out FLV format is really simple to record from RTMP. Header is 100% constant. Stream data is saved in ‘tags’ which is nothing else but RTMP messages with headers. Two directives were added today: record & max_record.

There’s another very important improvement that was made today. I’ve finally implemented a dispatcher module for AMF0 calls – cmd_module. It registers callbacks for commonly used AMF0 calls (connect, play, publish etc) and does all AMF0-related job like reading query fields and replying with tons of protocol messages and reply objects.

Version 0.0.10 is now capable of live streaming, access control, flv recording.

New fixes lead to the following conf:

application mytv { 
 live on; 
 record /tmp/av; 
 record_size 3000000; 
} 

Leave a comment

Announcing NGINX RTMP module

I want to announce NGINX RTMP module which makes NGINX a streaming video server. By the moment there is already working live video/audio streaming.

Today I’ve implemented a fix in RTMP protocol. As it became clear from here, flash clients do not follow the spec when handling (& emitting) type 3 RTMP packets. The spec says these packets should never have extended timestamp field (which makes much sense). However in real life flash clients do add such field when the head chunk of the current message has extended timestamp. Type 3 fragments just carry the 4-byte copy of the timestamp in addition to 1-byte header. Looks really ulgy.

, , ,

Leave a comment