crtmpserver convert rtsp streaming to rtmp streaming

Rtsp Broadcasting: 

Braodcast from android handset with the help of Rtsp Server from VXG (Google player)

IP:              Port: 5540

Resolution: 720X480

Bitrate:  Video=1000 kpbs,  Audio=64 kpbs

URL = rtsp://


Streaming Server:

Debian 8 with crtmpserver v1.1c

IP =

Enable RTSP source by add following definition in the externalStreams section of crtmpserver.lua:

externalStreams ={




Verify RTMP on Workstation :

ffplay rtmp://



Support rtmp and rtsp same time from crtmpserver

Enable rtsp inbound in accept section of config file:

acceptors =



Verify RTSP on Workstation :

ffplay rtsp://








Configuration file



The configuration file is actually a lua script which must contain an

object called configuration.

This will be read by the server and used to fully configure the server.

Besides this object called

configuration you can have functions, include other lua libraries, etc.

In the end, you have to

make the configuration object available. The rest of this section will

explain the structue of

configuration object in great detail. But first, let’s take an bird-eye








Main structure









— content removed for clarity




— content removed for clarity




configuration structure

key type    mandatory  description

daemon boolean    yes     true means the server will start in daemon mode.

false means it will start in console mode (nice for development)

true  表示 服务以后台方式启动;

false 表示 服务以控制台模式启动(以用于开发);

pathSeparator string(1) yes     This value will be used by the server to

compose paths (like media files paths).

Examples: on UNIX-like systems this is / while on windows is \.

Special care must be taken when you specify this values on windows

because \ is an escape sequence for lua so the value should be “\\”


例如,在UNIX-like是 /, Windows是 \  ;

logAppenders   object yes     Will hold a collection of log appenders. Each

of log messages will pass through all the log appenders enumerated here.

More details below

配置日志追加的容器 <>

applications   object yes     Will hold a collection of loaded applications.

Besides that, it will also hold few other values. More detailsbelow

配置加载各种应用的容器 <>


When the server starts, the following sequence of operations is performed:




The configuration file is loaded. Part of the loading process, is

the verification.

If something is wrong with the syntax please read this





daemon value is read. The server now will either fork to become daemon

or continue as is in console mode

读取 daemon 值,判断服务是以后台方式启动还是以控制台方式启动


logAppenders is read. This is where all log appenders are configured

and brought up to running state.

Depending on the collection of your log appenders, you may (not) see

further log messages




applications is taken into consideration. Up until now, the server

doesn’t do much.

After this stage completes, all the applications are fully

functional and the server is online and ready to do stuff







This section contains a list of log appenders. The entire collection of

appenders listed in this section

is loaded inside the logger at config-time. All log messages will be

than passed to all this log appenders.

Depending on the log level, an appender may (not) log the message.

“Logging” a message means “saving”

it on the specified “media” (in the example below we have a console

appender and a file).







name=”console appender”,





name=”file appender”,








logAppenders structure

key type    mandatory  description

name    string yes     The name of the appender. Is usually used inside

pretty print routines


type    string yes     The type of the appender. It can

be console, coloredConsole or file. console and

coloredConsole will output to console. The difference between them is

that coloredConsole

will also apply a color to the message, depending on the log level.

Quite useful when eye-balling the console.

file log appender will output everything on the specified file



控制台和带颜色控制台 都会将日志消息输出到控制台,



level   number yes     The log level used. The values are presented just

below. Any message having having a log level

less or equal to this value will be logged. The rest are discarded.

Example: setting level to 0, will only log FATAL errors.

Setting it to 3, will only log FATAL, ERROR, WARNING and INFO







级别为0时,只记录 FATAL 消息;


fileName   string yes     If the type of appender is a file, this will

contain the path of the file



Log levels

Name    Value




3   INFO


5   FINE



Observation: When daemon mode is set to true, all console appenders will

be ignored.

(Read the explanation for daemon setting here










This section is where all the applications inside the server are placed.

It holds the attributes of each application that the server will use to

launch them.

Each application may have specific attributes that it requires to

execute its own functionality.







— settings for application 1

— content removed for clarity



— settings for application 2

— content removed for clarity



— settings for application 3

— content removed for clarity





Applications Structure

key type    mandatory  description

rootDirectory string true    The folder containing applications

subfolders. If this path begins with a / or \ (depending on the OS),

than is treated as an absolute path. Otherwise is treated as a path

relative to the run-time directory

(the place where you started the server)


如果路径以 / 或 \ 开始, 则视其为绝对路径,否则视为启动服务时所在的相对



Following the rootDirectory, there is a collection of applications. Each

application has

its properties contained in an object. See details below

rootDirectory 之后,是应用的集合;每个应用都定义了一个有特定属性的对象;

细节如下所示; <>





Application Definition


This is where the settings of an application are defined. We will

present only the

settings common to all applications. Later on, we will also explain the

settings particular to certain

applications Since revision 790 there is a new cool feature:

mediaStorage; with this feature

basicaly an application may have multiple mediaFolder’s and .seek/.meta

files are now stored into

separate folder from media file that are streamed.










description=”FLV Playback Sample”,




— this settings are now part of mediaStorage setting

— keyframeSeek=true,

— seekGranularity=1.5,

— clientSideBuffer=12,

— generateMetaFiles=true,

— renameBadFiles=true,











acceptors =



— acceptor 1

— content removed for clarity



— acceptor 2

— content removed for clarity



— acceptor n

— content removed for clarity



— new feature mediaStorage

mediaStorage = {


description=”Main storage”,

mediaFolder=”/usr/main_storage/media”, — only this parameter IS


metaFolder=”/usr/main_storage/metadata”, — if you have static

large file to stream it is good to know that for a file around 500MB

— it’s .seek file has

around 16MB; so it would be preffer to designate metafolder into a system

— partition which has

enough space… for no surprises… :)




keyframeSeek=false, — should crtmpdserver DO SEEK ONLY IN

key-frame (true/false)?

— very useful to know in situations like

play/pause/resume (meaning pause/seek/play)






— here is another example of storage; it does not start with


description=”Second storage of same application”,






externalStreams =



— stream 1

— content removed for clarity



— stream 2

— content removed for clarity



— stream n

— content removed for clarity





— content removed for clarity








Application Structure

key type    mandatory  description

name    string yes     Name of application.



protocol   string yes     Type of application. The

value dynamiclinklibrary means the application is a shared library.


值为 dynamiclinklibrary 意即 应用是一个共享库

description    string no You can put a description of the application here.


default    boolean    no This flag designates the default application.

The default application is responsible in analyzing the connectrequest

and distribute the future connection to the correct application.



validateHandshake boolean    no Tells the server to validate the

client’s handshake before going further.

This is optional with a default value of true. If this is true and the

handshake fails,

the connection is dropped. If this is false, handshake validation will

not be enforced

and all the connections are accepted no matter if they are correctly

hand shaking or not.



如果这个值为真 且 握手失败,服务器就放弃这个连接。


keyframeSeek   boolean    no This instructs the streamer to seek only on

key frames. In case of live streaming, this is discarded.



seekGranularity    double no The seek resolution/granularity value in

seconds. Values are between 0.1 and 600.

For example, if granularity is 10 seconds, and a seek to t=2:34 is

desired, the seek

will actually go to t=2:30.

60seconds is recommended for full length movies and 1 second for video


搜索的精细度,以秒为单位, 值域定义在 0.1 ~ 600;


如果粒度定义为10秒,并期望定位到 t= 2:34;

则实际上是会定位到 t= 2:30.


clientSideBuffer   double no The amount of client side buffer that will

be maintained for each connection.

Values are between 5 and30 seconds.

每个连接在客户端的缓冲秒数,值定义在5 ~ 30 秒;

generateMetaFiles boolean    no This will generate seek/meta files on

application startup.

在应用启动前生成 seek/meta文件

renameBadFiles boolean    no If this flag is true and the media file

can’t be parsed, the media file will be renamed to *.bad.

Otherwise it will be left alone.

如果这上值为真且媒体文件是不能被解析的,则媒体文件被重命名为 *.bad,


aliases    object no The application will also be known by this name.


acceptors object no Acceptors hold the service that will be hosted to

the server. An application can have its own acceptor,

but this is not entirely required, and can be optional.



externalStreams    object no

authentication object no

mediaFolder    string yes     When define mediaStorage this field is

mandatory as it points out physical location of media files.

当定义了 mediaStorage时,这个域用来指定媒体文件的物理位置;

metaFolder string no It holds the location where .seek/.meta files

created from files inside mediaFolder are stored.

指定用来存放 .seek/.meta文件的位置;

statsFolder    string no Location for stats files.



Acceptor Structure

key type    mandatory  description

ip string yes     The IP where the service is located. means all

interfaces and all IPs.


port    string yes     Port number that the service will listen to.


protocol   string yes     The protocol stack handled by

the ip:port combination.

对应 ip:port的服务的协议

streaming misc

Media Player:



Let nginx support RTMP streaming,  & HLS


Let nginx support seek in mp4 file, with timestamp included in mp4



Setting up HLS live streaming server using NGINX + nginx-rtmp-module on Ubuntu







Learning rtmpdump Through Examples

Learning rtmpdump Through Examples

by pstranger

Today, technology goes forward and we get some new possibilities. TV broadcasting doesn’t lose time and goes forward too. Today, you can watch online TV and watch TV programs on demand. But what if you want to record them? Don’t worry – some programs and live broadcasting (not all yet) can be recorded.

If you are not so young, then you can remember the VCR (video cassette recorder) era. You could turn on your video recorder, push the “Record” button, stop it after some time and after rewinding the tape you could play a recorded program on your TV. So what does the computer era offer?

Some theory

Today, TV broadcasting via internet goes in many popular stream formats and protocols.

You have certainly heard about such streaming formats:

  • flash video streams (Adobe Flash Player): FLV, MP4, F4V
  • Windows media streams (Windows Media Player): WMV, ASF, ASX and others.

There are also various streaming protocols. Examples of streaming protocols:

  • flash video: HTTP, RTMP, RTMPE
  • Windows media video: HTTP, RTSP, MMS and others.

Let’s take a look at services which are broadcasting in the RTMP protocol. What is it? Wikipedia says: “Real Time Messaging Protocol (RTMP) was initially a proprietary protocol developed by Macromedia for streaming audio, video and data over the Internet, between a Flash player and a server. Macromedia is now owned by Adobe, which has released the specification of the protocol for public use.”

So if your favorite online service (TV or video archive) uses the RTMP protocol you have a good chance of being able to save its video stream as a file on your local drive. There is an excellent utility for recording streams broadcasting TV and video on demand. This utility is called “rtmpdump.” What is it? “rtmpdump” is a console toolkit for RTMP streams. Does the word “console” mean advantage or disadvantage in this case? I think it is big advantage for such a tool. Its operating principle is simple: you input the name of a command with some options, which include the address of the video server, and get a desirable file containing the recorded TV program. You will see no graphical input on the screen, nor other useless information. It just connects to the server, consuming only the network traffic containing the video, and records it to your hard disk. If you know about the powerful “wget” utility, then you can imagine what it is like.


It’s time to start. To have “rtmpdump” in your operational system, you should install the package having the same name from the repository. This package goes with another utility, which is called “rtmpsuck.” This tool can also record video stream, but we will use it as auxiliary tool to find options for “rtmpdump.”

In order to use “rtmpsuck,” we need some preparation. “rtmpsuck” is a local RTMP proxy server which passes traffic into the internet through itself, detecting the flowing RTMP protocol and it’s parameters. “rtmpsuck” goes with no parameters. So if you run “rtmpsuck” you can only see:

RTMP proxy server … … Streaming on rtmp://

What that says is that the server is running and listening on port 1935. It’s necessary to notice that port 1935 is a default port of RTMP servers. But in this case, “rtmpsuck” is useless. Why? Because to make it work, you need to redirect RTMP traffic to a proxy server, which in turn will help us to know the connection parameters to the media server. To do this, you need to run the following command as a “root”:

iptables -t nat -A OUTPUT -p tcp --dport 1935 -m owner \! --uid-owner root -j REDIRECT

The meaning of this command is to add a new rule in the table controlling your network traffic in order to redirect outbound TCP traffic flowing to the default RTMP external server port (1935) to a local RTMP proxy server, except traffic which belongs to root. So, if you now open a page in you browser to watch a media stream, your traffic will flow via the proxy server, and “rtmpsuck” will provide you information which can be used in “rtmpdump.” After getting all the information, you can close “rtmpsuck” (Ctrl+C) and must remove the “iptabels” rule which you added before:

iptables -t nat -D OUTPUT -p tcp --dport 1935 -m owner \! --uid-owner root -j REDIRECT
    1. Example: Online IP TV broadcasting (“Russia Today”)

Step 1 Run as a root in terminal:

iptables -t nat -A OUTPUT -p tcp --dport 1935 -m owner \! --uid-owner root -j REDIRECT

Step 2 Run as a root in terminal:


Step 3 As an ordinary user, open in Firefox this address:

Step 4 Switch to root’s terminal. You should see something like the following:

app: live flashVer: LNX 10,1,82,76
tcUrl: rtmp://
Playpath: RT_US_3

Break the command after a while (Ctrl+C).

Depending on your connection quality, you can get different meanings of the option “Playpath”.

You can change the options of video quality by using the following entries after the command Playpath:

RT_US_3 – high
RT_US_2 – medium
RT_US_1 – low

Step 5 Run the command in root terminal:

iptables -t nat -D OUTPUT -p tcp --dport 1935 -m owner \! --uid-owner root -j REDIRECT

Step 6 Run the command in terminal as an ordinary user:

rtmpdump -r rtmp:// \
-a live \
-y RT_US_3 \ -W \
-p \
-f "LNX 10,1,82,76" \
-o ~/rt.flv \
-V \
-B 600

After 10 minutes, you will get the video file “rt.flv” in your home directory which you can play in your favorite media player.

You can know what these parameters mean if you run the manual of command “rtmpdump”:

man rtmpdump

Option -V is just verbose, turn it off if your test recording is passed.

Exercise 1: If you live in Europe or Asia (or if it is just convenient to you), you can try to get the parameters for main broadcasting. Firefox address is

    1. Example: Online IP TV broadcasting (“Bloomberg”)

Repeat steps 1 through 5 for address

Step 6 Run the following command in terminal as an ordinary user:

rtmpdump -r rtmpt:// \
-a live \
-y us_300@21006 \
-W \
-p \
-f "LNX 10,1,82,76" \
-o ~/bloomberg.flv \
-V \
-B 600 \

Here we added the option “– live” to make utility work right.

    1. Example: TV streaming LIVE (“Euronews”)

The address of streaming broadcasting is:

“rtmpsuck” gives us the next:

app: rtpeuronewslive
flashVer: LNX 10,1,82,76
tcUrl: rtmp://
Playpath: eng_euronews-flash-750.sdp

so our command will be:

rtmpdump -r rtmp:// \
-a rtpeuronewslive \
-y eng_euronews-flash-750.sdp \
-W \
-p \
-f "LNX 10,1,82,76" \
-o ~/euronews.flv \
-B 600
    1. Example: Video on demand (“Deutsche Welle”)

There are many good programs you can find on this page:,,4756,00.html

But if you try above technique, disappointment will wait for you. The reason for this is the video server is broadcasting on a different port. If you look into the source code of “rtmpsuck” you can see that default port of RTMP server (1935) is hard-coded, and that is why “rtmpsuck” is not a helper to us in this case.

The tool that will help us is called “tcpdump.” It is a console network sniffer. The nice feature of this tool is that it can show only printable symbols contained in network packets, which is handy for capturing web pages and this kind of stuff. If this tool is not yet installed on your system, you should do it now. The next utility is “grep” which helps to print lines matching a pattern which can be set.

Let’s get one of the excellent programs about lifestyle Europe, which is called “Euromaxx.” We assume that RTMP proxy server is not running and redirection traffic is turned off.

Step 1 Run as a “root” in terminal next set of commands:

tcpdump -ieth0 -nn -A |grep -e"rtmp" -e"connect" -e"play">/euromaxx.txt

It means that strings which included patterns (rtmp, connect or play) containing in network traffic and flowing trough network interface (eth0 in my case) will be recorded in file “euromaxx.txt,” which will be located in root directory (“/”).

Step 2 As an ordinary user, open in Firefox page:!/93184/euromaxx/Program=7555 and start to play the video. Wait a moment for the video to start to play, click the “pause” button on the built-in player, and click the “Update page” button on Firefox. Repeat this action 4 times.

Step 3 Go to root terminal and break running commands (Ctrl+C).

Step 4 Open the file “euromaxx.txt” in text editor and find piece of text:

a4337/dwwod1/..flashVer...LNX 10,1,82,76..swfUrl..;*rtmpt:// videoFunction.?.........pageUrl..K!/93184/euromaxx/Program=7555..object.Encoding.@.........;mp4:dwtv_video/flv/eme/emagen100311-euromaxx01ep_sd_avc.mp4

Now you can easily determinate options for “rtmpdump”.

Step 5 Run command in terminal as ordinary user:

rtmpdump -r rtmpt:// \
-a a4337/dwwod1/ \
-y mp4:dwtv_video/flv/eme/emagen100311-euromaxx01ep_sd_avc.mp4 \
-f "LNX 10,1,82,76" \
-W \
-p!/93184/euromaxx/Program=7555 \
-o ~/euromaxx.flv

After a while you will find the recorded program in your home directory.

The pitfall of this technique is that you can meet dots in an inappropriate place in the string. The reason for this is the fact that the text string, which should be continuous, is situated in two network packets and “tcpdump” changes unprintable symbols to dots. So, if something goes wrong, then place the key -V into you “rtmpdump” command and look at the debug messages. If “rtmpdump” can’t even connect to the server, then the reason in this case is rather a wrong URL.

Finishing stroke

There is a natural desire to record some program on a schedule (placing recording script for example in “cron”). If you will use the same file name of a recorded video program, then you will rewrite the previous one. In order to avoid this, it is very convenient to use the file name which contains the name of the broadcasting server, including the date and time of the recording. The next script shows the usage of this trick for our first TV broadcasting example:

FILENAME="$BASENAME"_`date +%Y-%m-%d_%H%M%S`.flv
rtmpdump -r rtmp:// \
-y RT_US_3 \
-o ~/$FILENAME \
-B 1200

Exercise 2: Write a script for the scheduler in order to record a program which was yesterday in the last video on demand example using this hint:

YESTERDAY=$(date -d yesterday +"%d%m%y")

The answers will appear elsewhere in this issue of magazine. Also, you can find more information about streaming media recording on this site

Remove GPT from a disk under ubuntu

Suppose /dev/sdb is the device to be cleand


sudo apt-get install gdisk

sudo gdisk /dev/sdb

> Enter 2,  select GPT

> Enter  ?,  get command list

> Enter x,   expert mode

> Enter ?,  get command list

> Enter z,   destroy GPT


# create dos partition table, and partition

sudo fdisk /dev/sdb

# format the dos partition,   say /dev/sdb1

sudo mkfs.msdos /dev/sdb1

Install lighttpd on ubuntu

sudo apt-get update

sudo apt-get upgrade

sudo apt-get install lighttpd

modify lighttpd configuration ==> sudo nano /etc/lighttpd/lighttpd.conf

  • Disable global dir listing :  server.dir-listing          = “enable”  ==> server.dir-listing          = “disable”
  • Add alias of url:   alias.url = (
                  “/img/”         => “/www/image/”,
                  “/fp/”          => “/www/flowplayer/”,
                  “/Google_I_O/”  => “/usr/share/red5/dist/webapps/root/Google_I_O/”,
                  “/assets/”      => “/usr/share/red5/dist/webapps/root/assets/”,
                  “/download/”    => “/data/download/”,
                  “/dl/”          => “/data/download/”
  • Enable dir listing for the specified url:  $HTTP[“url”] =~ “^/dl/|^/download/|^/Google_I_O/” {
        dir-listing.activate = “enable”
  • Enable module of mod_flv_streaming

sudo /usr/sbin/lighty-enable-mod cgi

sudo /etc/init.d/lighttpd  force-reload