Il existe un paquet officiel pour crtmpserver : sudo apt-get install crtmpserver . Cependant, l’installation depuis le code source permet d’adapter le serveur à ses besoins.

Installation depuis le code source

Installer les prérequis

sudo apt-get install g++ subversion cmake make libssl-dev

Compilation et installation

svn co --username anonymous --password "" https://svn.rtmpd.com/crtmpserver/trunk crtmpserver
cd crtmpserver/builders/cmake
cmake -DCRTMPSERVER_INSTALL_PREFIX=/usr/local/ .
make
sudo make install

Répartition des fichiers après l’installation :

L’executable : /usr/local/sbin/rtcmpserver
Le fichier configuration exemple : /usr/local/etc/crtmpserver.lua.sample
Le repertoire des applications : /usr/local/lib/crtmpserver/applications

Configuration

Création du fichier de configuration

sudo cp /usr/local/etc/crtmpserver.lua.sample /usr/local/etc/crtmpserver.lua

les chemins doivent être réécrits pour correspondre à l’installation :

Par exemple pour le repertoire racine des applications :
rootDirectory=”/usr/local/lib/crtmpserver/applications”

Génération du certificat pour le protocole rtmps

cd /usr/local/lib/crtmpserver/applications/appselector
sudo openssl req -x509 -nodes -days 10950 -newkey rsa:2048 -keyout server.key -out server.crt

Fichier de démarrage

Voici un fichier de démarrage inspiré de la version du paquet officiel

Contenu à copier dans /etc/init.d/crtmpserver
#!/bin/sh
### BEGIN INIT INFO
# Provides:          crtmpserver
# Required-Start:    $network $local_fs $remote_fs
# Required-Stop:     $remote_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: C++ RTMP/RTSP streaming server
# Description:       High performance RTMP/RTSP/MPEG-TS streaming server
### END INIT INFO

# Author: Andriy Beregovenko <jet@jet.kiev.ua>

PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin
DESC="C++ RTMP Server"
NAME=crtmpserver
DAEMON=/usr/local/sbin/crtmpserver
DAEMON_ARGS=" --daemon "
DAEMON_CONF=/usr/local/etc/crtmpserver.lua
DAEMON_USER="root"
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME



[ -x $DAEMON ] || exit 0
[ -r $DAEMON_CONF ] || exit 0



. /lib/init/vars.sh
. /lib/lsb/init-functions

DAEMON_UID=$(getent passwd ${DAEMON_USER} | cut -d":" -f3)
if [ -z "${DAEMON_UID}" ]; then
        echo "Error: User ${DAEMON_USER} does not exist."
        exit 1
fi

UID_ARG=" --uid=${DAEMON_UID} "

do_start()
{
        start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
                || return 1
        start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \
                $DAEMON_ARGS $UID_ARG $DAEMON_CONF \
                || return 2
}

do_stop()
{
        start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME
        RETVAL="$?"
        [ "$RETVAL" = 2 ] && return 2

        start-stop-daemon --stop --quiet --oknodo --retry=INT/30/KILL/5 --exec $DAEMON
        [ "$?" = 2 ] && return 2

        rm -f $PIDFILE
        return "$RETVAL"
}

case "$1" in
  start)
    log_daemon_msg "Starting $DESC " "$NAME"
    do_start
    case "$?" in
                0|1) log_end_msg 0 ;;
                2) log_end_msg 1 ;;
        esac
  ;;
  stop)
        log_daemon_msg "Stopping $DESC" "$NAME"
        do_stop
        case "$?" in
                0|1) log_end_msg 0 ;;
                2) log_end_msg 1 ;;
        esac
        ;;
  status)
       status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
       ;;
  restart)
        log_daemon_msg "Restarting $DESC" "$NAME"
        do_stop
        case "$?" in
          0|1)
                do_start
                case "$?" in
                        0) log_end_msg 0 ;;
                        1) log_end_msg 1 ;; # Old process is still running
                        *) log_end_msg 1 ;; # Failed to start
                esac
                ;;
          *)
                # Failed to stop
                log_end_msg 1
                ;;
        esac
        ;;
  force-reload)
        restart
        ;;
  *)
        echo "Usage: $SCRIPTNAME {start|stop|status|restart}" >&2
        exit 3
        ;;
esac

:
Création du service :
sudo chmod +x /etc/init.d/crtmpserver
sudo update-rc.d crtmpserver defaults

Tests

sudo service crtmpserver start  

Si le service se lance il doit indiquer : Starting C++ RTMP Server crtmpserver

Adapter l’application flvplayback

L’application flvplayback possede une fonction qui permet de lister les fluxs du serveur. Voici comment la supprimer et configurer le serveur avec des fonctionnalitées au minimum.

Préparation de la compilation pour avoir un minimum d’applications :

Il faut modifier le fichier builders/cmake/applications/CMakeLists.txt et commenter les emplacements des applications inutilisées:

cmake_minimum_required(VERSION 2.6)
PROJECT(applications)

SET(CRTMPSERVER_ROOT "${CRTMPSERVER_ROOT}/applications")
SET(ACTIVE_APPS "")
SET(ACTIVE_APPS_LIBS "")
ADD_SUBDIRECTORY(flvplayback flvplayback)
ADD_SUBDIRECTORY(appselector appselector)
#ADD_SUBDIRECTORY(samplefactory samplefactory)
#ADD_SUBDIRECTORY(vptests vptests)
#ADD_SUBDIRECTORY(admin admin)
#ADD_SUBDIRECTORY(proxypublish proxypublish)
#ADD_SUBDIRECTORY(stresstest stresstest)
#ADD_SUBDIRECTORY(applestreamingclient applestreamingclient)
#ADD_SUBDIRECTORY(vmapp vmapp)

Le fichier de configuration builders/cmake/crtmpserver/crtmpserver.lua doit être modifié aussi:

configuration=
{
        daemon=false,
        pathSeparator="/",
        logAppenders=
        {
                {
                        name="console appender",
                        type="coloredConsole",
                        level=6
                },
                {
                        name="file appender",
                        type="file",
                        level=6,
                        fileName="/var/log/crtmpserver/rtmpd-791",
                        fileHistorySize=10,
                        fileLength=1024*4096
                }
        },
        applications=
        {
                rootDirectory="applications",
                {
                        name="appselector",
                        description="Application for selecting the rest of the applications",
                        protocol="dynamiclinklibrary",
                        validateHandshake=true,
                        default=true,
                        acceptors =
                        {
                                {
                                        ip="0.0.0.0",
                                        port=1935,
                                        protocol="inboundRtmp" --only rtmp protocol, for testing obvioulsy
                                },
                        }
                },
                {
                        description="FLV Playback - Test Application for mediaStorage tutorial",
                        name="flvplayback",
                        protocol="dynamiclinklibrary",
                        aliases=
                        {
                                "live",
                        },
                        acceptors =
                        {
                        },
                        externalStreams =
                        {
                        },
                        validateHandshake=true,
                        mediaStorage = {
                                namedStorage1={
                                        --this storage contains all properties with their
                                        --default values. The only mandatory property is
                                        --mediaFolder
                                        description="Some storage",
                                        mediaFolder="/usr/local/media/",    --this is main storage physical location
                                        metaFolder="/usr/local/metadata",   --this is metadata physical location for main storage
                                        enableStats=false,
                                        clientSideBuffer=15,
                                        keyframeSeek=false,
                                        seekGranularity=0.1,  --0.1 for videoclips, 60 for series or full movies length
                                },
                                namedStorage2={
                                        mediaFolder="/usr/local/media1/",   --this is second storage physical location
                                        metaFolder="/usr/local/metadata1",  --this is metadata physical location for second storage
                                },
                        },
                },
                --#INSERTION_MARKER# DO NOT REMOVE THIS. USED BY appscaffold SCRIPT.
        }
}

Modification du code de l’application flvplayback :

Pour empecher le listage des fluxs il faut supprimmer les fonctions ProcessGetAvailableFlvs() et ProcessInsertMetadata() de rtmpappprotocolhandler.h et rtmpappprotocolhandler.cpp

sources/applications/flvplayback/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);
        };
}
#endif  /* _RTMPAPPPROTOCOLHANDLER_H */
#endif /* HAS_PROTOCOL_RTMP */

sources/applications/flvplayback/src/rtmpappprotocolhandler.cpp


/*
 *  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);
//      }
NYIR;
}
 
#endif /* HAS_PROTOCOL_RTMP */

Pages de références

Le projet C++ RTMP Server :
http://www.rtmpd.com/

CRTMPServer on Ubuntu HOWTO :
http://forum.telestream.net/forum/messageview.aspx?catid=44&threadid=10779

Simple tutoriel pour compiler une application :
http://wiki.rtmpd.com/tutorial_basic

Proteger les flux :
http://wiki.rtmpd.com/tutorial_protect_streams

Page de test pour lire un flux
https://dl.dropboxusercontent.com/u/2918563/flvplayback.swf