Criando seu próprio servidor de stream usando NGINX- RTMP
Tags: stream, nginx, rtmp, tutorial
Published: 2022-10-27 12:20:47

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

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9l480oun59fjogdr1fha.png)

## 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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lfz21molc0uk2imhdgd1.png)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g422rvybjyw7gdpdb725.png)

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;"]
```

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;
        }
    }
}
```

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 . 
```
Subir o container: 
```
docker container run -p 1935:1935 -p 8080:80 devtojuan/stream-server
```

## 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
```

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
```