DEV Community

Juan Nunes
Juan Nunes

Posted on

19

Criando seu próprio servidor de stream usando NGINX- RTMP

Objetivo desse Post é mostrar como é simples criar um servidor de stream utilizando o NGINX.

Image description

Protocolos de transmissão de vídeo

Antes de começarmos a configurar o nosso servidor precisamos conhecer um pouco dos Protocolos que utilizaremos, no nosso caso teremos o RTMP e o HLS.

Image description

RTMP - (Real Time Messaging Protocol) é um sistema baseado no protocolo TCP e foi criado excluisivamente para transmissão de Vídeo, Áudio e Dados. Os Dados podem ser transmitidos em Live(ao vivo) ou pre-recorded (Pré-gravado) além disso pode ser compartilhado mensagens de bate papo e push de notificações. Foi criado com intuito de transmitir mídia entre um servidor e o Adobe flash Player.

Um dos pontos positivos de utilizar o RTMP é a baixa latência que ele possui.

HLS - (HTTP Live Streaming) Como o própio nome diz o HLS é um sistema baseado no protocolo HTTP e foi criado pela apple para ser a evolução do RTMP no cenário de Mídia. Uma das vantagens desse protocolo é a sua adaptabilidade a diferentes dispositivos e resoluções. Por ser baseado em HTTP ele não é bem um "stream" pois no final das contas acaba fazendo múltiplas requisições e enviando pequenos fragmentos do conteúdo, com essa fragmentação devido as múltiplas requisições ele "escolhe" qual qualidade deve ser enviada de acordo com o dispositivo e conexão.

Image description

Diferente do RTMP esse protocolo possui uma alta latência, porém pode ser mitigada utilizando outros recurso em conjunto.

Criando o Servidor

Para criação do servidor utilizaremos o Docker para subir nossa imagem com Nginx.

No código abaixo temos o nosso Dockerfile com seus Workflows. Para possibilitar o nginx utilizar o RTMP nos utilizaremos um modulo chamado NGINX_RTMP_MODULE.



FROM buildpack-deps:stretch


ENV NGINX_VERSION nginx-1.18.0
ENV NGINX_RTMP_MODULE_VERSION 1.2.1


RUN apt-get update && \
    apt-get install -y ca-certificates openssl libssl-dev && \
    rm -rf /var/lib/apt/lists/*


RUN mkdir -p /tmp/build/nginx && \
    cd /tmp/build/nginx && \
    wget -O ${NGINX_VERSION}.tar.gz https://nginx.org/download/${NGINX_VERSION}.tar.gz && \
    tar -zxf ${NGINX_VERSION}.tar.gz


RUN mkdir -p /tmp/build/nginx-rtmp-module && \
    cd /tmp/build/nginx-rtmp-module && \
    wget -O nginx-rtmp-module-${NGINX_RTMP_MODULE_VERSION}.tar.gz https://github.com/arut/nginx-rtmp-module/archive/v${NGINX_RTMP_MODULE_VERSION}.tar.gz && \
    tar -zxf nginx-rtmp-module-${NGINX_RTMP_MODULE_VERSION}.tar.gz && \
    cd nginx-rtmp-module-${NGINX_RTMP_MODULE_VERSION}


RUN cd /tmp/build/nginx/${NGINX_VERSION} && \
    ./configure \
        --sbin-path=/usr/local/sbin/nginx \
        --conf-path=/etc/nginx/nginx.conf \
        --error-log-path=/var/log/nginx/error.log \
        --pid-path=/var/run/nginx/nginx.pid \
        --lock-path=/var/lock/nginx/nginx.lock \
        --http-log-path=/var/log/nginx/access.log \
        --http-client-body-temp-path=/tmp/nginx-client-body \
        --with-http_ssl_module \
        --with-threads \
        --with-ipv6 \
        --add-module=/tmp/build/nginx-rtmp-module/nginx-rtmp-module-${NGINX_RTMP_MODULE_VERSION} && \
    make -j $(getconf _NPROCESSORS_ONLN) && \
    make install && \
    mkdir /var/lock/nginx && \
    rm -rf /tmp/build

RUN ln -sf /dev/stdout /var/log/nginx/access.log && \
    ln -sf /dev/stderr /var/log/nginx/error.log

COPY nginx.conf /etc/nginx/nginx.conf

EXPOSE 1935
CMD ["nginx", "-g", "daemon off;"]


Enter fullscreen mode Exit fullscreen mode

Agora precisamos do nosso arquivo de configuração do nginx o nginx.conf



worker_processes auto;
rtmp_auto_push on;
events {}

rtmp {
    server {
        listen 1935;

        application live {

            live        on; mm

            hls         on;
            hls_path    /tmp/hls;
            hls_fragment 5s;
        }
    }
}

http {
    server {
        listen 80;

        location /hls {
            root /tmp;
        }

        location / {
            add_header 'Access-Control-Allow-Origin' '*' always;
            root /tmp;
        }
    }
}


Enter fullscreen mode Exit fullscreen mode

O arquivo de configuração é bem simples, apenas para colocar no ar o servidor e exemplificar seu uso.

  • rtmp_auto_push - Possibilita fazer mais de uma transmissão ao mesmo tempo.
  • listen 1935 - Essa é a porta padrão do RTMP.
  • live on - habilita a transmissão usando o RTMP.
  • hls_fragment - Tamanho do fragmento que será enviado.

Tendo esses 2 arquivos já podemos rodar nosso servidor, utilize os comandos abaixo para subir o container.

Build do container:



docker image build -t devtojuan/stream-server . 


Enter fullscreen mode Exit fullscreen mode

Subir o container:



docker container run -p 1935:1935 -p 8080:80 devtojuan/stream-server


Enter fullscreen mode Exit fullscreen mode

Iniciando Stream

Para começar sua stream você vai precisar de algum software que transmita, podendo ser OBS Studio, Xsplit, Lightstream etc.

Para iniciar a transmissão informe a url da stream.

Como estamos usando a porta 1935(padrão do rtmp) não é necessário informá-la junto ao caminho.



rtmp://localhost/live/teste


Enter fullscreen mode Exit fullscreen mode

Agora para assistir a livestream vai precisar de um player que consiga transmitir. O VLC é o mais recomendado.

Basta informar esse caminho ao player:



http://localhost/hls/teste.m3u8


Enter fullscreen mode Exit fullscreen mode

Sentry image

Hands-on debugging session: instrument, monitor, and fix

Join Lazar for a hands-on session where you’ll build it, break it, debug it, and fix it. You’ll set up Sentry, track errors, use Session Replay and Tracing, and leverage some good ol’ AI to find and fix issues fast.

RSVP here →

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay