crtmpserver实现防盗流和流推送验证 之二

IV. Catching the thieves
抓住小偷

Well, we have just added a secure mechanism to our little streaming server. 
Now, all we have to do is just watching log file. But, before doing that we have to 
download a small utility for viewing our log file. This utility is called Kiwi Log Viewer, 
we can download it from 
前面,我们为流媒体服务器添加了一个安全机制;
现在,我们需要做的是研究日志文件,
但在这之前,我们先下载一个日志文件查看的工具,Kiwi Log Viewer
可以在这下载:
  http://www.solarwinds.com/register/kiwi_registration.aspx?Program=884&c=70150000000EIWt .




So, to make our lives easier, first thing to look for is that if the pageUrl is from domain(s) 
that we expected (taking here for example second scenario as for the first it is the same thing 
differs only domain);
为了使我们的工作更加轻松, 首先要查找的是pageUrl是从我们期待的域名来的,
命令如下:

ameeran cmake# tail -f /tmp/rtmpserver.log | egrep '<STR name="pageUrl">'

and the results would be…
而结果可能是:

<STR name="pageUrl">http://www.a-queens.ro/testswf.html</STR>

as long as we see our domain in pageUrl it is ok
可以看到结果是我们想要的;

Now, let's simulate a copy&paste action like in second scenario when we calling the page from 
a domain that it is not defined in our fileter rules (http://www.curier.ro/testswf1.html)
再来看对不起第二个场景中的复制&粘贴后的调用日志:

ameeran cmake# tail -f /tmp/rtmpserver.log | egrep '<STR name="pageUrl">'
                <STR name="pageUrl">http://www.a-queens.ro/testswf.html</STR>
                <STR name="pageUrl">http://www.curier.ro/testswf1.html</STR>

it seems that one of our many streams it was called from outside. we want, for curiosity, 
to see who's trying to leech us.
从上面的结果可以看到,有多个外部访问来获取我们的流,
出于好奇,我们想看看到底是谁在捣蛋:

1. copy log file (/tmp/rtmpserver.log) into your user home directory or somewhere into your 
   server structure where you have access to download it into your desktop pc;
   将日志文件从服务器下载到你的PC;
2. download log file into your desktop;
   将日志文件放在桌面
3. open Kiwi Log Viewer (or other utility of this kind if you have already one) and load log file;
   打开刚下载的那个工具并加载日志文件
4. search for value of pageUrl that is not from our domain(s);
   查找外部来的pageUrl; 
FIG.7 

查找值 finding value:
FIG.8 

查看连接的IP view connection ip:  
FIG.9


V. Combining protected streams (from above) with PUBLISHING streams via FMLE
盗流防护与FMLE推流保护的联合使用 

when we need, beside protecting our streams for viewing, at the same time, to be able to 
publish streams via FMLE and to have some protection mechanism over it. we are going to 
setup up rtmpd to pick up publish streams via FMLE and show them into a webpage and, 
in the same time, to enjoy that protection that we have achieved above.
有时,我们除了要防备盗流,还要对通过FMLE推送的流做一些保护;
要实现这点,需要对通过FMLE推送上来的流,在rtmpd中做一些设置;
并且可以配合上面的盗流防护一起使用;

So, to have it worked we need to have a different approach because there is FMLE authentication 
as well in the picture. We will have our example to default playground application, 
flvplayback for simplicity. We must overwrite all Inkove process includind InvokeConnect 
then testing if userAgent it is a flash authenticate one (FMLE or Wirecast) then go to 
authentication if not go to filtering Uri.ip. Our practical example will be from SECOND SCENARIO 
only that we add FMLE publishing&authentication.
为了实现这个机制,我们需要有不同的方法来实现对FMLE的授权验证;
我们的示例程序是使用默认的播放应用 flvplayback; 
需要重写所有的 Inkove 处理,包括 InvokeConnect,
然后测试 userAgent是否被授权(FMLE 或 Wirecast), 
然后测试它是不是需要过滤的Uri.ip;
在我们的实际例子中,将会对第二种场景添加FMLE 发布&授权。

Logical flow:
处理逻辑:
1. if there is not adobe auth (or compatible) then skip to 4.
   如果不是 adobe 授权(或兼容)的客户端,直接转到 4; 


2. if there is adobe auth (or compatible) compare flashVer with encoderAgents {} 
   from config file (rtmpserver.lua); if flashVer is not listed skip to 4.
   如果是 adobe 授权(或兼容) 的客户端,则比较配置文件(rtmpserver.lua)中的encoderAgents{}
   中的 flashVer值,如果值不匹配则转到4;


3. if there is adobe auth (or compatible) and flashVer is listed into encoderAgents {}, 
   then we call basic class function BaseRTMPAppProtocolHandler::ProcessInvokeConnect(pFrom, request) 
   which automatically will be authenticated with username/password. Then skip to 5.
   如果是 adobe授权(或兼容)的客户端,且 flashVer 值在 encoderAgents{} 获得了匹配,
   则调用基类函数 BaseRTMPAppProtocolHandler::ProcessInvokeConnect(pFrom, request),
   它将会自动验证 用户名/密码,
   然后转到5;
4. validate our tcUrl, swfUrl, pageUrl and Uri.ip from InitialRequest
   在 InitialRequest中验证 tcUrl, swfUrl, pageUrl, 和 Uri.ip 


5. everything it ok; go ahead!
   所有验证都通过后,继续往下走;

1. download source into new folder, as /usr/local/rtmpd
   下载源码到一个新的文件夹中,如 /usr/local/rtmpd

ameeran / # cd /usr/local
ameeran local # svn co --username anonymous https://svn.rtmpd.com/crtmpserver/branches/1.0 rtmpd


2. go to flvplayback source directory
进入 flvplayback源目录

ameeran local # cd rtmpd/sources/application/flvplayback
ameeran flvplayback #

3. modify rtmpappprotocolhandler.h to add 2 functions for validate
修改 rtmpappprotocolhandler.h , 添加两个验证函数


show code
ameeran flvplayback # edit include/rtmpappprotocolhandler.h
ameeran flvplayback # cat include/rtmpappprotocolhandler.h
/*
 *  Copyright (c) 2010,
 *  Gavriloaie Eugen-Andrei (shiretu@gmail.com)
 *
 *  This file is part of crtmpserver.
 *  crtmpserver is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  crtmpserver is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with crtmpserver.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 
#ifdef HAS_PROTOCOL_RTMP
#ifndef _RTMPAPPPROTOCOLHANDLER_H
#define _RTMPAPPPROTOCOLHANDLER_H
 
#include "protocols/rtmp/basertmpappprotocolhandler.h"
 
namespace app_flvplayback {
 
        class RTMPAppProtocolHandler
        : public BaseRTMPAppProtocolHandler {
        public:
                RTMPAppProtocolHandler(Variant &configuration);
                virtual ~RTMPAppProtocolHandler();
 
                virtual bool ProcessInvokeGeneric(BaseRTMPProtocol *pFrom,
                                Variant &request);
                virtual bool ProcessInvokeConnect(BaseRTMPProtocol *pFrom,
                                Variant &request);
                virtual bool ValidateRequest(Variant &request);
 
        private:
                bool ProcessGetAvailableFlvs(BaseRTMPProtocol *pFrom, Variant &request);
                bool ProcessInsertMetadata(BaseRTMPProtocol *pFrom, Variant &request);
        };
}
#endif  /* _RTMPAPPPROTOCOLHANDLER_H */
#endif /* HAS_PROTOCOL_RTMP */


rtmpappprotocolhandler.h source code: http://pastebin.com/raw.php?i=JYYPQuqh


4. modify rtmpappprotocolhandler.cpp to add our magic source code
修改 rtmpappprotocolhandler.cpp ,添加源码:
show code
ameeran flvplayback # edit src/rtmpappprotocolhandler.h
ameeran flvplayback # cat src/rtmpappprotocolhandler.h
/*
 *  Copyright (c) 2010,
 *  Gavriloaie Eugen-Andrei (shiretu@gmail.com)
 *
 *  This file is part of crtmpserver.
 *  crtmpserver is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  crtmpserver is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with crtmpserver.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 
#ifdef HAS_PROTOCOL_RTMP
#include "rtmpappprotocolhandler.h"
#include "protocols/rtmp/basertmpprotocol.h"
#include "protocols/rtmp/messagefactories/messagefactories.h"
#include "application/baseclientapplication.h"
#include "streaming/baseinnetstream.h"
#include "streaming/streamstypes.h"
using namespace app_flvplayback;
 
RTMPAppProtocolHandler::RTMPAppProtocolHandler(Variant &configuration)
: BaseRTMPAppProtocolHandler(configuration) {
 
}
 
RTMPAppProtocolHandler::~RTMPAppProtocolHandler() {
}
 
bool RTMPAppProtocolHandler::ProcessInvokeGeneric(BaseRTMPProtocol *pFrom,
                Variant &request) {
 
        string functionName = M_INVOKE_FUNCTION(request);
        if (functionName == "getAvailableFlvs") {
                return ProcessGetAvailableFlvs(pFrom, request);
        } else if (functionName == "insertMetadata") {
                return ProcessInsertMetadata(pFrom, request);
        } else {
                return BaseRTMPAppProtocolHandler::ProcessInvokeGeneric(pFrom, request);
        }
}
 
// adding functions for filter validations
bool RTMPAppProtocolHandler::ProcessInvokeConnect(BaseRTMPProtocol *pFrom, Variant &request) {
        //1. Get the request params
        if (M_INVOKE_PARAMS(request).MapSize() < 1) {
                FATAL("Invalid request");
                return false;
        }
        Variant connectParameters = M_INVOKE_PARAM(request, 0);
 
        if (_authMethod != "") {
                //we have adobe auth enabled
                string flashVer = connectParameters[RM_INVOKE_PARAMS_CONNECT_FLASHVER];
                if (!_configuration[CONF_APPLICATION_AUTH][CONF_APPLICATION_AUTH_ENCODER_AGENTS].HasKey(flashVer)) {
                        //this connection will not be authenticated, so we will try to validate the URI's
                        if (!ValidateRequest(request)) {
                                FATAL("Invalid connect request");
                                return false;
                        }
                }
        } else {
                //we don't have adobe auth enabled at all. We will try to validate the URI's
                if (!ValidateRequest(request)) {
                        FATAL("Invalid connect request");
                        return false;
                }
        }
 
 
        return BaseRTMPAppProtocolHandler::ProcessInvokeConnect(pFrom, request);
}
 
bool RTMPAppProtocolHandler::ValidateRequest(Variant &request) {
        //TODO: Validate the various URI's inside the request here
        //0. Dump the request on console, just to see its structure
       FINEST("Initial request:\n%s", STR(request.ToString()));
 
       //1. Get the connect params from the connect invoke
       Variant connectParams = M_INVOKE_PARAM(request, 0);
 
       //2. This should be a key-value map
       if (connectParams != V_MAP) {
               FATAL("Incorrect invoke params:\n%s", STR(request.ToString()));
               return false;
       }
 
        //3. Let's extract few values. Make sure we extract them using non-case-sensitive keys
        Variant tcUrl = connectParams.GetValue(RM_INVOKE_PARAMS_CONNECT_TCURL, false);
 
        //If you are sure about case-sensitive settings, you can extract it directly like this
        Variant swfUrl = connectParams[RM_INVOKE_PARAMS_CONNECT_SWFURL];
        //Variant tcUrl = connectParams[RM_INVOKE_PARAMS_CONNECT_TCURL];
        Variant pageUrl = connectParams[RM_INVOKE_PARAMS_CONNECT_PAGEURL];
 
 
        //4. Do some validation on them.
 
        if (pageUrl != V_STRING) {
               FATAL("Incorrect "RM_INVOKE_PARAMS_CONNECT_PAGEURL": %s", STR(request.ToString()));
                return false;
        }
 
        if (tcUrl != V_STRING) {
                FATAL("Incorrect "RM_INVOKE_PARAMS_CONNECT_TCURL":\n%s", STR(request.ToString()));
                return false;
        }
 
        string rawURI;
        URI uri;
        if (!URI::FromString(pageUrl, true, uri)) {
                FATAL("Unable to parse the uri %s", STR(rawURI));
                return false;
        }
 
        // as proto we are going to validate rtmp/rtmpe
        // added if/elseif/else and INFO like Andriy suggested
         if (((string) tcUrl) != "rtmp://media.bfy.ro/livestream") {
             INFO("Connect schema is \'%s\'", STR((string) tcUrl));
         } else if (((string) tcUrl) != "rtmpe://media.bfy.ro/livestream") {
            INFO("Connect schema is \'%s\'", STR((string) tcUrl));
         }
         else {
                FATAL("Incorrect "RM_INVOKE_PARAMS_CONNECT_TCURL": %s", STR(request.ToString()));
                return false;
         }
        // we use our static flowplayer which is always on the same address
        // added if/elseif/else and INFO like Andriy suggested
         if (((string) swfUrl) != "http://www.a-queens.ro/flowplayer/flowplayer-3.2.5.swf") {
             INFO("Flash player address is \'%s\'", STR((string) swfUrl));
         } else if (((string) swfUrl) != "http://www.a-queens.ro/player.swf") {
             INFO("Flash player address is \'%s\'", STR((string) swfUrl));
         }
         else {
              FATAL("Incorrect "RM_INVOKE_PARAMS_CONNECT_SWFURL": %s", STR(request.ToString()));
              return false;
         }
 
        // ip which resolve our calling webpage(s)/website(s)
        // added if/elseif/else and INFO like Andriy suggested
        if (((string) uri.ip) == "86.122.125.158") {
                 INFO("Stream calling webpage is \'%s\'", STR((string) pageUrl));
                 INFO("stream Calling webpage IP is \'%s\'", STR((string) uri.ip));
        }
        else {
             FATAL("Incorrect "RM_INVOKE_PARAMS_CONNECT_PAGEURL": %s", STR(request.ToString()));
             return false;
        }
 
        return true;
        //NYIR;
}
 
bool RTMPAppProtocolHandler::ProcessGetAvailableFlvs(BaseRTMPProtocol *pFrom, Variant &request) {
        Variant parameters;
        parameters.PushToArray(Variant());
        parameters.PushToArray(Variant());
 
        vector<string> files;
        if (!ListFolder(_configuration[CONF_APPLICATION_MEDIAFOLDER], files)) {
                FATAL("Unable to list folder %s",
                                STR(_configuration[CONF_APPLICATION_MEDIAFOLDER]));
                return false;
        }
 
        string file, name, extension;
 
        FOR_VECTOR_ITERATOR(string, files, i) {
                file = VECTOR_VAL(i);
 
                splitFileName(file, name, extension);
                extension = lowercase(extension);
 
                if (extension != MEDIA_TYPE_FLV
                                && extension != MEDIA_TYPE_MP3
                                && extension != MEDIA_TYPE_MP4
                                && extension != MEDIA_TYPE_M4A
                                && extension != MEDIA_TYPE_M4V
                                && extension != MEDIA_TYPE_MOV
                                && extension != MEDIA_TYPE_F4V
                                && extension != MEDIA_TYPE_TS
                                && extension != MEDIA_TYPE_MKV)
                        continue;
                string flashName = "";
                if (extension == MEDIA_TYPE_FLV) {
                        flashName = name;
                } else if (extension == MEDIA_TYPE_MP3) {
                        flashName = extension + ":" + name;
                } else {
                        if (extension == MEDIA_TYPE_MP4
                                        || extension == MEDIA_TYPE_M4A
                                        || extension == MEDIA_TYPE_M4V
                                        || extension == MEDIA_TYPE_MOV
                                        || extension == MEDIA_TYPE_F4V) {
                                flashName = MEDIA_TYPE_MP4":" + name + "." + extension;
                        } else {
                                flashName = extension + ":" + name + "." + extension;
                        }
                }
 
 
                //        FINEST("Parsing `%s`", STR(flashName));
                //        Variant v = GetMetaData(flashName, true);
                //        if (v != V_NULL)
                parameters[(uint32_t) 1].PushToArray(flashName);
        }
 
        map<uint32_t, BaseStream *> allInboundStreams =
                        GetApplication()->GetStreamsManager()->FindByType(ST_IN_NET, true);
 
        FOR_MAP(allInboundStreams, uint32_t, BaseStream *, i) {
                parameters[(uint32_t) 1].PushToArray(MAP_VAL(i)->GetName());
        }
 
        Variant message = GenericMessageFactory::GetInvoke(3, 0, 0, false, 0,
                        "SetAvailableFlvs", parameters);
 
        return SendRTMPMessage(pFrom, message);
}
 
bool RTMPAppProtocolHandler::ProcessInsertMetadata(BaseRTMPProtocol *pFrom, Variant &request) {
        //STREAMING REFACTORING
        //    //FINEST("request:\n%s", STR(request.ToString()));
        //
        //    //1. Get the stream name
        //    if ((VariantType) M_INVOKE_PARAM(request, 1) != V_STRING)
        //        return true;
        //    string streamName = M_INVOKE_PARAM(request, 1);
        //
        //    //2. Get the stream
        //    vector<BaseOutboundStream *> streams = FindOSByName(streamName);
        //    BaseInboundStream *pInboundStream = NULL;
        //
        //    FOR_VECTOR(streams, i) {
        //        if (streams[i]->GetProtocol()->GetId() == pFrom->GetId()) {
        //            pInboundStream = streams[i]->GetInboundStream();
        //            break;
        //        }
        //    }
        //    if (pInboundStream == NULL) {
        //        FINEST("This stream is not yet bound");
        //        return true;
        //    }
        //    if (pInboundStream->IsEnqueueForDelete()) {
        //        FINEST("This stream will be deleted soon");
        //        return true;
        //    }
        //
        //    //3. Prepare the FlexStreamSend message
        //    Variant params;
        //    params.PushToArray(M_INVOKE_PARAM(request, 2));
        //    return pInboundStream->SendStreamMessage("onMetaData", params);
        NYIR;
}
#endif /* HAS_PROTOCOL_RTMP */
rtmpappprotocolhandler.cpp source code: http://pastebin.com/raw.php?i=cvHQTcGT

5. creating users file (or modify existing one to our needs)
创建用户文件(或修改现在的)

ameeran flvplayback # cd /usr/local/rtmpd/builders/cmake/applications/flvplayback/
ameeran flvplayback # cat users.lua
users=
{
        user1="password1",
        user2="password2"
}
modify this file in order to give our users access via username/password.


6. modify default config file regarding our needs; for simplicity, like both scenarios 
above we will make a basic config file where our main streaming application we will assign 
an alias as livestream to be called from within webpages or FMLE (Wirecast):
按我们的需要修改默认的配置文件;
为了简单起见,上面的两个场景都使用相同的一个简单的配置文件;


show code
ameeran flvplayback # cd /usr/local/rtmpd/builders/cmake/rtmpserver/
ameeran rtmpserver # mv rtmpserver.lua rtmpserver.lua_old
ameeran rtmpserver # touch rtmpserver.lua
ameeran rtmpserver # edit rtmpserver.lua
ameeran rtmpserver # cat rtmpserver.lua
-- Start of the configuration. This is the only node in the config file.
-- The rest of them are sub-nodes
configuration=
{
        -- if true, the server will run as a daemon.
        -- NOTE: all console appenders will be ignored if this is a daemon
        daemon=false,
        -- the OS's path separator. Used in composing paths
        pathSeparator="/",
        -- this is the async DNS resolver. This is a "clinet" connection
        -- to the server.
        dnsResolver=
        {
                -- the DNS resolver will connect to ip:port.
                -- Whe a request of resolving a domain is made, instead of
                -- using gethostbyname, we will pass that request to ip:port
                -- This way, the request is async. Of course, it can be looped back
                ip="127.0.0.1",
                port=9311,
                acceptors =
                {
                        {
                                ip="0.0.0.0",
                                port=9311,
                                protocol="inboundDns"
                        },
                }
        },
        -- this is the place where all the logging facilities are setted up
        -- you can add/remove any number of locations
        logAppenders=
        {
                {
                        -- name of the appender. Not too important, but is mandatory
                        name="console appender",
                        -- type of the appender. We can have the following values:
                        -- console, coloredConsole and file
                        -- NOTE: console appenders will be ignored if we run the server
                        -- as a daemon
                        type="coloredConsole",
                        -- the level of logging. 6 is the FINEST message, 0 is FATAL message.
                        -- The appender will "catch" all the messages below or equal to this level
                        -- bigger the level, more messages are recorded
                        level=6
                },
                {
                        name="file appender",
                        type="file",
                        level=6,
                        -- the file where the log messages are going to land
                        fileName="/tmp/rtmpserver.log"
                }
        },
        -- this node holds all the RTMP applications
        applications=
        {
                -- this is the root directory of all applications
                -- usually this is relative to the binary execuable
                rootDirectory="applications",
                --this is where the applications array starts
                {
                        -- The name of the application. It is mandatory and must be unique
                        name="appselector",
                        -- Short description of the application. Optional
                        description="Application for selecting the rest of the applications",
                        -- The type of the application. Possible values are:
                        -- dynamiclinklibrary - the application is a shared library
                        protocol="dynamiclinklibrary",
                        -- the complete path to the library. This is optional. If not provided,
                        -- the server will try to load the library from here
                        -- <rootDirectory>/<name>/lib<name>.{so|dll|dylib}
                        -- library="/some/path/to/some/shared/library.so"
                        -- Tells the server to validate the clien's handshake before going further.
                        -- It is optional, defaulted to true
                        validateHandshake=true,
                        -- this is the folder from where the current application gets it's content.
                        -- It is optional. If not specified, it will be defaulted to:
                        -- <rootDirectory>/<name>/mediaFolder
                        -- mediaFolder="/some/directory/where/media/files/are/stored"
                        -- the application will also be known by that names. It is optional
                        --aliases=
                        --{
                        --      "simpleLive",
                        --      "vod",
                        --      "live",
                        --},
                        -- This flag designates the default application. The default application
                        -- is responsable of analyzing the "connect" request and distribute
                        -- the future connection to the correct application.
                        default=true,
                        acceptors =
                        {
                                {
                                        ip="0.0.0.0",
                                        port=1935,
                                        protocol="inboundRtmp"
                                },
                                {
                                        ip="0.0.0.0",
                                        port=8081,
                                        protocol="inboundRtmps",
                                        sslKey="server.key",
                                        sslCert="server.crt"
                                },
                                {
                                        ip="0.0.0.0",
                                        port=8080,
                                        protocol="inboundRtmpt"
                },
                        }
                },
                {
                        description="FLV Playback Sample",
                        name="flvplayback",
                        protocol="dynamiclinklibrary",
                        mediaFolder="/usr/local/media",
                        aliases=
                        {
                                "vod",
                                "live",
                                "livestream",
                        },
                        acceptors =
                        {
                                {
                                        ip="0.0.0.0",
                                        port=1935,
                                        protocol="inboundRtmfp"
                                },
                                {
                                        ip="0.0.0.0",
                                        port=6666,
                                        protocol="inboundLiveFlv",
                                        waitForMetadata=true,
                                },
                                {
                                        ip="0.0.0.0",
                                        port=9999,
                                        protocol="inboundTcpTs"
                                },
                                {
                                            ip="0.0.0.0",
                                            port=10000,
                                            protocol="inboundUdpTs"
                                },
                        },
                        externalStreams =
                        {
                        },
                        validateHandshake=true,
                        keyframeSeek=true,
                        seekGranularity=60, --in seconds, between 0.1 and 600
                        clientSideBuffer=12, --in seconds, between 5 and 30
                        --generateMetaFiles=true, --this will generate seek/meta files on application startup
                        authentication=
                        {
                              type="adobe",
                              encoderAgents=
                              {
                                      "FMLE/3.0 (compatible; FMSc/1.0)",
                                      "FME/2.5 (compatible; FMSc/1.0)", --added for compatibility
                                      "Wirecast/FM 1.0 (compatible; FMSc/1.0)", --added for wirecast
                                      "GNU 10,0,32,18", --added for block recording with rtmpdump from linux/unix
                                      "WIN 10,0,32,18", --added for block recording with rtmpdump from windows
                              }
                              --usersFile="users.lua",
                        }
                },
                {
                                name="admin",
                                description="Application for administering",
                                protocol="dynamiclinklibrary",
                                aliases=
                                {
                                        "rtmpd_admin",
                                },
                                acceptors =
                                {
                                        {
                                                ip="0.0.0.0",
                                                port=1112,
                                                protocol="inboundJsonCli",
                                                useLengthPadding=true
                                        },
                                }
                                --validateHandshake=true,
                                --default=true,
                 },
                --#INSERTION_MARKER# DO NOT REMOVE THIS. USED BY appscaffold SCRIPT.
        }
}
ameeran rtmpserver #
rtmpserver.lua source code: http://pastebin.com/raw.php?i=Hs04SAkw

6. compile and make rtmpd
编译并生成 rtmpd

show code
ameeran rtmpserver # cd ..
ameeran cmake # cmake .
-- The C compiler identification is GNU
-- The CXX compiler identification is GNU
-- Check for working C compiler: /usr/bin/gcc
-- Check for working C compiler: /usr/bin/gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Looking for openssl headers - found
-- Looking for openssl library - found
-- Looking for crypto library - found
-- Looking for dl
-- Looking for libdl headers - found
-- Looking for libdl library - found
-- We have support for precompiled headers
-- Check if the system is big endian
-- Searching 16 bit integer
-- Looking for sys/types.h
-- Looking for sys/types.h - found
-- Looking for stdint.h
-- Looking for stdint.h - found
-- Looking for stddef.h
-- Looking for stddef.h - found
-- Check size of unsigned short
-- Check size of unsigned short - done
-- Using unsigned short
-- Check if the system is big endian - little endian
-- We have a Linux-2.6.32-gentoo-r7 system
-- Defines are in place
-- Configuring done
-- Generating done
-- Build files have been written to: /usr/local/rtmpd/builders/cmake
ameeran cmake # make
Scanning dependencies of target lua
[  0%] Building C object lua/CMakeFiles/lua.dir/usr/local/rtmpd/3rdparty/lua-dev/lgc.c.o
[  1%] Building C object lua/CMakeFiles/lua.dir/usr/local/rtmpd/3rdparty/lua-dev/lzio.c.o
[  1%] Building C object lua/CMakeFiles/lua.dir/usr/local/rtmpd/3rdparty/lua-dev/ltm.c.o
[  1%] Building C object lua/CMakeFiles/lua.dir/usr/local/rtmpd/3rdparty/lua-dev/ldump.c.o
[  2%] Building C object lua/CMakeFiles/lua.dir/usr/local/rtmpd/3rdparty/lua-dev/liolib.c.o
[  2%] Building C object lua/CMakeFiles/lua.dir/usr/local/rtmpd/3rdparty/lua-dev/lparser.c.o
[  2%] Building C object lua/CMakeFiles/lua.dir/usr/local/rtmpd/3rdparty/lua-dev/lvm.c.o
[  3%] Building C object lua/CMakeFiles/lua.dir/usr/local/rtmpd/3rdparty/lua-dev/lcode.c.o
[  3%] Building C object lua/CMakeFiles/lua.dir/usr/local/rtmpd/3rdparty/lua-dev/lobject.c.o
[  3%] Building C object lua/CMakeFiles/lua.dir/usr/local/rtmpd/3rdparty/lua-dev/lopcodes.c.o
[  4%] Building C object lua/CMakeFiles/lua.dir/usr/local/rtmpd/3rdparty/lua-dev/lmem.c.o
[  4%] Building C object lua/CMakeFiles/lua.dir/usr/local/rtmpd/3rdparty/lua-dev/lfunc.c.o
[  4%] Building C object lua/CMakeFiles/lua.dir/usr/local/rtmpd/3rdparty/lua-dev/lstrlib.c.o
[  4%] Building C object lua/CMakeFiles/lua.dir/usr/local/rtmpd/3rdparty/lua-dev/linit.c.o
[  5%] Building C object lua/CMakeFiles/lua.dir/usr/local/rtmpd/3rdparty/lua-dev/lundump.c.o
[  5%] Building C object lua/CMakeFiles/lua.dir/usr/local/rtmpd/3rdparty/lua-dev/lstring.c.o
...
Linking CXX shared library libthelib.so
[ 75%] Built target thelib
Scanning dependencies of target rtmpserver
[ 76%] Building CXX object rtmpserver/CMakeFiles/rtmpserver.dir/usr/local/rtmpd/sources/rtmpserver/src/rtmpserver.cpp.o
Linking CXX executable rtmpserver
[ 76%] Built target rtmpserver
Scanning dependencies of target flvplayback
[ 77%] Building CXX object applications/flvplayback/CMakeFiles/flvplayback.dir/usr/local/rtmpd/sources/applications/flvplayback/src/rtspappprotocolhandler.cpp.o
[ 77%] Building CXX object applications/flvplayback/CMakeFiles/flvplayback.dir/usr/local/rtmpd/sources/applications/flvplayback/src/rtpappprotocolhandler.cpp.o
[ 77%] Building CXX object applications/flvplayback/CMakeFiles/flvplayback.dir/usr/local/rtmpd/sources/applications/flvplayback/src/rtmpappprotocolhandler.cpp.o
[ 78%] Building CXX object applications/flvplayback/CMakeFiles/flvplayback.dir/usr/local/rtmpd/sources/applications/flvplayback/src/liveflvappprotocolhandler.cpp.o
[ 78%] Building CXX object applications/flvplayback/CMakeFiles/flvplayback.dir/usr/local/rtmpd/sources/applications/flvplayback/src/tsappprotocolhandler.cpp.o
[ 78%] Building CXX object applications/flvplayback/CMakeFiles/flvplayback.dir/usr/local/rtmpd/sources/applications/flvplayback/src/rtmfpappprotocolhandler.cpp.o
[ 79%] Building CXX object applications/flvplayback/CMakeFiles/flvplayback.dir/usr/local/rtmpd/sources/applications/flvplayback/src/flvplaybackapplication.cpp.o
[ 79%] Building CXX object applications/flvplayback/CMakeFiles/flvplayback.dir/usr/local/rtmpd/sources/applications/flvplayback/src/flvplayback.cpp.o
Linking CXX shared library libflvplayback.so
[ 79%] Built target flvplayback
Scanning dependencies of target appselector
...
Scanning dependencies of target tests
[ 98%] Building CXX object tests/CMakeFiles/tests.dir/usr/local/rtmpd/sources/tests/src/commontestssuite.cpp.o
[ 99%] Building CXX object tests/CMakeFiles/tests.dir/usr/local/rtmpd/sources/tests/src/thelibtestssuite.cpp.o
[ 99%] Building CXX object tests/CMakeFiles/tests.dir/usr/local/rtmpd/sources/tests/src/varianttestssuite.cpp.o
[ 99%] Building CXX object tests/CMakeFiles/tests.dir/usr/local/rtmpd/sources/tests/src/basetestssuite.cpp.o
[100%] Building CXX object tests/CMakeFiles/tests.dir/usr/local/rtmpd/sources/tests/src/main.cpp.o
Linking CXX executable tests
[100%] Built target tests
ameeran cmake #

7. starting up the beauty ;)
启动 rtmpd

show code
ameeran cmake # ./rtmpserver/rtmpserver ./rtmpserver/rtmpserver.lua &
ameeran cmake # /usr/local/rtmpd/sources/rtmpserver/src/rtmpserver.cpp:168 Plug in the default protocol factory
/usr/local/rtmpd/sources/rtmpserver/src/rtmpserver.cpp:175 Initialize I/O handlers manager: epoll
/usr/local/rtmpd/sources/rtmpserver/src/rtmpserver.cpp:178 Initialize DNS resolver
/usr/local/rtmpd/sources/thelib/src/netio/epoll/iohandlermanager.cpp:96 Handlers count changed: 0->1 IOHT_ACCEPTOR
/usr/local/rtmpd/sources/thelib/src/netio/epoll/iohandlermanager.cpp:96 Handlers count changed: 1->2 IOHT_TCP_CONNECTOR
/usr/local/rtmpd/sources/rtmpserver/src/rtmpserver.cpp:184 Initialize applications
/usr/local/rtmpd/sources/thelib/src/netio/epoll/iohandlermanager.cpp:96 Handlers count changed: 2->3 IOHT_ACCEPTOR
/usr/local/rtmpd/sources/thelib/src/netio/epoll/iohandlermanager.cpp:96 Handlers count changed: 3->4 IOHT_ACCEPTOR
/usr/local/rtmpd/sources/thelib/src/netio/epoll/iohandlermanager.cpp:96 Handlers count changed: 4->5 IOHT_ACCEPTOR
/usr/local/rtmpd/sources/thelib/src/configuration/configfile.cpp:787 Application "appselector" is up and running
/usr/local/rtmpd/sources/thelib/src/netio/epoll/iohandlermanager.cpp:96 Handlers count changed: 5->6 IOHT_UDP_CARRIER
/usr/local/rtmpd/sources/thelib/src/netio/epoll/iohandlermanager.cpp:96 Handlers count changed: 6->7 IOHT_ACCEPTOR
/usr/local/rtmpd/sources/thelib/src/netio/epoll/iohandlermanager.cpp:96 Handlers count changed: 7->8 IOHT_ACCEPTOR
/usr/local/rtmpd/sources/thelib/src/configuration/configfile.cpp:787 Application "flvplayback" (vod,live,livestream) is up and running
/usr/local/rtmpd/sources/thelib/src/netio/epoll/iohandlermanager.cpp:96 Handlers count changed: 8->9 IOHT_ACCEPTOR
/usr/local/rtmpd/sources/thelib/src/configuration/configfile.cpp:787 Application "admin" (rtmpd_admin) is up and running
/usr/local/rtmpd/sources/rtmpserver/src/rtmpserver.cpp:190 Install the quit signal
/usr/local/rtmpd/sources/rtmpserver/src/rtmpserver.cpp:193 Install the conf re-read signal
/usr/local/rtmpd/sources/rtmpserver/src/rtmpserver.cpp:200
+-----------------------------------------------------------------------------+
|                                                                     Services|
+---+---------------+-----+-------------------------+-------------------------+
| c |      ip       | port|   protocol stack name   |     application name    |
+---+---------------+-----+-------------------------+-------------------------+
|tcp|        0.0.0.0| 9311|               inboundDns|                   #none#|
+---+---------------+-----+-------------------------+-------------------------+
|tcp|        0.0.0.0| 1935|              inboundRtmp|              appselector|
+---+---------------+-----+-------------------------+-------------------------+
|tcp|        0.0.0.0| 8081|             inboundRtmps|              appselector|
+---+---------------+-----+-------------------------+-------------------------+
|tcp|        0.0.0.0| 8080|             inboundRtmpt|              appselector|
+---+---------------+-----+-------------------------+-------------------------+
|udp|        0.0.0.0| 1935|             inboundRtmfp|              flvplayback|
+---+---------------+-----+-------------------------+-------------------------+
|tcp|        0.0.0.0| 6666|           inboundLiveFlv|              flvplayback|
+---+---------------+-----+-------------------------+-------------------------+
|tcp|        0.0.0.0| 9999|             inboundTcpTs|              flvplayback|
+---+---------------+-----+-------------------------+-------------------------+
|tcp|        0.0.0.0| 1112|           inboundJsonCli|                    admin|
+---+---------------+-----+-------------------------+-------------------------+
 
/usr/local/rtmpd/sources/rtmpserver/src/rtmpserver.cpp:201 GO! GO! GO! (18927)
/usr/local/rtmpd/sources/thelib/src/netio/epoll/iohandlermanager.cpp:96 Handlers count changed: 9->10 IOHT_TCP_CARRIER
/usr/local/rtmpd/sources/thelib/src/netio/epoll/tcpacceptor.cpp:134 Client connected: 127.0.0.1:37514 -> 0.0.0.0:9311
/usr/local/rtmpd/sources/thelib/src/netio/epoll/iohandlermanager.cpp:96 Handlers count changed: 10->11 IOHT_TCP_CARRIER
/usr/local/rtmpd/sources/thelib/src/netio/epoll/iohandlermanager.cpp:105 Handlers count changed: 11->10 IOHT_TCP_CONNECTOR
Well, so far so good. No errors ;)


Testing server setup
测试服务器的设置

1. Streaming online static files and test protection
在线媒体流文件和测试

Remember our testing setup from above, III. Testing? Well we have to do some modifications 
into those .html pages and we will use jwplayer since both players will pass our validation rules.
我们对前面的测试用html页面做些修改,以添加验证机制

预约定 prerequests

a simple .html file into webroot of a-queens.ro domain;
jwplayer suite into webroot directory of a-queens.ro domain (player.swf and .js files)

期望 expectations

calling webpage(s) to be from a-queens.ro domain;
flash player webadress to be http://www.a-queens.ro/player.swf;
tcUrl schema to be
rtmp://media.bfy.ro/livestream
or
rtmpe://media.bfy.ro/livestream


1. create on webroot directory of www.a-queens.ro our test page, 
testswf_els.html (testswf Eduardo Luis Scenario) as:
创建测试页面的路径并修改页面代码如下:


show code
<html>
<head><title>Eduardo Luis Secenario - swf test page</title>
<body>
 
<div style="margin-left: 15px; margin-top: 55px;">
<script type='text/javascript' src='jwplayer.js'></script>
<script type='text/javascript' src='swfobject.js'></script>
 
<div id='mediaspace'>This text will be replaced</div>
 
<script type='text/javascript'>
  var so = new SWFObject('player.swf','mpl','470','290','9');
  so.addParam('allowfullscreen','true');
  so.addParam('allowscriptaccess','always');
  so.addParam('wmode','opaque');
  so.addVariable('file','wild');
  so.addVariable('provider','rtmp');
  so.addVariable('streamer','rtmpe://media.bfy.ro/livestream');
  so.write('mediaspace');
</script>
 
</div>
</body>
</html>    


2. run the webpage address of test file
打开测试页面:
FIG.10


and in the background:
在rtmpd的输出信息可以看到:

show code
/usr/local/rtmpd/sources/thelib/src/netio/epoll/tcpacceptor.cpp:134 Client connected: 86.122.125.158:57133 -> 0.0.0.0:1935
/usr/local/rtmpd/sources/thelib/src/netio/epoll/iohandlermanager.cpp:96 Handlers count changed: 10->11 IOHT_TCP_CARRIER
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:71 Register protocol CTCP(15) <-> TCP(15) <-> [IR(16)] to application appselector
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/inboundrtmpprotocol.cpp:105 New protocol chain: CTCP(15) <-> [TCP(15)] <-> RE(17) <-> IR(16)
/usr/local/rtmpd/sources/applications/appselector/src/rtmpappprotocolhandler.cpp:83 Selected application: flvplayback (livestream)
/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:152 Protocol CTCP(15) <-> TCP(15) <-> RE(17) <-> [IR(16)] unregistered from application: appselector
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:71 Register protocol CTCP(15) <-> TCP(15) <-> RE(17) <-> [IR(16)] to application flvplayback
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:1189 This agent is not on the list of allowed encoders: `WIN 10,1,102,64`
/usr/local/rtmpd/sources/applications/flvplayback/src/rtmpappprotocolhandler.cpp:85 Initial request:
<MAP name="" isArray="false">
    <MAP name="header" isArray="false">
        <UINT32 name="channelId">3</UINT32>
        <UINT8 name="headerType">3</UINT8>
        <BOOL name="isAbsolute">false</BOOL>
        <UINT32 name="messageLength">329</UINT32>
        <UINT8 name="messageType">20</UINT8>
        <UINT32 name="streamId">0</UINT32>
        <UINT32 name="timestamp">0</UINT32>
    </MAP>
    <MAP name="invoke" isArray="false">
        <STR name="functionName">connect</STR>
        <DOUBLE name="id">1.000</DOUBLE>
        <BOOL name="isFlex">false</BOOL>
        <MAP name="parameters" isArray="false">
            <MAP name="__index__value__0" isArray="false">
                <STR name="app">livestream</STR>
                <DOUBLE name="audioCodecs">3191.000</DOUBLE>
                <DOUBLE name="capabilities">239.000</DOUBLE>
                <STR name="flashVer">WIN 10,1,102,64</STR>
                <BOOL name="fpad">false</BOOL>
                <DOUBLE name="objectEncoding">0.000</DOUBLE>
                <STR name="pageUrl">http://www.a-queens.ro/testswf_els.html</STR>
                <STR name="swfUrl">http://www.a-queens.ro/player.swf</STR>
                <STR name="tcUrl">rtmpe://media.bfy.ro/livestream</STR>
                <DOUBLE name="videoCodecs">252.000</DOUBLE>
                <DOUBLE name="videoFunction">1.000</DOUBLE>
            </MAP>
        </MAP>
    </MAP>
</MAP>
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:324 User control message type: RM_USRCTRL_TYPE_STREAM_SET_BUFFER_LENGTH
/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:160 Stream 7 of type NR with name `` registered to application `flvplayback`
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:668 Play request for stream name `wild`. Start: -2; length: -1
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:1502 No live streams found: `wild` or `wild`
/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:160 Stream 8 of type IFRFLV with name `/usr/local/sonya/media/wild.flv` registered to application `flvplayback`
/usr/local/rtmpd/sources/thelib/src/netio/epoll/iohandlermanager.cpp:96 Handlers count changed: 11->12 IOHT_TIMER
/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:168 Stream 7 of type NR with name `` unregistered from application `flvplayback`
/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:160 Stream 9 of type ONR4R with name `wild` registered to application `flvplayback`
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:324 User control message type: RM_USRCTRL_TYPE_STREAM_SET_BUFFER_LENGTH


as we can see we have passed all validation rules
可以看到我们通过了所有验证规则;


3. SIMULATE copy&paste code into another webroot domain (www.curier.ro) whose Uri.ip 
is not listed into validation rules
再来测试在其它的域名中使用复制&粘贴代码

FIG.11


and in the background:
可以看到输出信息:

show code
/usr/local/rtmpd/sources/thelib/src/netio/epoll/tcpacceptor.cpp:134 Client connected: 86.122.125.158:50488 -> 0.0.0.0:1935
/usr/local/rtmpd/sources/thelib/src/netio/epoll/iohandlermanager.cpp:96 Handlers count changed: 12->13 IOHT_TCP_CARRIER
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:71 Register protocol CTCP(18) <-> TCP(19) <-> [IR(20)] to application appselector
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/inboundrtmpprotocol.cpp:105 New protocol chain: CTCP(18) <-> [TCP(19)] <-> RE(21) <-> IR(20)
/usr/local/rtmpd/sources/applications/appselector/src/rtmpappprotocolhandler.cpp:83 Selected application: flvplayback (livestream)
/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:152 Protocol CTCP(18) <-> TCP(19) <-> RE(21) <-> [IR(20)] unregistered from application: appselector
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:71 Register protocol CTCP(18) <-> TCP(19) <-> RE(21) <-> [IR(20)] to application flvplayback
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:1189 This agent is not on the list of allowed encoders: `WIN 10,1,102,64`
/usr/local/rtmpd/sources/applications/flvplayback/src/rtmpappprotocolhandler.cpp:85 Initial request:
<MAP name="" isArray="false">
    <MAP name="header" isArray="false">
        <UINT32 name="channelId">3</UINT32>
        <UINT8 name="headerType">3</UINT8>
        <BOOL name="isAbsolute">false</BOOL>
        <UINT32 name="messageLength">325</UINT32>
        <UINT8 name="messageType">20</UINT8>
        <UINT32 name="streamId">0</UINT32>
        <UINT32 name="timestamp">1</UINT32>
    </MAP>
    <MAP name="invoke" isArray="false">
        <STR name="functionName">connect</STR>
        <DOUBLE name="id">1.000</DOUBLE>
        <BOOL name="isFlex">false</BOOL>
        <MAP name="parameters" isArray="false">
            <MAP name="__index__value__0" isArray="false">
                <STR name="app">livestream</STR>
                <DOUBLE name="audioCodecs">3191.000</DOUBLE>
                <DOUBLE name="capabilities">239.000</DOUBLE>
                <STR name="flashVer">WIN 10,1,102,64</STR>
                <BOOL name="fpad">false</BOOL>
                <DOUBLE name="objectEncoding">0.000</DOUBLE>
                <STR name="pageUrl">http://www.curier.ro/testswf_els.html</STR>
                <STR name="swfUrl">http://www.curier.ro/player.swf</STR>
                <STR name="tcUrl">rtmpe://media.bfy.ro/livestream</STR>
                <DOUBLE name="videoCodecs">252.000</DOUBLE>
                <DOUBLE name="videoFunction">1.000</DOUBLE>
            </MAP>
        </MAP>
    </MAP>
</MAP>
/usr/local/rtmpd/sources/applications/flvplayback/src/rtmpappprotocolhandler.cpp:133 Incorrect swfUrl: <MAP name="" isArray="false">
    <MAP name="header" isArray="false">
        <UINT32 name="channelId">3</UINT32>
        <UINT8 name="headerType">3</UINT8>
        <BOOL name="isAbsolute">false</BOOL>
        <UINT32 name="messageLength">325</UINT32>
        <UINT8 name="messageType">20</UINT8>
        <UINT32 name="streamId">0</UINT32>
        <UINT32 name="timestamp">1</UINT32>
    </MAP>
    <MAP name="invoke" isArray="false">
        <STR name="functionName">connect</STR>
        <DOUBLE name="id">1.000</DOUBLE>
        <BOOL name="isFlex">false</BOOL>
        <MAP name="parameters" isArray="false">
            <MAP name="__index__value__0" isArray="false">
                <STR name="app">livestream</STR>
                <DOUBLE name="audioCodecs">3191.000</DOUBLE>
                <DOUBLE name="capabilities">239.000</DOUBLE>
                <STR name="flashVer">WIN 10,1,102,64</STR>
                <BOOL name="fpad">false</BOOL>
                <DOUBLE name="objectEncoding">0.000</DOUBLE>
                <STR name="pageUrl">http://www.curier.ro/testswf_els.html</STR>
                <STR name="swfUrl">http://www.curier.ro/player.swf</STR>
                <STR name="tcUrl">rtmpe://media.bfy.ro/livestream</STR>
                <DOUBLE name="videoCodecs">252.000</DOUBLE>
                <DOUBLE name="videoFunction">1.000</DOUBLE>
            </MAP>
        </MAP>
    </MAP>
</MAP>
/usr/local/rtmpd/sources/applications/flvplayback/src/rtmpappprotocolhandler.cpp:66 Invalid connect request
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpprotocol.cpp:799 Unable to send rtmp message to application
/usr/local/rtmpd/sources/thelib/src/netio/epoll/tcpcarrier.cpp:97 Unable to signal data available
/usr/local/rtmpd/sources/thelib/src/protocols/protocolmanager.cpp:43 Enqueue for delete for protool [TCP(19)] <-> RE(21) <-> IR(20)
/usr/local/rtmpd/sources/thelib/src/netio/epoll/iohandlermanager.cpp:105 Handlers count changed: 13->12 IOHT_TCP_CARRIER
/usr/local/rtmpd/sources/thelib/src/protocols/protocolmanager.cpp:43 Enqueue for delete for protool [RE(21)] <-> IR(20)
/usr/local/rtmpd/sources/thelib/src/protocols/protocolmanager.cpp:43 Enqueue for delete for protool [IR(20)]
/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:152 Protocol [IR(20)] unregistered from application: flvplayback


GET LOST! ;)


2. Authenticate and publishing with FMLE
对FMLE授权并发布

Setting up FMLE
设置FMLE


a. Open FMLE and set up default encoding parameters (for simplicity we select default low 
bandwidth preset - i am not expert and those settings are beyond this tutorial)
打开FMLE并使用默认的编码参数设置;
FIG.12

b. Set connect parameters to our rtmpdserver and define our stream test (we will use this 
name later when calling within webpage) and connect to server.
设置连接参数并修改流名,连接到服务器
FIG.13 


and in the background:
可以在输出日志中看到:


show code
1296562558:3:/usr/local/rtmpd/sources/thelib/src/netio/epoll/tcpacceptor.cpp:134:OnConnectionAvailable:Client connected: 86.122.125.158:61130 -> 0.0.0.0:1935
1296562558:4:/usr/local/rtmpd/sources/thelib/src/netio/epoll/iohandlermanager.cpp:96:RegisterIOHandler:Handlers count changed: 10->11 IOHT_TCP_CARRIER
1296562558:6:/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:71:RegisterProtocol:Register protocol CTCP(15) <-> TCP(47) <-> [IR(48)] to application appselector
1296562558:2:/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/inboundrtmpprotocol.cpp:126:ValidateClient:This version of player doesn't support validation
1296562558:6:/usr/local/rtmpd/sources/applications/appselector/src/rtmpappprotocolhandler.cpp:83:ProcessInvokeConnect:Selected application: flvplayback (livestream)
1296562558:6:/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:152:UnRegisterProtocol:Protocol CTCP(15) <-> TCP(47) <-> [IR(48)] unregistered from application: appselector
1296562558:6:/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:71:RegisterProtocol:Register protocol CTCP(15) <-> TCP(47) <-> [IR(48)] to application flvplayback
1296562558:6:/usr/local/rtmpd/sources/thelib/src/protocols/protocolmanager.cpp:43:EnqueueForDelete:Enqueue for delete for protool CTCP(15) <-> [TCP(47)] <-> IR(48)
1296562558:4:/usr/local/rtmpd/sources/thelib/src/netio/epoll/iohandlermanager.cpp:105:UnRegisterIOHandler:Handlers count changed: 11->10 IOHT_TCP_CARRIER
1296562558:6:/usr/local/rtmpd/sources/thelib/src/protocols/protocolmanager.cpp:43:EnqueueForDelete:Enqueue for delete for protool [IR(48)]
1296562558:6:/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:152:UnRegisterProtocol:Protocol [IR(48)] unregistered from application: flvplayback
1296562608:3:/usr/local/rtmpd/sources/thelib/src/netio/epoll/tcpacceptor.cpp:134:OnConnectionAvailable:Client connected: 86.122.125.158:62838 -> 0.0.0.0:1935
1296562608:4:/usr/local/rtmpd/sources/thelib/src/netio/epoll/iohandlermanager.cpp:96:RegisterIOHandler:Handlers count changed: 10->11 IOHT_TCP_CARRIER
1296562608:6:/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:71:RegisterProtocol:Register protocol CTCP(15) <-> TCP(49) <-> [IR(50)] to application appselector
1296562608:2:/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/inboundrtmpprotocol.cpp:126:ValidateClient:This version of player doesn't support validation
1296562608:6:/usr/local/rtmpd/sources/applications/appselector/src/rtmpappprotocolhandler.cpp:83:ProcessInvokeConnect:Selected application: flvplayback (livestream)
1296562608:6:/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:152:UnRegisterProtocol:Protocol CTCP(15) <-> TCP(49) <-> [IR(50)] unregistered from application: appselector
1296562608:6:/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:71:RegisterProtocol:Register protocol CTCP(15) <-> TCP(49) <-> [IR(50)] to application flvplayback
1296562608:6:/usr/local/rtmpd/sources/thelib/src/protocols/protocolmanager.cpp:43:EnqueueForDelete:Enqueue for delete for protool CTCP(15) <-> [TCP(49)] <-> IR(50)
1296562608:4:/usr/local/rtmpd/sources/thelib/src/netio/epoll/iohandlermanager.cpp:105:UnRegisterIOHandler:Handlers count changed: 11->10 IOHT_TCP_CARRIER
1296562608:6:/usr/local/rtmpd/sources/thelib/src/protocols/protocolmanager.cpp:43:EnqueueForDelete:Enqueue for delete for protool [IR(50)]
1296562608:6:/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:152:UnRegisterProtocol:Protocol [IR(50)] unregistered from application: flvplayback
1296562614:3:/usr/local/rtmpd/sources/thelib/src/netio/epoll/tcpacceptor.cpp:134:OnConnectionAvailable:Client connected: 86.122.125.158:56394 -> 0.0.0.0:1935
1296562614:4:/usr/local/rtmpd/sources/thelib/src/netio/epoll/iohandlermanager.cpp:96:RegisterIOHandler:Handlers count changed: 10->11 IOHT_TCP_CARRIER
1296562614:6:/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:71:RegisterProtocol:Register protocol CTCP(15) <-> TCP(51) <-> [IR(52)] to application appselector
1296562614:2:/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/inboundrtmpprotocol.cpp:126:ValidateClient:This version of player doesn't support validation
1296562614:6:/usr/local/rtmpd/sources/applications/appselector/src/rtmpappprotocolhandler.cpp:83:ProcessInvokeConnect:Selected application: flvplayback (livestream)
1296562614:6:/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:152:UnRegisterProtocol:Protocol CTCP(15) <-> TCP(51) <-> [IR(52)] unregistered from application: appselector
1296562614:6:/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:71:RegisterProtocol:Register protocol CTCP(15) <-> TCP(51) <-> [IR(52)] to application flvplayback


c. as we have been authenticated, we start to publish our stream (hit the START button in the 
center bottom of FMLE window)
获得了授权,则可以推送流了
FIG.14


FIG.15




and in the background:


show code
1296563537:3:/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:160:SignalStreamRegistered:Stream 22 of type NR with name `` registered to application `flvplayback`
1296563537:6:/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:543:ProcessInvokePublish:Try to publish stream test?videoKeyframeFrequency=5&totalDatarate=122.
1296563537:3:/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:168:SignalStreamUnRegistered:Stream 22 of type NR with name `` unregistered from application `flvplayback`
1296563537:3:/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:160:SignalStreamRegistered:Stream 23 of type INR with name `test?videoKeyframeFrequency=5&totalDatarate=122` registered to application `flvplayback`
1296563537:6:/usr/local/rtmpd/sources/thelib/src/streaming/streamsmanager.cpp:91:GetWaitingSubscribers:short name: test; long name: test?videoKeyframeFrequency=5&totalDatarate=122
1296563537:6:/usr/local/rtmpd/sources/thelib/src/streaming/streamsmanager.cpp:99:GetWaitingSubscribers:short count: 0; long count: 0
1296563537:6:/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:565:ProcessInvokePublish:subscribedOutStreams count: 0


Putting publish stream into a webpage
在页面上查看推送的流


a. create a simple webpage, using jwplayer (it could be done with Flowplayer too, since only 
those players will pass out validation rules), named it testfmle_els.html and put it into 
webroot directory of our test domain, a-queens.ro
创建页面

show code
<html>
<head><title>Eduardo Luis Secenario - FMLE test page</title>
<body>
 
<div style="margin-left: 15px; margin-top: 55px;">
<script type='text/javascript' src='jwplayer.js'></script>
<script type='text/javascript' src='swfobject.js'></script>
 
<div id='mediaspace'>This text will be replaced</div>
 
<script type='text/javascript'>
  var so = new SWFObject('player.swf','mpl','470','290','9');
  so.addParam('allowfullscreen','true');
  so.addParam('allowscriptaccess','always');
  so.addParam('wmode','opaque');
  so.addVariable('file','test');
  so.addVariable('provider','rtmp');
  so.addVariable('streamer','rtmpe://media.bfy.ro/livestream');
  so.write('mediaspace');
</script>
 
</div>
</body>
</html> 


b. calling webpage address in our favorite browser to see if it is working…
打开页面
FIG.16


and in the background:


show code
1296564067:3:/usr/local/rtmpd/sources/thelib/src/netio/epoll/tcpacceptor.cpp:134:OnConnectionAvailable:Client connected: 86.122.125.158:57291 -> 0.0.0.0:1935
1296564067:4:/usr/local/rtmpd/sources/thelib/src/netio/epoll/iohandlermanager.cpp:96:RegisterIOHandler:Handlers count changed: 11->12 IOHT_TCP_CARRIER
1296564067:6:/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:71:RegisterProtocol:Register protocol CTCP(16) <-> TCP(65) <-> [IR(66)] to application appselector
1296564067:6:/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/inboundrtmpprotocol.cpp:105:PerformHandshake:New protocol chain: CTCP(16) <-> [TCP(65)] <-> RE(67) <-> IR(66)
1296564067:6:/usr/local/rtmpd/sources/applications/appselector/src/rtmpappprotocolhandler.cpp:83:ProcessInvokeConnect:Selected application: flvplayback (livestream)
1296564067:6:/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:152:UnRegisterProtocol:Protocol CTCP(16) <-> TCP(65) <-> RE(67) <-> [IR(66)] unregistered from application: appselector
1296564067:6:/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:71:RegisterProtocol:Register protocol CTCP(16) <-> TCP(65) <-> RE(67) <-> [IR(66)] to application flvplayback
1296564067:2:/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:1189:AuthenticateAdobe:This agent is not on the list of allowed encoders: `WIN 10,1,102,64`
1296564067:6:/usr/local/rtmpd/sources/applications/flvplayback/src/rtmpappprotocolhandler.cpp:85:ValidateRequest:Initial request:
<MAP name="" isArray="false">
    <MAP name="header" isArray="false">
        <UINT32 name="channelId">3</UINT32>
        <UINT8 name="headerType">3</UINT8>
        <BOOL name="isAbsolute">false</BOOL>
        <UINT32 name="messageLength">330</UINT32>
        <UINT8 name="messageType">20</UINT8>
        <UINT32 name="streamId">0</UINT32>
        <UINT32 name="timestamp">0</UINT32>
    </MAP>
    <MAP name="invoke" isArray="false">
        <STR name="functionName">connect</STR>
        <DOUBLE name="id">1.000</DOUBLE>
        <BOOL name="isFlex">false</BOOL>
        <MAP name="parameters" isArray="false">
            <MAP name="__index__value__0" isArray="false">
                <STR name="app">livestream</STR>
                <DOUBLE name="audioCodecs">3191.000</DOUBLE>
                <DOUBLE name="capabilities">239.000</DOUBLE>
                <STR name="flashVer">WIN 10,1,102,64</STR>
                <BOOL name="fpad">false</BOOL>
                <DOUBLE name="objectEncoding">0.000</DOUBLE>
                <STR name="pageUrl">http://www.a-queens.ro/testfmle_els.html</STR>
                <STR name="swfUrl">http://www.a-queens.ro/player.swf</STR>
                <STR name="tcUrl">rtmpe://media.bfy.ro/livestream</STR>
                <DOUBLE name="videoCodecs">252.000</DOUBLE>
                <DOUBLE name="videoFunction">1.000</DOUBLE>
            </MAP>
        </MAP>
    </MAP>
</MAP>
1296564067:2:/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:324:ProcessUsrCtrl:User control message type: RM_USRCTRL_TYPE_STREAM_SET_BUFFER_LENGTH
1296564067:3:/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:160:SignalStreamRegistered:Stream 24 of type NR with name `` registered to application `flvplayback`
1296564067:3:/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:668:ProcessInvokePlay:Play request for stream name `test`. Start: -2; length: -1
1296564067:3:/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:168:SignalStreamUnRegistered:Stream 24 of type NR with name `` unregistered from application `flvplayback`
1296564067:3:/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:160:SignalStreamRegistered:Stream 25 of type ONR4R with name `test` registered to application `flvplayback`
1296564067:2:/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:324:ProcessUsrCtrl:User control message type: RM_USRCTRL_TYPE_STREAM_SET_BUFFER_LENGTH


So, everything is working as expected. So far, we have managed to authenticate to FMLE instance, to publish a stream and to view it online within a webpage.


3. Authenticate and publish with Wirecast
使用Wirecast来测试授权和验证

Setting up Wirecast
a. Open Wirecast and set up default broadcast parameters (for simplicity we select default low 
bandwidth preset, connect url and authentication parameters - hit Set Credentials… button - 
and define our stream as test1)
FIG.17




b. Select broadcast source (here default laptop webcam), then start broadcasting… 
(acknowledge value of User Agent above, Wirecast/FM 1.0; to make it working that value must 
be in encoderAgents list inside rtmpserver.lua - i have already put it there but to be aware of)

FIG.18


FIG.19


and in the background:
show code
/usr/local/rtmpd/sources/thelib/src/netio/epoll/tcpacceptor.cpp:134 Client connected: 86.122.125.158:56239 -> 0.0.0.0:1935
/usr/local/rtmpd/sources/thelib/src/netio/epoll/iohandlermanager.cpp:96 Handlers count changed: 11->12 IOHT_TCP_CARRIER
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:71 Register protocol CTCP(16) <-> TCP(15) <-> [IR(16)] to application appselector
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/inboundrtmpprotocol.cpp:126 This version of player doesn't support validation
/usr/local/rtmpd/sources/applications/appselector/src/rtmpappprotocolhandler.cpp:83 Selected application: flvplayback (livestream)
/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:152 Protocol CTCP(16) <-> TCP(15) <-> [IR(16)] unregistered from application: appselector
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:71 Register protocol CTCP(16) <-> TCP(15) <-> [IR(16)] to application flvplayback
/usr/local/rtmpd/sources/thelib/src/protocols/protocolmanager.cpp:43 Enqueue for delete for protool CTCP(16) <-> [TCP(15)] <-> IR(16)
/usr/local/rtmpd/sources/thelib/src/netio/epoll/iohandlermanager.cpp:105 Handlers count changed: 12->11 IOHT_TCP_CARRIER
/usr/local/rtmpd/sources/thelib/src/protocols/protocolmanager.cpp:43 Enqueue for delete for protool [IR(16)]
/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:152 Protocol [IR(16)] unregistered from application: flvplayback
/usr/local/rtmpd/sources/thelib/src/netio/epoll/tcpacceptor.cpp:134 Client connected: 86.122.125.158:61920 -> 0.0.0.0:1935
/usr/local/rtmpd/sources/thelib/src/netio/epoll/iohandlermanager.cpp:96 Handlers count changed: 11->12 IOHT_TCP_CARRIER
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:71 Register protocol CTCP(16) <-> TCP(17) <-> [IR(18)] to application appselector
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/inboundrtmpprotocol.cpp:126 This version of player doesn't support validation
/usr/local/rtmpd/sources/applications/appselector/src/rtmpappprotocolhandler.cpp:83 Selected application: flvplayback (livestream)
/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:152 Protocol CTCP(16) <-> TCP(17) <-> [IR(18)] unregistered from application: appselector
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:71 Register protocol CTCP(16) <-> TCP(17) <-> [IR(18)] to application flvplayback
/usr/local/rtmpd/sources/thelib/src/protocols/protocolmanager.cpp:43 Enqueue for delete for protool CTCP(16) <-> [TCP(17)] <-> IR(18)
/usr/local/rtmpd/sources/thelib/src/netio/epoll/iohandlermanager.cpp:105 Handlers count changed: 12->11 IOHT_TCP_CARRIER
/usr/local/rtmpd/sources/thelib/src/protocols/protocolmanager.cpp:43 Enqueue for delete for protool [IR(18)]
/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:152 Protocol [IR(18)] unregistered from application: flvplayback
/usr/local/rtmpd/sources/thelib/src/netio/epoll/tcpacceptor.cpp:134 Client connected: 86.122.125.158:57789 -> 0.0.0.0:1935
/usr/local/rtmpd/sources/thelib/src/netio/epoll/iohandlermanager.cpp:96 Handlers count changed: 11->12 IOHT_TCP_CARRIER
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:71 Register protocol CTCP(16) <-> TCP(19) <-> [IR(20)] to application appselector
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/inboundrtmpprotocol.cpp:126 This version of player doesn't support validation
/usr/local/rtmpd/sources/applications/appselector/src/rtmpappprotocolhandler.cpp:83 Selected application: flvplayback (livestream)
/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:152 Protocol CTCP(16) <-> TCP(19) <-> [IR(20)] unregistered from application: appselector
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:71 Register protocol CTCP(16) <-> TCP(19) <-> [IR(20)] to application flvplayback
/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:160 Stream 3 of type NR with name `` registered to application `flvplayback`
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:543 Try to publish stream test1.
/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:168 Stream 3 of type NR with name `` unregistered from application `flvplayback`
/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:160 Stream 4 of type INR with name `test1` registered to application `flvplayback`
/usr/local/rtmpd/sources/thelib/src/streaming/streamsmanager.cpp:91 short name: test1; long name: test1
/usr/local/rtmpd/sources/thelib/src/streaming/streamsmanager.cpp:99 short count: 0; long count: 0
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:565 subscribedOutStreams count: 0
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpprotocol.cpp:275 Chunk size changed for RTMP connection 0x8bf79e0: 128->314
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpprotocol.cpp:275 Chunk size changed for RTMP connection 0x8bf79e0: 314->315
Putting publish stream into a webpage


a. create a simple webpage, using jwplayer (it could be done with Flowplayer too, 
since only those players will pass out validation rules), named it testwcast_els.html 
and put it into webroot directory of our test domain, a-queens.ro
创建播放页面

show code
<html>
<head><title>Eduardo Luis Secenario - Wirecast test page</title>
<body>
 
<div style="margin-left: 15px; margin-top: 55px;">
<script type='text/javascript' src='jwplayer.js'></script>
<script type='text/javascript' src='swfobject.js'></script>
 
<div id='mediaspace'>This text will be replaced</div>
 
<script type='text/javascript'>
  var so = new SWFObject('player.swf','mpl','470','290','9');
  so.addParam('allowfullscreen','true');
  so.addParam('allowscriptaccess','always');
  so.addParam('wmode','opaque');
  so.addVariable('file','test1');
  so.addVariable('provider','rtmp');
  so.addVariable('streamer','rtmpe://media.bfy.ro/livestream');
  so.write('mediaspace');
</script>
 
</div>
</body>
</html> 


b. calling webpage address in our favorite browser to see if it is working…
打开页面
FIG.20


and in the background:
show code
/usr/local/rtmpd/sources/thelib/src/netio/epoll/tcpacceptor.cpp:134 Client connected: 86.122.125.158:53149 -> 0.0.0.0:1935
/usr/local/rtmpd/sources/thelib/src/netio/epoll/iohandlermanager.cpp:96 Handlers count changed: 12->13 IOHT_TCP_CARRIER
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:71 Register protocol CTCP(17) <-> TCP(30) <-> [IR(31)] to application appselector
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/inboundrtmpprotocol.cpp:105 New protocol chain: CTCP(17) <-> [TCP(30)] <-> RE(32) <-> IR(31)
/usr/local/rtmpd/sources/applications/appselector/src/rtmpappprotocolhandler.cpp:83 Selected application: flvplayback (livestream)
/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:152 Protocol CTCP(17) <-> TCP(30) <-> RE(32) <-> [IR(31)] unregistered from application: appselector
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:71 Register protocol CTCP(17) <-> TCP(30) <-> RE(32) <-> [IR(31)] to application flvplayback
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:1189 This agent is not on the list of allowed encoders: `WIN 10,1,102,64`
/usr/local/rtmpd/sources/applications/flvplayback/src/rtmpappprotocolhandler.cpp:85 Initial request:
<MAP name="" isArray="false">
    <MAP name="header" isArray="false">
        <UINT32 name="channelId">3</UINT32>
        <UINT8 name="headerType">3</UINT8>
        <BOOL name="isAbsolute">false</BOOL>
        <UINT32 name="messageLength">331</UINT32>
        <UINT8 name="messageType">20</UINT8>
        <UINT32 name="streamId">0</UINT32>
        <UINT32 name="timestamp">1</UINT32>
    </MAP>
    <MAP name="invoke" isArray="false">
        <STR name="functionName">connect</STR>
        <DOUBLE name="id">1.000</DOUBLE>
        <BOOL name="isFlex">false</BOOL>
        <MAP name="parameters" isArray="false">
            <MAP name="__index__value__0" isArray="false">
                <STR name="app">livestream</STR>
                <DOUBLE name="audioCodecs">3191.000</DOUBLE>
                <DOUBLE name="capabilities">239.000</DOUBLE>
                <STR name="flashVer">WIN 10,1,102,64</STR>
                <BOOL name="fpad">false</BOOL>
                <DOUBLE name="objectEncoding">0.000</DOUBLE>
                <STR name="pageUrl">http://www.a-queens.ro/testwcast_els.html</STR>
                <STR name="swfUrl">http://www.a-queens.ro/player.swf</STR>
                <STR name="tcUrl">rtmpe://media.bfy.ro/livestream</STR>
                <DOUBLE name="videoCodecs">252.000</DOUBLE>
                <DOUBLE name="videoFunction">1.000</DOUBLE>
            </MAP>
        </MAP>
    </MAP>
</MAP>
/usr/local/rtmpd/sources/applications/flvplayback/src/rtmpappprotocolhandler.cpp:126 tcUrl is 'rtmpe://media.bfy.ro/livestream'
/usr/local/rtmpd/sources/applications/flvplayback/src/rtmpappprotocolhandler.cpp:136 swfUrl is 'http://www.a-queens.ro/player.swf'
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:324 User control message type: RM_USRCTRL_TYPE_STREAM_SET_BUFFER_LENGTH
/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:160 Stream 9 of type NR with name `` registered to application `flvplayback`
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:668 Play request for stream name `test1`. Start: -2; length: -1
/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:168 Stream 9 of type NR with name `` unregistered from application `flvplayback`
/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:160 Stream 10 of type ONR4R with name `test1` registered to application `flvplayback`
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:324 User control message type: RM_USRCTRL_TYPE_STREAM_SET_BUFFER_LENGTH
Again, everything is working as expected. We have managed to authenticate via 
Wirecast instance, to publish a stream and to view it online within a webpage.


4. SIMULTATE stop/start publishing
停止、启动流发布


Setting up FMLE (with Wirecast would be the same)


a. Open FMLE and set up default encoding parameters (for simplicity we select default 
low bandwidth preset), authenticate and start publishing.
FIG.21


FIG.22




in the background:
show code
/usr/local/rtmpd/sources/thelib/src/netio/epoll/tcpacceptor.cpp:134 Client connected: 86.122.125.158:59462 -> 0.0.0.0:1935
/usr/local/rtmpd/sources/thelib/src/netio/epoll/iohandlermanager.cpp:96 Handlers count changed: 11->12 IOHT_TCP_CARRIER
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:71 Register protocol CTCP(16) <-> TCP(47) <-> [IR(48)] to application appselector
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/inboundrtmpprotocol.cpp:126 This version of player doesn't support validation
/usr/local/rtmpd/sources/applications/appselector/src/rtmpappprotocolhandler.cpp:83 Selected application: flvplayback (livestream)
/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:152 Protocol CTCP(16) <-> TCP(47) <-> [IR(48)] unregistered from application: appselector
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:71 Register protocol CTCP(16) <-> TCP(47) <-> [IR(48)] to application flvplayback
/usr/local/rtmpd/sources/thelib/src/protocols/protocolmanager.cpp:43 Enqueue for delete for protool CTCP(16) <-> [TCP(47)] <-> IR(48)
/usr/local/rtmpd/sources/thelib/src/netio/epoll/iohandlermanager.cpp:105 Handlers count changed: 12->11 IOHT_TCP_CARRIER
/usr/local/rtmpd/sources/thelib/src/protocols/protocolmanager.cpp:43 Enqueue for delete for protool [IR(48)]
/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:152 Protocol [IR(48)] unregistered from application: flvplayback
/usr/local/rtmpd/sources/thelib/src/netio/epoll/tcpacceptor.cpp:134 Client connected: 86.122.125.158:64876 -> 0.0.0.0:1935
/usr/local/rtmpd/sources/thelib/src/netio/epoll/iohandlermanager.cpp:96 Handlers count changed: 11->12 IOHT_TCP_CARRIER
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:71 Register protocol CTCP(16) <-> TCP(49) <-> [IR(50)] to application appselector
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/inboundrtmpprotocol.cpp:126 This version of player doesn't support validation
/usr/local/rtmpd/sources/applications/appselector/src/rtmpappprotocolhandler.cpp:83 Selected application: flvplayback (livestream)
/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:152 Protocol CTCP(16) <-> TCP(49) <-> [IR(50)] unregistered from application: appselector
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:71 Register protocol CTCP(16) <-> TCP(49) <-> [IR(50)] to application flvplayback
/usr/local/rtmpd/sources/thelib/src/protocols/protocolmanager.cpp:43 Enqueue for delete for protool CTCP(16) <-> [TCP(49)] <-> IR(50)
/usr/local/rtmpd/sources/thelib/src/netio/epoll/iohandlermanager.cpp:105 Handlers count changed: 12->11 IOHT_TCP_CARRIER
/usr/local/rtmpd/sources/thelib/src/protocols/protocolmanager.cpp:43 Enqueue for delete for protool [IR(50)]
/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:152 Protocol [IR(50)] unregistered from application: flvplayback
/usr/local/rtmpd/sources/thelib/src/netio/epoll/tcpacceptor.cpp:134 Client connected: 86.122.125.158:62684 -> 0.0.0.0:1935
/usr/local/rtmpd/sources/thelib/src/netio/epoll/iohandlermanager.cpp:96 Handlers count changed: 11->12 IOHT_TCP_CARRIER
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:71 Register protocol CTCP(16) <-> TCP(51) <-> [IR(52)] to application appselector
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/inboundrtmpprotocol.cpp:126 This version of player doesn't support validation
/usr/local/rtmpd/sources/applications/appselector/src/rtmpappprotocolhandler.cpp:83 Selected application: flvplayback (livestream)
/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:152 Protocol CTCP(16) <-> TCP(51) <-> [IR(52)] unregistered from application: appselector
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:71 Register protocol CTCP(16) <-> TCP(51) <-> [IR(52)] to application flvplayback
/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:160 Stream 14 of type NR with name `` registered to application `flvplayback`
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:543 Try to publish stream test?videoKeyframeFrequency=5&totalDatarate=122.
/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:168 Stream 14 of type NR with name `` unregistered from application `flvplayback`
/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:160 Stream 15 of type INR with name `test?videoKeyframeFrequency=5&totalDatarate=122` registered to application `flvplayback`
/usr/local/rtmpd/sources/thelib/src/streaming/streamsmanager.cpp:91 short name: test; long name: test?videoKeyframeFrequency=5&totalDatarate=122
/usr/local/rtmpd/sources/thelib/src/streaming/streamsmanager.cpp:99 short count: 0; long count: 0
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:565 subscribedOutStreams count: 0




Putting publish stream into a webpage to test stop/start FMLE publishing


a. create a simple webpage, using jwplayer (it could be done with Flowplayer too, 
since only those players will pass out validation rules), named it testfmle1_els.html 
and put it into webroot directory of our test domain, a-queens.ro. We will use livestream 
plugin of JW instead rtmp provider.


show code
<html>
<head><title>Eduardo Luis Secenario - FMLE test page</title>
<body>
 
<div style="margin-left: 15px; margin-top: 55px;">
<script type='text/javascript' src='jwplayer.js'></script>
<script type='text/javascript' src='swfobject.js'></script>
 
<div id='mediaspace'>This text will be replaced</div>
 
<script type='text/javascript'>
  var so = new SWFObject('player.swf','mpl','470','290','9');
  so.addParam('allowfullscreen','true');
  so.addParam('allowscriptaccess','always');
  so.addParam('wmode','opaque');
  so.addVariable('file','test');
  so.addVariable('plugins','livestream');
  so.addVariable('streamer','rtmpe://media.bfy.ro/livestream');
  so.addVariable('autostart','true');
  so.write('mediaspace');
</script>
 
</div>
</body>
</html> 
b. calling webpage address in our favorite browser…
FIG.23


in the background:
show code
/usr/local/rtmpd/sources/thelib/src/netio/epoll/tcpacceptor.cpp:134 Client connected: 86.122.125.158:51802 -> 0.0.0.0:1935
/usr/local/rtmpd/sources/thelib/src/netio/epoll/iohandlermanager.cpp:96 Handlers count changed: 12->13 IOHT_TCP_CARRIER
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:71 Register protocol CTCP(17) <-> TCP(53) <-> [IR(54)] to application appselector
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/inboundrtmpprotocol.cpp:105 New protocol chain: CTCP(17) <-> [TCP(53)] <-> RE(55) <-> IR(54)
/usr/local/rtmpd/sources/applications/appselector/src/rtmpappprotocolhandler.cpp:83 Selected application: flvplayback (livestream)
/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:152 Protocol CTCP(17) <-> TCP(53) <-> RE(55) <-> [IR(54)] unregistered from application: appselector
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:71 Register protocol CTCP(17) <-> TCP(53) <-> RE(55) <-> [IR(54)] to application flvplayback
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:1189 This agent is not on the list of allowed encoders: `WIN 10,1,102,64`
/usr/local/rtmpd/sources/applications/flvplayback/src/rtmpappprotocolhandler.cpp:85 Initial request:
<MAP name="" isArray="false">
    <MAP name="header" isArray="false">
        <UINT32 name="channelId">3</UINT32>
        <UINT8 name="headerType">3</UINT8>
        <BOOL name="isAbsolute">false</BOOL>
        <UINT32 name="messageLength">331</UINT32>
        <UINT8 name="messageType">20</UINT8>
        <UINT32 name="streamId">0</UINT32>
        <UINT32 name="timestamp">1</UINT32>
    </MAP>
    <MAP name="invoke" isArray="false">
        <STR name="functionName">connect</STR>
        <DOUBLE name="id">1.000</DOUBLE>
        <BOOL name="isFlex">false</BOOL>
        <MAP name="parameters" isArray="false">
            <MAP name="__index__value__0" isArray="false">
                <STR name="app">livestream</STR>
                <DOUBLE name="audioCodecs">3191.000</DOUBLE>
                <DOUBLE name="capabilities">239.000</DOUBLE>
                <STR name="flashVer">WIN 10,1,102,64</STR>
                <BOOL name="fpad">false</BOOL>
                <DOUBLE name="objectEncoding">0.000</DOUBLE>
                <STR name="pageUrl">http://www.a-queens.ro/testfmle1_els.html</STR>
                <STR name="swfUrl">http://www.a-queens.ro/player.swf</STR>
                <STR name="tcUrl">rtmpe://media.bfy.ro/livestream</STR>
                <DOUBLE name="videoCodecs">252.000</DOUBLE>
                <DOUBLE name="videoFunction">1.000</DOUBLE>
            </MAP>
        </MAP>
    </MAP>
</MAP>
/usr/local/rtmpd/sources/applications/flvplayback/src/rtmpappprotocolhandler.cpp:126 tcUrl is 'rtmpe://media.bfy.ro/livestream'
/usr/local/rtmpd/sources/applications/flvplayback/src/rtmpappprotocolhandler.cpp:136 swfUrl is 'http://www.a-queens.ro/player.swf'
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:324 User control message type: RM_USRCTRL_TYPE_STREAM_SET_BUFFER_LENGTH
/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:160 Stream 16 of type NR with name `` registered to application `flvplayback`
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:668 Play request for stream name `test`. Start: -2; length: -1
/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:168 Stream 16 of type NR with name `` unregistered from application `flvplayback`
/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:160 Stream 17 of type ONR4R with name `test` registered to application `flvplayback`
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:324 User control message type: RM_USRCTRL_TYPE_STREAM_SET_BUFFER_LENGTH


c. stop publishing in FMLE
FIG.24


in the background:
show code
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:977 Default implementation of ProcessInvokeGeneric: Request: FCUnpublish
/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:168 Stream 15 of type INR with name `test?videoKeyframeFrequency=5&totalDatarate=122` unregistered from application `flvplayback`
/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:160 Stream 22 of type NR with name `` registered to application `flvplayback`
/usr/local/rtmpd/sources/thelib/src/netio/epoll/iohandlermanager.cpp:251 ***Event handler HUP: 0x8c09fc0
/usr/local/rtmpd/sources/thelib/src/netio/epoll/tcpcarrier.cpp:86 Unable to read data. 86.122.125.158:56501 -> 86.123.101.7:1935
/usr/local/rtmpd/sources/thelib/src/protocols/protocolmanager.cpp:43 Enqueue for delete for protool [TCP(59)] <-> RE(61) <-> IR(60)
/usr/local/rtmpd/sources/thelib/src/netio/epoll/iohandlermanager.cpp:105 Handlers count changed: 14->13 IOHT_TCP_CARRIER
/usr/local/rtmpd/sources/thelib/src/protocols/protocolmanager.cpp:43 Enqueue for delete for protool [RE(61)] <-> IR(60)
/usr/local/rtmpd/sources/thelib/src/protocols/protocolmanager.cpp:43 Enqueue for delete for protool [IR(60)]
/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:168 Stream 21 of type ONR4R with name `test` unregistered from application `flvplayback`
/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:152 Protocol [IR(60)] unregistered from application: flvplayback
/usr/local/rtmpd/sources/thelib/src/streaming/baseoutstream.cpp:93 BaseOutStream::UnLink: This stream is not linked


re-publishing
FIG.25


show code
/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:160 Stream 23 of type NR with name `` registered to application `flvplayback`
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:543 Try to publish stream test?videoKeyframeFrequency=5&totalDatarate=122.
/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:168 Stream 23 of type NR with name `` unregistered from application `flvplayback`
/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:160 Stream 24 of type INR with name `test?videoKeyframeFrequency=5&totalDatarate=122` registered to application `flvplayback`
/usr/local/rtmpd/sources/thelib/src/streaming/streamsmanager.cpp:91 short name: test; long name: test?videoKeyframeFrequency=5&totalDatarate=122
/usr/local/rtmpd/sources/thelib/src/streaming/streamsmanager.cpp:99 short count: 1; long count: 0
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:565 subscribedOutStreams count: 1
/usr/local/rtmpd/sources/thelib/src/netio/epoll/tcpacceptor.cpp:134 Client connected: 86.122.125.158:64789 -> 0.0.0.0:1935
/usr/local/rtmpd/sources/thelib/src/netio/epoll/iohandlermanager.cpp:96 Handlers count changed: 13->14 IOHT_TCP_CARRIER
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:71 Register protocol CTCP(18) <-> TCP(62) <-> [IR(63)] to application appselector
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/inboundrtmpprotocol.cpp:105 New protocol chain: CTCP(18) <-> [TCP(62)] <-> RE(64) <-> IR(63)
/usr/local/rtmpd/sources/applications/appselector/src/rtmpappprotocolhandler.cpp:83 Selected application: flvplayback (livestream)
/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:152 Protocol CTCP(18) <-> TCP(62) <-> RE(64) <-> [IR(63)] unregistered from application: appselector
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:71 Register protocol CTCP(18) <-> TCP(62) <-> RE(64) <-> [IR(63)] to application flvplayback
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:1189 This agent is not on the list of allowed encoders: `WIN 10,1,102,64`
/usr/local/rtmpd/sources/applications/flvplayback/src/rtmpappprotocolhandler.cpp:85 Initial request:
<MAP name="" isArray="false">
    <MAP name="header" isArray="false">
        <UINT32 name="channelId">3</UINT32>
        <UINT8 name="headerType">3</UINT8>
        <BOOL name="isAbsolute">false</BOOL>
        <UINT32 name="messageLength">331</UINT32>
        <UINT8 name="messageType">20</UINT8>
        <UINT32 name="streamId">0</UINT32>
        <UINT32 name="timestamp">0</UINT32>
    </MAP>
    <MAP name="invoke" isArray="false">
        <STR name="functionName">connect</STR>
        <DOUBLE name="id">1.000</DOUBLE>
        <BOOL name="isFlex">false</BOOL>
        <MAP name="parameters" isArray="false">
            <MAP name="__index__value__0" isArray="false">
                <STR name="app">livestream</STR>
                <DOUBLE name="audioCodecs">3191.000</DOUBLE>
                <DOUBLE name="capabilities">239.000</DOUBLE>
                <STR name="flashVer">WIN 10,1,102,64</STR>
                <BOOL name="fpad">false</BOOL>
                <DOUBLE name="objectEncoding">0.000</DOUBLE>
                <STR name="pageUrl">http://www.a-queens.ro/testfmle1_els.html</STR>
                <STR name="swfUrl">http://www.a-queens.ro/player.swf</STR>
                <STR name="tcUrl">rtmpe://media.bfy.ro/livestream</STR>
                <DOUBLE name="videoCodecs">252.000</DOUBLE>
                <DOUBLE name="videoFunction">1.000</DOUBLE>
            </MAP>
        </MAP>
    </MAP>
</MAP>
/usr/local/rtmpd/sources/applications/flvplayback/src/rtmpappprotocolhandler.cpp:126 tcUrl is 'rtmpe://media.bfy.ro/livestream'
/usr/local/rtmpd/sources/applications/flvplayback/src/rtmpappprotocolhandler.cpp:136 swfUrl is 'http://www.a-queens.ro/player.swf'
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:324 User control message type: RM_USRCTRL_TYPE_STREAM_SET_BUFFER_LENGTH
/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:160 Stream 25 of type NR with name `` registered to application `flvplayback`
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:668 Play request for stream name `test`. Start: -2; length: -1
/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:168 Stream 25 of type NR with name `` unregistered from application `flvplayback`
/usr/local/rtmpd/sources/thelib/src/application/baseclientapplication.cpp:160 Stream 26 of type ONR4R with name `test` registered to application `flvplayback`
/usr/local/rtmpd/sources/thelib/src/protocols/rtmp/basertmpappprotocolhandler.cpp:324 User control message type: RM_USRCTRL_TYPE_STREAM_SET_BUFFER_LENGTH


5. SIMULATE RECORDING from OUTSIDE


working…


Final thoughts


working…


VI. ANEXA


IMPORTANT
Due to latest changes for auth mechanism introduced with rev. 577 you must update your 
rtmpappprotocolhandler.cpp as: – change all contents of
对于新版本的rtmpappprotocolhandler.cpp修改


bool RTMPAppProtocolHandler::ProcessInvokeConnect(BaseRTMPProtocol *pFrom, Variant &request)
with new one found here: http://pastebin.com/GhbNscFE


Global stuff
1. we should make a crtmpserver user in order to stat up crtmpserver; i won't show that here 
   because i think all of us knows how to do that
2. suppose that our crtmpserver user has UID 1002 (cat /etc/passwd) now in all scenarios we 
   start up crtmpserver like this:


./crtmpserver/crtmpserver –uid=1002 ./crtmpserver/crtmpserver.lua (– means two minus signs)


if you were to use (install) tinyxml natively and do not want to use tinyxml whitch came with 
crtmpdserer 3rdparty you should be aware that
when instaling iot must be compiled with STL option. Just a quick howto only for Gentoo and 
BSD* like (only this machines i have right now for testing)


- a. gentoo
root # ACCEPT_KEYWORDS=”~x86” USE=“debug stl” emerge tinyxml


- b. BSD* like systems, modify Makefile to add STL option
cd /usr/ports/textproc/tinyxml/


   nano -w Makefile ...
   and add CXXFLAGS+=        -DTIXML_USE_STL before \\.if defined(NOPROFILE) || defined(NO_PROFILE) like:
   Raw file here: http://pastebin.com/raw.php?i=Q7A0YjXx
   sonya # make install clean
I. Scenario


1. crtmpserver.lua file
Raw file: http://pastebin.com/raw.php?i=1Vt23Sa9


2. rtmpappprotocolhandler.h for all scenarios, no matter if you use Adobe FMLE authentification 
or not


Raw file here: http://pastebin.com/raw.php?i=gsjDGA7A
  
3.  rtmpappprotocolhandler.cpp for this scenario from above 
Raw file here: http://pastebin.com/raw.php?i=mEi7tAcy
II. Scenario


1. crtmpserver.lua file
Raw file: http://pastebin.com/raw.php?i=1Vt23Sa9


2. rtmpappprotocolhandler.h for all scenarios, no matter if you use Adobe FMLE authentification 
or not
 Raw file here: http://pastebin.com/raw.php?i=gsjDGA7A
 
3.  rtmpappprotocolhandler.cpp for this scenario from above  
  Raw file: http://pastebin.com/raw.php?i=NrG3VDVf
 
V. Scenario


1. crtmpserver.lua file
  Raw here: http://pastebin.com/raw.php?i=tcMA6vtP
  
2. rtmpappprotocolhandler.h for all scenarios, no matter if you use Adobe FMLE authentification 
or not
 Raw file here: http://pastebin.com/raw.php?i=gsjDGA7A
 
3.  rtmpappprotocolhandler.cpp for this scenario from above  
  Raw file: http://pastebin.com/raw.php?i=z5yBAYa5
  
4. users.lua file, file whitch will authenticate your Adobe FMLE publishing users
well, inside builders/cmake/applications/flvplayback we must create another structure of directories like applications/flvplayback and put there our users.lua file.
ameeran flvplayback # cd /usr/local/rtmpd/builders/cmake/applications/flvplayback/
ameeran flvplayback # mkdir applications && cd applications && mkdir flvplayback && cd flvplayback
ameeran flvplayback # pwd
ameeran flvplayback # /usr/local/rtmpd/builders/cmake/applications/flvplayback/applications/flvplayback/
ameeran flvplayback # touch users.lua (and then nano -w users.lua writing users as)
ameeran flvplayback # cat users.lua
ameeran flvplayback # users=
 {
      firstuser="firstpassword",
      seconduser="secondpassword"
 }
 5. compile and run crtmpserver
 
Due to latest changes, rev. 781 being latest when i write this, you must update your 
rtmpappprotocolhandler.cpp as:


   // ip which resolve our calling webpage(s)/website(s)
        // added if/elseif/else and INFO like Andriy suggested
        if (((string) uri.ip) == "86.122.125.158") {
                 INFO("Stream calling webpage is \'%s\'", STR((string) pageUrl));
                 INFO("stream Calling webpage IP is \'%s\'", STR((string) uri.ip));
        }
        else {
             FATAL("Incorrect "RM_INVOKE_PARAMS_CONNECT_PAGEURL": %s", STR(request.ToString()));
             return false;
        }
        return true;
with:


   // ip which resolve our calling webpage(s)/website(s)
        // added if/elseif/else and INFO like Andriy suggested
        if (((string) uri.ip()) == "86.122.125.158") {
                 INFO("Stream calling webpage is \'%s\'", STR((string) pageUrl));
                 INFO("stream Calling webpage IP is \'%s\'", STR((string) uri.ip()));
        }
        else {
             FATAL("Incorrect "RM_INVOKE_PARAMS_CONNECT_PAGEURL": %s", STR(request.ToString()));
             return false;
        }
        return true;
Adding filter for pageURL (webpage where resides the webplayer, dinamic or static webpages)


We need to modify only rtmpappprotocolhandler.cpp, into function bool RTMPAppProtocolHandler::ValidateRequest(Variant &request), after ip filter and before return true; :


   // filter to verify webpage from which webplayer resides - modify values below for your needs
   // for static page:
   if (((string) pageUrl) == "http://www.domain.com/testpage.html") {
        INFO("Calling website page address is: \'%s\'", STR((string) pageUrl));
   }
   // dinamic webpage like wordpress & joomla blogs
   else if (((string) pageUrl).find("http://www.domain.com/index.php?option=")==0) {
        INFO("Calling website page address is: \'%s\'", STR((string) pageUrl));
   } else {
        FATAL("Incorect website page calling "RM_INVOKE_PARAMS_CONNECT_PAGEURL": %s", STR(request.ToString()));
      return false;              }     
   }
Show total number of connections after a connection is made


We need to modify only rtmpappprotocolhandler.cpp for few line of code addition, into function bool RTMPAppProtocolHandler::ValidateRequest(Variant &request), after last filter [ uriIp() or pageURL() ] and before return true; :


   // Show total number of connections by now including this one which is supposed to be "online"
   // since has passed all validations filters. Inspired from Andriy patch for limit max connections
   if (_connections.size() > 0 ) {
       INFO("Total number of connections: \'%u\'", _connections.size());
   }
Add posibility to configure a global number of connections that rtmpd could accept


I do not know if this could be the right place for it but i thought it might be useful mostly for those who are trying to limit rtmp connections by firewall level (hardware or software). After connection numbers limit defined in crtmpserver.lua is reached rtmpd reject next request with NetConnection.Connect.Rejected message. This patch was made by Adriy for Adriana i have just implemented here.


modify rtmpappprotocolhandler.h to define maxConnections constant
   #ifdef HAS_PROTOCOL_RTMP
   #ifndef _RTMPAPPPROTOCOLHANDLER_H
   #define _RTMPAPPPROTOCOLHANDLER_H
   #include "protocols/rtmp/basertmpappprotocolhandler.h"


   namespace app_flvplayback {


        class RTMPAppProtocolHandler
        : public BaseRTMPAppProtocolHandler {
        public:
                RTMPAppProtocolHandler(Variant &configuration);
                virtual ~RTMPAppProtocolHandler();


                virtual bool ProcessInvokeGeneric(BaseRTMPProtocol *pFrom,
                                Variant &request);
                virtual bool ProcessInvokeConnect(BaseRTMPProtocol *pFrom,
                                Variant &request);
                virtual bool ValidateRequest(Variant &request);


        private:
                bool ProcessGetAvailableFlvs(BaseRTMPProtocol *pFrom, Variant &request);
                bool ProcessInsertMetadata(BaseRTMPProtocol *pFrom, Variant &request);
                /* define variable which holds max connections value */
                uint32_t maxConnections;
        };
    }
    #endif  /* _RTMPAPPPROTOCOLHANDLER_H */
    #endif /* HAS_PROTOCOL_RTMP */
modify rtmpappprotocolhandler.cpp, inside function RTMPAppProtocolHandler::RTMPAppProtocolHandler(Variant &configuration): BaseRTMPAppProtocolHandler(configuration) as follows:
     // Andriy patch
        // Reading value of maxConnections variables from config file
        if (configuration.HasKey("maxConnections")) {
                maxConnections = (uint32_t) configuration["maxConnections"];
        } else {
                maxConnections = 0;
        }
modify crtmpserver.lua, and add inside flvplayback app parameter maxConnections:
    ...
     validateHandshake=true,
     keyframeSeek=true,
     seekGranularity=1.5, --in seconds, between 0.1 and 600
     clientSideBuffer=4, --in seconds, between 5 and 30
     -- generateMetaFiles=true, --this will generate seek/meta files on application startup
     renameBadFiles=true,
     enableCheckBandwidth=true,
     -- specify max number of connections that rtmpd should accept.
     maxConnections=200,
    ...
tutorial_protect_streams.txt · Last modified: 2012/10/25 03:06 by rani
        
Except where otherwise noted, content on this wiki is licensed under the following license: 
GNU Free Documentation License 1.3
            
 

posted @ 2013-08-05 19:53  pangbangb  阅读(1457)  评论(0编辑  收藏  举报