Nginx-Vod-Module en Azure Container Instances

En el artículo anterior te compartí el ejemplo que he estado utilizando para desplegar un Nginx con soporte para RTMP, para probar la ingesta de video en directo. Hoy quiero mostrarte el ejemplo para el video bajo de manda, apoyándome en nginx-vod-module de Kaltura, también en Azure Container Instances.

nginx.conf

La configuración de Nginx en este caso utilizará el módulo de Kaltura, del cual puedes revisar diferentes configuraciones en la carpeta conf de su repositorio de GitHub.

worker_processes auto;

events {

  use epoll;
}

http {

  log_format main '$remote_addr $remote_user [$time_local] "$request" '
  '$status "$http_referer" "$http_user_agent"';

  access_log /dev/stdout main;
  error_log stderr debug;

  default_type application/octet-stream;
  include /usr/local/nginx/conf/mime.types;

  sendfile on;
  tcp_nopush on;
  tcp_nodelay on;

  vod_mode local;
  vod_metadata_cache metadata_cache 16m;
  vod_response_cache response_cache 512m;
  vod_last_modified_types *;
  vod_segment_duration 9000;
  vod_align_segments_to_key_frames on;
  vod_dash_fragment_file_name_prefix "segment";
  vod_hls_segment_file_name_prefix "segment";

  vod_manifest_segment_durations_mode accurate;

  open_file_cache max=1000 inactive=5m;
  open_file_cache_valid 2m;
  open_file_cache_min_uses 1;
  open_file_cache_errors on;

  aio on;

  server {

    listen 80;
    server_name localhost;
    root /opt/static;

    location ~ ^/videos/.+$ {

      autoindex on;
    }

    location /hls/ {

      vod hls;
      alias /opt/static/videos/;
      add_header Access-Control-Allow-Headers '*';
      add_header Access-Control-Allow-Origin '*';
      add_header Access-Control-Allow-Methods 'GET, HEAD, OPTIONS';
    }

    location /thumb/ {

      vod thumb;
      alias /opt/static/videos/;
      add_header Access-Control-Allow-Headers '*';
      add_header Access-Control-Allow-Origin '*';
      add_header Access-Control-Allow-Methods 'GET, HEAD, OPTIONS';
    }

    location /dash/ {

      vod dash;
      alias /opt/static/videos/;
      add_header Access-Control-Allow-Headers '*';
      add_header Access-Control-Allow-Origin '*';
      add_header Access-Control-Allow-Methods 'GET, HEAD, OPTIONS';
    }
  }
}

Para este ejemplo, tengo configurado los formatos HLS y DASH de aquellos videos ubicados en el directorio /opt/static/videos.

Dockerfile

Al igual que en el ejemplo con Live Streaming, quiero utilizar Azure Container Instances por simplicidad, y porque es para un momento puntual, por lo que debo preparar una imagen de Docker con un Nginx y el módulo para el VoD. Para ello he configurado el siguiente Dockerfile:

FROM alpine:3.11.6 AS base_image

FROM base_image AS build

RUN apk add --no-cache curl build-base openssl openssl-dev zlib-dev linux-headers pcre-dev ffmpeg ffmpeg-dev
RUN mkdir nginx nginx-vod-module

ARG NGINX_VERSION=1.17.10
ARG VOD_MODULE_VERSION=399e1a0ecb5b0007df3a627fa8b03628fc922d5e

RUN curl -sL https://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz | tar -C /nginx --strip 1 -xz
RUN curl -sL https://github.com/kaltura/nginx-vod-module/archive/${VOD_MODULE_VERSION}.tar.gz | tar -C /nginx-vod-module --strip 1 -xz

WORKDIR /nginx
RUN ./configure --prefix=/usr/local/nginx \
--add-module=../nginx-vod-module \
--with-http_ssl_module \
--with-file-aio \
--with-threads \
--with-cc-opt="-O3"
RUN make
RUN make install
RUN rm -rf /usr/local/nginx/html /usr/local/nginx/conf/*.default

FROM base_image
RUN apk add --no-cache ca-certificates openssl pcre zlib ffmpeg
COPY --from=build /usr/local/nginx /usr/local/nginx
COPY nginx.conf /usr/local/nginx/conf/
ENTRYPOINT ["/usr/local/nginx/sbin/nginx"]
CMD ["-g", "daemon off;"]

Como puedes ver, descargo la última versión de Nginx hasta el momento, además del módulo de Kaltura, y lo instalo.

Desplegar Nginx en Azure Container Instances

Ahora que ya tienes todas las piezas solo queda desplegar tu nuevo servidor en ACI:

#Build and push your image
docker build . -t YOUR_USERNAME/nginx-rtmp-vod
docker push YOUR_USERNAME/nginx-rtmp-vod

#Azure Storage Account where the live streaming events are
RESOURCE_GROUP="Nginx-Demos"
AZ_STORAGE_NAME="media"

#Get the Azure Storage Account Key
AZ_STORAGE_KEY=$(az storage account keys list --resource-group $RESOURCE_GROUP --account-name $AZ_STORAGE_NAME --query "[0].value" --output tsv)

#Create a the VoD container with nginx-vod-module
az container create \
--resource-group $RESOURCE_GROUP \
--name nginx-rtmp-vod \
--image YOUR_USERNAME/nginx-rtmp-vod \
--dns-name-label nginx-rtmp-vod --ports 80 \
--cpu 2 --memory 3.5 \
--azure-file-volume-share-name recordings \
--azure-file-volume-account-name $AZ_STORAGE_NAME \
--azure-file-volume-account-key $AZ_STORAGE_KEY \
-azure-file-volume-mount-path /opt/static/videos/

Lo primero que hago es generar la imagen y publicarla en Docker Hub. Después recupero la clave de la cuenta de almacenamiento donde tengo los videos que grabé en directo en el artículo anterior. Por último genero el contenedor para ACI indicando la imagen que acabo de crear y mapeo el directorio recordings en la ruta /opt/static/videos/. Este directorio de Azure Files puede ser cualquier otro donde tengas los videos que quieres reproducir, sin que provengan directamente de mi ejemplo anterior, pero me parecía chulo que los eventos en directo sirvieran para verlos después en diferido 🙂

Para comprobar que funciona correctamente puedes utilizar este HTML, donde debes hacer referencia al video que quieres reproducir:

El código lo tienes en mi GitHub.

¡Saludos!