Search
Write a publication
Pull to refresh

RTSP сервер на NodeJS

Потоковый протокол реального времени (англ. real time streaming protocol, сокр. RTSP) — прикладной протокол, предназначенный для использования в системах, работающих с мультимедийными данными (мультимедийным содержимым, медиасодержимым), и позволяющий удалённо управлять потоком данных с сервера, предоставляя возможность выполнения команд, таких как запуск (старт), приостановку (пауза) и остановку (стоп) вещания (проигрывания) мультимедийного содержимого, а также доступа по времени к файлам, расположенным на сервере. Разработан IETF в 1998 году и описан в RFC 2326. RTSP не выполняет сжатия, а также не определяет метода инкапсуляции мультимедийных данных и транспортных протоколов. Передача потоковых данных сама по себе не является частью протокола RTSP. Большинство серверов RTSP использует для этого стандартный транспортный протокол реального времени, осуществляющий передачу аудио- и видеоданных.

Копаясь на просторах npm не нашел подходящей реализации этого протокола поэтому было решено попробовать реализовать свое решение которое имело бы возможность публиковать потоки UDP, а смотреть TCP и наоборот. Так же хотелось иметь возможность контролировать опубликование или просмотр потоков.

По итогу родился пакет на media-rtsp и хотел бы им поделиться.

(async () => {
    /**
     * Test debug function
     * @param argument
     * @private
     */
    const _debug = (...argument) => {
        console.info.apply(this, ['['+Date.now()+']', ...argument]);
    }
    
    /**
     * Config server
     * @type {object}
     */
    const CONFIG = {
        // * Port server listen (Default: 544)
        "port" : 5544,
        // * Host server listen (Default: 127.0.0.1)
        "host" : "127.0.0.1",
        // * Name of the server (Use in response header) (Default: RTSP SERVER)
        "serverName" : "RTSP SERVER",
        // * Require request access permission from (method: access(name, callback)) (Default: empty)
        "access" : ["auth", "media"],
        // * Port udp range (Default: 56000-57000)
        "portList" : {
            "start" : 56000, 
            "end" : 57000
        }
    };
    
    const RTSP_SERVER = require('media-rtsp');
    
    // Create server
    const rtspServer = new RTSP_SERVER(CONFIG);

    /**
     * Event connection new client
     * @event connect
     */
    rtspServer.on('connect', (clientObject) => {

        clientObject.on('RTSP:command', (command, data) => {
            console.debug('RTSP:command', command, clientObject.getID(), data);
        });

        clientObject.on('write', (message, isCommand) => {
            if(isCommand){
                console.debug('write', clientObject.getID(), message);
            }

        });

        /**
         * Event auth client
         * @event auth
         */
        clientObject.on('auth', () => {
            _debug(
                'event:[client|auth]',
                'ID: '+clientObject.getID(),
                'HeaderData: '+clientObject.getHeaderData()
            );
        });

        /**
         * Event create new media object from client
         * @event media
         */
        clientObject.on('media', (mediaObject) => {

            /**
             * Event destroy media object
             */
            mediaObject.once('destroy', () => {
                _debug(
                    'event:[client|media|destroy]',
                    'ID: '+mediaObject.getID(),
                    'Name: '+mediaObject.getName(),
                    'Type: '+mediaObject.getType(),
                    'ClientID: '+clientObject.getID(),
                    'DestroyInfo: '+mediaObject.getDestroy(),
                );
            });

            _debug(
                'event:[client|media|create]',
                'ID: '+mediaObject.getID(),
                'Name: '+mediaObject.getName(),
                'Type: '+mediaObject.getType(), // publish, views
                'ClientID: '+clientObject.getID(),
            );
        });


        /**
         * Event destroy client
         */
        clientObject.on('destroy', () => {
            _debug(
                'event:[client|destroy]',
                'ID: '+clientObject.getID(),
                'DestroyInfo: '+clientObject.getDestroy()
            );
        });

        _debug(
            'event:[client|connect]',
            'ID: '+clientObject.getID()
        );
    });


    /**
     * Event listen server
     * @event listen
     */
    rtspServer.on('listen', () => {
        _debug(
            'event:[listen]',
            'Host: '+rtspServer.getHost(),
            'Port: '+rtspServer.getPort()
        );
    });


    /**
     * Client authorization request
     * @param clientObject
     * @returns {Promise<object>|boolean|Error}
     */
    rtspServer.access('auth', async (clientObject) => {
        _debug('request:[access|auth]',
            'ClientID: '+clientObject.getID(),
            'HeaderData: '+clientObject.getHeaderData()
        );
        return true;
    });


    /**
     * Client create media request
     * @param mediaObject
     * @returns {Promise<object>|boolean|Error}
     */
    rtspServer.access('media', async (mediaObject, clientObject) => {
        _debug(
            'request:[access|media]',
            'MediaID: '+mediaObject.getID(),
            'MediaName: '+mediaObject.getName(),
            'MediaType: '+mediaObject.getType(),
            'MediaClientID: '+clientObject.getID(),
        );
        return true;
    });

    // Start listen
    await rtspServer.listen();

})();

в этом примере CONFIG.access содержит имена событий которые обязательно требует авторизации через rtspServer.access в противном случае автоматически будет отказ на создание сессии или медиа.

Кому интересно присоединяйтесь к усовершенствованию проекта на гитхабе.

Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.