From f144a6f0a4b230d7e9a8079a09c6fe2718ce0213 Mon Sep 17 00:00:00 2001 From: Adolfo Delorenzo Date: Fri, 20 Jan 2023 22:15:42 +0000 Subject: [PATCH] first commit --- Dockerfile | 116 +++++++++ Dockerfile-alpine | 118 +++++++++ Dockerfile-nvenc | 124 +++++++++ LICENSE | 21 ++ README.md | 97 +++++++ conf/nginx-nvenc.conf | 132 ++++++++++ conf/nginx.conf | 132 ++++++++++ conf/nginx_no-ffmpeg.conf | 115 ++++++++ conf/nginx_rtmp_minimal_no-stats.conf | 14 + docker-entrypoint.sh | 15 ++ patch.sh | 362 ++++++++++++++++++++++++++ players/dash.html | 23 ++ players/hls.html | 23 ++ players/hls_hlsjs.html | 41 +++ players/rtmp.html | 24 ++ players/rtmp_hls.html | 30 +++ 16 files changed, 1387 insertions(+) create mode 100644 Dockerfile create mode 100644 Dockerfile-alpine create mode 100644 Dockerfile-nvenc create mode 100644 LICENSE create mode 100644 README.md create mode 100644 conf/nginx-nvenc.conf create mode 100644 conf/nginx.conf create mode 100644 conf/nginx_no-ffmpeg.conf create mode 100644 conf/nginx_rtmp_minimal_no-stats.conf create mode 100644 docker-entrypoint.sh create mode 100644 patch.sh create mode 100644 players/dash.html create mode 100644 players/hls.html create mode 100644 players/hls_hlsjs.html create mode 100644 players/rtmp.html create mode 100644 players/rtmp_hls.html diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..8f85990 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,116 @@ +ARG DEBIAN_VERSION=stretch-slim + +##### Building stage ##### +FROM debian:${DEBIAN_VERSION} as builder +MAINTAINER Tareq Alqutami + +# Versions of nginx, rtmp-module and ffmpeg +ARG NGINX_VERSION=1.17.5 +ARG NGINX_RTMP_MODULE_VERSION=1.2.1 +ARG FFMPEG_VERSION=4.2.1 + +# Install dependencies +RUN apt-get update && \ + apt-get install -y \ + wget build-essential ca-certificates \ + openssl libssl-dev yasm \ + libpcre3-dev librtmp-dev libtheora-dev \ + libvorbis-dev libvpx-dev libfreetype6-dev \ + libmp3lame-dev libx264-dev libx265-dev && \ + rm -rf /var/lib/apt/lists/* + + +# Download nginx source +RUN mkdir -p /tmp/build && \ + cd /tmp/build && \ + wget https://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz && \ + tar -zxf nginx-${NGINX_VERSION}.tar.gz && \ + rm nginx-${NGINX_VERSION}.tar.gz + +# Download rtmp-module source +RUN cd /tmp/build && \ + wget https://github.com/arut/nginx-rtmp-module/archive/v${NGINX_RTMP_MODULE_VERSION}.tar.gz && \ + tar -zxf v${NGINX_RTMP_MODULE_VERSION}.tar.gz && \ + rm v${NGINX_RTMP_MODULE_VERSION}.tar.gz + +# Build nginx with nginx-rtmp module +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 \ + --http-log-path=/var/log/nginx/access.log \ + --pid-path=/var/run/nginx/nginx.pid \ + --lock-path=/var/lock/nginx.lock \ + --http-client-body-temp-path=/tmp/nginx-client-body \ + --with-http_ssl_module \ + --with-threads \ + --add-module=/tmp/build/nginx-rtmp-module-${NGINX_RTMP_MODULE_VERSION} && \ + make -j $(getconf _NPROCESSORS_ONLN) && \ + make install + +# Download ffmpeg source +RUN cd /tmp/build && \ + wget http://ffmpeg.org/releases/ffmpeg-${FFMPEG_VERSION}.tar.gz && \ + tar -zxf ffmpeg-${FFMPEG_VERSION}.tar.gz && \ + rm ffmpeg-${FFMPEG_VERSION}.tar.gz + +# Build ffmpeg +RUN cd /tmp/build/ffmpeg-${FFMPEG_VERSION} && \ + ./configure \ + --enable-version3 \ + --enable-gpl \ + --enable-small \ + --enable-libx264 \ + --enable-libx265 \ + --enable-libvpx \ + --enable-libtheora \ + --enable-libvorbis \ + --enable-librtmp \ + --enable-postproc \ + --enable-swresample \ + --enable-libfreetype \ + --enable-libmp3lame \ + --disable-debug \ + --disable-doc \ + --disable-ffplay \ + --extra-libs="-lpthread -lm" && \ + make -j $(getconf _NPROCESSORS_ONLN) && \ + make install + +# Copy stats.xsl file to nginx html directory and cleaning build files +RUN cp /tmp/build/nginx-rtmp-module-${NGINX_RTMP_MODULE_VERSION}/stat.xsl /usr/local/nginx/html/stat.xsl && \ + rm -rf /tmp/build + +##### Building the final image ##### +FROM debian:${DEBIAN_VERSION} + +# Install dependencies +RUN apt-get update && \ + apt-get install -y \ + ca-certificates openssl libpcre3-dev \ + librtmp1 libtheora0 libvorbis-dev libmp3lame0 \ + libvpx4 libx264-dev libx265-dev && \ + rm -rf /var/lib/apt/lists/* + +# Copy files from build stage to final stage +COPY --from=builder /usr/local /usr/local +COPY --from=builder /etc/nginx /etc/nginx +COPY --from=builder /var/log/nginx /var/log/nginx +COPY --from=builder /var/lock /var/lock +COPY --from=builder /var/run/nginx /var/run/nginx + +# Forward logs to Docker +RUN ln -sf /dev/stdout /var/log/nginx/access.log && \ + ln -sf /dev/stderr /var/log/nginx/error.log + +# Copy nginx config file to container +COPY conf/nginx.conf /etc/nginx/nginx.conf + +# Copy html players to container +COPY players /usr/local/nginx/html/players + +EXPOSE 1935 +EXPOSE 8080 + +CMD ["nginx", "-g", "daemon off;"] diff --git a/Dockerfile-alpine b/Dockerfile-alpine new file mode 100644 index 0000000..f939ad7 --- /dev/null +++ b/Dockerfile-alpine @@ -0,0 +1,118 @@ +ARG ALPINE_VERSION=3.11 + +##### Building stage ##### +FROM alpine:${ALPINE_VERSION} as builder +MAINTAINER Tareq Alqutami + +# Versions of nginx, rtmp-module and ffmpeg +ARG NGINX_VERSION=1.17.5 +ARG NGINX_RTMP_MODULE_VERSION=1.2.1 +ARG FFMPEG_VERSION=4.2.1 + +# Install dependencies +RUN apk update && \ + apk --no-cache add \ + bash build-base ca-certificates \ + openssl openssl-dev make \ + gcc libgcc libc-dev rtmpdump-dev \ + zlib-dev musl-dev pcre pcre-dev lame-dev \ + yasm pkgconf pkgconfig libtheora-dev \ + libvorbis-dev libvpx-dev freetype-dev \ + x264-dev x265-dev && \ + rm -rf /var/lib/apt/lists/* + +# Download nginx source +RUN mkdir -p /tmp/build && \ + cd /tmp/build && \ + wget https://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz && \ + tar zxf nginx-${NGINX_VERSION}.tar.gz && \ + rm nginx-${NGINX_VERSION}.tar.gz + +# Download rtmp-module source +RUN cd /tmp/build && \ + wget https://github.com/arut/nginx-rtmp-module/archive/v${NGINX_RTMP_MODULE_VERSION}.tar.gz && \ + tar zxf v${NGINX_RTMP_MODULE_VERSION}.tar.gz && \ + rm v${NGINX_RTMP_MODULE_VERSION}.tar.gz + +# Build nginx with nginx-rtmp module +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 \ + --http-log-path=/var/log/nginx/access.log \ + --pid-path=/var/run/nginx/nginx.pid \ + --lock-path=/var/lock/nginx.lock \ + --http-client-body-temp-path=/tmp/nginx-client-body \ + --with-http_ssl_module \ + --with-threads \ + --add-module=/tmp/build/nginx-rtmp-module-${NGINX_RTMP_MODULE_VERSION} && \ + make CFLAGS=-Wno-error -j $(getconf _NPROCESSORS_ONLN) && \ + make install + +# Download ffmpeg source +RUN cd /tmp/build && \ + wget http://ffmpeg.org/releases/ffmpeg-${FFMPEG_VERSION}.tar.gz && \ + tar zxf ffmpeg-${FFMPEG_VERSION}.tar.gz && \ + rm ffmpeg-${FFMPEG_VERSION}.tar.gz + +# Build ffmpeg +RUN cd /tmp/build/ffmpeg-${FFMPEG_VERSION} && \ + ./configure \ + --enable-version3 \ + --enable-gpl \ + --enable-small \ + --enable-libx264 \ + --enable-libx265 \ + --enable-libvpx \ + --enable-libtheora \ + --enable-libvorbis \ + --enable-librtmp \ + --enable-postproc \ + --enable-avresample \ + --enable-swresample \ + --enable-libfreetype \ + --enable-libmp3lame \ + --disable-debug \ + --disable-doc \ + --disable-ffplay \ + --extra-libs="-lpthread -lm" && \ + make -j $(getconf _NPROCESSORS_ONLN) && \ + make install + +# Copy stats.xsl file to nginx html directory and clean build files +RUN cp /tmp/build/nginx-rtmp-module-${NGINX_RTMP_MODULE_VERSION}/stat.xsl /usr/local/nginx/html/stat.xsl && \ + rm -rf /tmp/build + +##### Building the final image ##### +FROM alpine:${ALPINE_VERSION} + +# Install dependencies +RUN apk update && \ + apk --no-cache add \ + bash ca-certificates openssl \ + pcre libtheora libvorbis libvpx \ + librtmp x264-dev x265-dev freetype lame && \ + rm -rf /var/lib/apt/lists/* + +# Copy files from build stage to final stage +COPY --from=builder /usr/local /usr/local +COPY --from=builder /etc/nginx /etc/nginx +COPY --from=builder /var/log/nginx /var/log/nginx +COPY --from=builder /var/lock /var/lock +COPY --from=builder /var/run/nginx /var/run/nginx + +# Forward logs to Docker +RUN ln -sf /dev/stdout /var/log/nginx/access.log && \ + ln -sf /dev/stderr /var/log/nginx/error.log + +# Copy nginx config file to container +COPY conf/nginx.conf /etc/nginx/nginx.conf + +# Copy html players to container +COPY players /usr/local/nginx/html/players + +EXPOSE 1935 +EXPOSE 8080 + +CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file diff --git a/Dockerfile-nvenc b/Dockerfile-nvenc new file mode 100644 index 0000000..77d0e68 --- /dev/null +++ b/Dockerfile-nvenc @@ -0,0 +1,124 @@ +##### Building stage ##### +FROM nvidia/cuda:11.1-devel-ubuntu20.04 as builder +MAINTAINER Kieran Harkin + +# Versions of nginx, rtmp-module and ffmpeg +ENV TZ=Europe/Dublin +ARG NGINX_VERSION=1.19.4 +ARG NGINX_RTMP_MODULE_VERSION=1.2.1 +ARG FFMPEG_VERSION=4.3.1 + +# Install dependencies +RUN apt update && \ + apt install -y --no-install-recommends \ + wget gcc make autoconf automake ca-certificates \ + openssl libssl-dev yasm git pkg-config \ + libpcre3-dev librtmp-dev libtheora-dev && \ + rm -rf /var/lib/apt/lists/* + +# Download nginx source +RUN mkdir -p /tmp/build && \ + cd /tmp/build && \ + wget https://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz && \ + tar -zxf nginx-${NGINX_VERSION}.tar.gz && \ + rm nginx-${NGINX_VERSION}.tar.gz + +# Download rtmp-module source +RUN cd /tmp/build && \ + wget https://github.com/arut/nginx-rtmp-module/archive/v${NGINX_RTMP_MODULE_VERSION}.tar.gz && \ + tar -zxf v${NGINX_RTMP_MODULE_VERSION}.tar.gz && \ + rm v${NGINX_RTMP_MODULE_VERSION}.tar.gz + +# Build nginx with nginx-rtmp module +RUN cd /tmp/build/nginx-${NGINX_VERSION} && \ + ./configure \ + --prefix=/app/nginx \ + --conf-path=/etc/nginx/nginx.conf \ + --error-log-path=/var/log/nginx/error.log \ + --http-log-path=/var/log/nginx/access.log \ + --pid-path=/var/run/nginx/nginx.pid \ + --lock-path=/var/lock/nginx.lock \ + --http-client-body-temp-path=/tmp/nginx-client-body \ + --with-http_ssl_module \ + --with-threads \ + --add-module=/tmp/build/nginx-rtmp-module-${NGINX_RTMP_MODULE_VERSION} \ + --with-cc-opt="-Wimplicit-fallthrough=0" && \ + make -j $(getconf _NPROCESSORS_ONLN) && \ + make install + +# Download ffmpeg source +RUN cd /tmp/build && \ + wget http://ffmpeg.org/releases/ffmpeg-${FFMPEG_VERSION}.tar.gz && \ + tar -zxf ffmpeg-${FFMPEG_VERSION}.tar.gz && \ + rm ffmpeg-${FFMPEG_VERSION}.tar.gz + +# Get ffnvcodec +RUN git clone https://git.videolan.org/git/ffmpeg/nv-codec-headers.git && \ + cd nv-codec-headers && \ + make -j $(getconf _NPROCESSORS_ONLN) && \ + make install + +# Build ffmpeg +RUN cd /tmp/build/ffmpeg-${FFMPEG_VERSION} && \ + ./configure \ + --prefix=/app/ffmpeg \ + --enable-cuda \ + --enable-cuvid \ + --enable-nvenc \ + --enable-nonfree \ + --enable-libnpp \ + --extra-cflags=-I/usr/local/cuda/include \ + --extra-ldflags=-L/usr/local/cuda/lib64 \ + --disable-debug \ + --disable-doc \ + --disable-ffplay \ + --extra-libs="-lpthread -lm" && \ + make -j $(getconf _NPROCESSORS_ONLN) && \ + make install + +# Copy stats.xsl file to nginx html directory and cleaning build files +RUN cp /tmp/build/nginx-rtmp-module-${NGINX_RTMP_MODULE_VERSION}/stat.xsl /app/nginx/html/stat.xsl && \ + rm -rf /tmp/build + +##### Building the final image ##### +FROM nvidia/cuda:11.1-runtime-ubuntu20.04 + +ENV NVIDIA_DRIVER_VERSION=455 +ENV NVIDIA_VISIBLE_DEVICES all +ENV NVIDIA_DRIVER_CAPABILITIES compute,video,utility + +#Setup nvidia-patch +COPY patch.sh docker-entrypoint.sh /app/ +RUN mkdir -p /patched-lib && \ + chmod +x /app/patch.sh /app/docker-entrypoint.sh && \ + ln -s /app/patch.sh /usr/local/bin/patch.sh + +# Install dependencies +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + ca-certificates openssl libpcre3-dev \ + librtmp1 libtheora0 libnvidia-decode-$NVIDIA_DRIVER_VERSION libnvidia-encode-$NVIDIA_DRIVER_VERSION && \ + rm -rf /var/lib/apt/lists/* + +# Copy files from build stage to final stage +COPY --from=builder /app /app +COPY --from=builder /etc/nginx /etc/nginx +COPY --from=builder /var/log/nginx /var/log/nginx +COPY --from=builder /var/lock /var/lock +COPY --from=builder /var/run/nginx /var/run/nginx + +# Forward logs to Docker +RUN ln -sf /dev/stdout /var/log/nginx/access.log && \ + ln -sf /dev/stderr /var/log/nginx/error.log + +# Copy nginx config file to container +COPY conf/nginx-nvenc.conf /etc/nginx/nginx.conf + +# Copy html players to container +COPY players /app/nginx/html/players + +EXPOSE 1935 +EXPOSE 8080 + +ENTRYPOINT ["/app/docker-entrypoint.sh"] +CMD ["/app/nginx/sbin/nginx", "-g", "daemon off;"] diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..ad8434a --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Tareq Alqutami + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..4892573 --- /dev/null +++ b/README.md @@ -0,0 +1,97 @@ +# RTMP-HLS Docker + +**Docker image for video streaming server that supports RTMP, HLS, and DASH streams.** + +[![Docker Automated build](https://img.shields.io/docker/cloud/automated/alqutami/rtmp-hls.svg)](https://hub.docker.com/r/alqutami/rtmp-hls/builds/) +[![Build Status](https://img.shields.io/docker/cloud/build/alqutami/rtmp-hls.svg)](https://hub.docker.com/r/alqutami/rtmp-hls) + +## Description + +This Docker image can be used to create a video streaming server that supports [**RTMP**](https://en.wikipedia.org/wiki/Real-Time_Messaging_Protocol), [**HLS**](https://en.wikipedia.org/wiki/HTTP_Live_Streaming), [**DASH**](https://en.wikipedia.org/wiki/Dynamic_Adaptive_Streaming_over_HTTP) out of the box. +It also allows adaptive streaming and custom transcoding of video streams. +All modules are built from source on Debian and Alpine Linux base images. + +## Features + * The backend is [**Nginx**](http://nginx.org/en/) with [**nginx-rtmp-module**](https://github.com/arut/nginx-rtmp-module). + * [**FFmpeg**](https://www.ffmpeg.org/) for transcoding and adaptive streaming. + * Default settings: + * RTMP is ON + * HLS is ON (adaptive, 5 variants) + * DASH is ON + * Other Nginx configuration files are also provided to allow for RTMP-only streams or no-FFmpeg transcoding. + * Statistic page of RTMP streams at `http://:/stats`. + * Available web video players (based on [video.js](https://videojs.com/) and [hls.js](https://github.com/video-dev/hls.js/)) at `/usr/local/nginx/html/players`. + +Current Image is built using: + * Nginx 1.17.5 (compiled from source) + * Nginx-rtmp-module 1.2.1 (compiled from source) + * FFmpeg 4.2.1 (compiled from source) + +This image was inspired by similar docker images from [tiangolo](https://hub.docker.com/r/tiangolo/nginx-rtmp/) and [alfg](https://hub.docker.com/r/alfg/nginx-rtmp/). It has small build size, adds support for HTTP-based streams and adaptive streaming using FFmpeg. + +## Usage + +### To run the server +``` +docker run -d -p 1935:1935 -p 8080:8080 alqutami/rtmp-hls +``` + +For Alpine-based Image use: +``` +docker run -d -p 1935:1935 -p 8080:8080 alqutami/rtmp-hls:latest-alpine +``` + +To run with custom conf file: +``` +docker run -d -p 1935:1935 -p 8080:8080 -v custom.conf:/etc/nginx/nginx.conf alqutami/rtmp-hls +``` +where `custom.conf` is the new conf file for Nginx. + +### To stream to the server + * **Stream live RTMP content to:** + ``` + rtmp://:1935/live/ + ``` + where `` is any stream key you specify. + + * **Configure [OBS](https://obsproject.com/) to stream content:**
+Go to Settings > Stream, choose the following settings: + * Service: Custom Streaming Server. + * Server: `rtmp://:1935/live`. + * Stream key: anything you want, however provided video players assume stream key is `test` + +### To view the stream + * **Using [VLC](https://www.videolan.org/vlc/index.html):** + * Go to Media > Open Network Stream. + * Enter the streaming URL: `rtmp://:1935/live/` + Replace `` with the IP of where the server is running, and + `` with the stream key you used when setting up the stream. + * For HLS and DASH, the URLs are of the forms: + `http://:8080/hls/.m3u8` and + `http://:8080/dash/_src.mpd` respectively. + * Click Play. + +* **Using provided web players:**
+The provided demo players assume the stream-key is called `test` and the player is opened in localhost. + * To play RTMP content (requires Flash): `http://localhost:8080/players/rtmp.html` + * To play HLS content: `http://localhost:8080/players/hls.html` + * To play HLS content using hls.js library: `http://localhost:8080/players/hls_hlsjs.html` + * To play DASH content: `http://localhost:8080/players/dash.html` + * To play RTMP and HLS contents on the same page: `http://localhost:8080/players/rtmp_hls.html` + + **Notes:** + + * These web players are hardcoded to play stream key "test" at localhost. + * To change the stream source for these players. Download the html files and modify the `src` attribute in the video tag in the html file. You can then mount the modified files to the container as follows: + ``` + docker run -d -p 1935:1935 -p 8080:8080 -v custom_players:/usr/local/nginx/html/players alqutami/rtmp-hls + ``` + where `custom_players` is the directory holding the modified html files. + +## Copyright +Released under MIT license. + +## More info + * **GitHub repo**: + + * **Docker Hub image**: diff --git a/conf/nginx-nvenc.conf b/conf/nginx-nvenc.conf new file mode 100644 index 0000000..d20bd4b --- /dev/null +++ b/conf/nginx-nvenc.conf @@ -0,0 +1,132 @@ +worker_processes auto; +#error_log logs/error.log; + +events { + worker_connections 1024; +} + +# RTMP configuration +rtmp { + server { + listen 1935; # Listen on standard RTMP port + chunk_size 4000; + # ping 30s; + # notify_method get; + + # This application is to accept incoming stream + application live { + live on; # Allows live input + + # for each received stream, transcode for adaptive streaming + # This single ffmpeg command takes the input and transforms + # the source into 4 different streams with different bitrates + # and qualities. # these settings respect the aspect ratio. + exec_push /app/ffmpeg/bin/ffmpeg -async 1 -vsync -1 -hwaccel cuvid -c:v h264_cuvid -i rtmp://localhost:1935/$app/$name + -c:v h264_nvenc -c:a aac -b:v 256k -b:a 64k -vf "scale_npp=480:trunc(ow/a/2)*2" -zerolatency 1 -f flv rtmp://localhost:1935/show/$name_low + -c:v h264_nvenc -c:a aac -b:v 768k -b:a 128k -vf "scale_npp=720:trunc(ow/a/2)*2" -zerolatency 1 -f flv rtmp://localhost:1935/show/$name_mid + -c:v h264_nvenc -c:a aac -b:v 1024k -b:a 128k -vf "scale_npp=960:trunc(ow/a/2)*2" -zerolatency 1 -f flv rtmp://localhost:1935/show/$name_high + -c:v h264_nvenc -c:a aac -b:v 1920k -b:a 128k -vf "scale_npp=1280:trunc(ow/a/2)*2" -zerolatency 1 -f flv rtmp://localhost:1935/show/$name_hd720 + -c copy -f flv rtmp://localhost:1935/show/$name_src; + drop_idle_publisher 10s; + } + + # This is the HLS application + application show { + live on; # Allows live input from above application + deny play all; # disable consuming the stream from nginx as rtmp + + hls on; # Enable HTTP Live Streaming + hls_fragment 3; + hls_playlist_length 20; + hls_path /mnt/hls/; # hls fragments path + # Instruct clients to adjust resolution according to bandwidth + hls_variant _src BANDWIDTH=4096000; # Source bitrate, source resolution + hls_variant _hd720 BANDWIDTH=2048000; # High bitrate, HD 720p resolution + hls_variant _high BANDWIDTH=1152000; # High bitrate, higher-than-SD resolution + hls_variant _mid BANDWIDTH=448000; # Medium bitrate, SD resolution + hls_variant _low BANDWIDTH=288000; # Low bitrate, sub-SD resolution + + # MPEG-DASH + dash on; + dash_path /mnt/dash/; # dash fragments path + dash_fragment 3; + dash_playlist_length 20; + } + } +} + + +http { + sendfile off; + tcp_nopush on; + directio 512; + # aio on; + + # HTTP server required to serve the player and HLS fragments + server { + listen 8080; + + # Serve HLS fragments + location /hls { + types { + application/vnd.apple.mpegurl m3u8; + video/mp2t ts; + } + + root /mnt; + + add_header Cache-Control no-cache; # Disable cache + + # CORS setup + add_header 'Access-Control-Allow-Origin' '*' always; + add_header 'Access-Control-Expose-Headers' 'Content-Length'; + + # allow CORS preflight requests + if ($request_method = 'OPTIONS') { + add_header 'Access-Control-Allow-Origin' '*'; + add_header 'Access-Control-Max-Age' 1728000; + add_header 'Content-Type' 'text/plain charset=UTF-8'; + add_header 'Content-Length' 0; + return 204; + } + } + + # Serve DASH fragments + location /dash { + types { + application/dash+xml mpd; + video/mp4 mp4; + } + + root /mnt; + + add_header Cache-Control no-cache; # Disable cache + + + # CORS setup + add_header 'Access-Control-Allow-Origin' '*' always; + add_header 'Access-Control-Expose-Headers' 'Content-Length'; + + # Allow CORS preflight requests + if ($request_method = 'OPTIONS') { + add_header 'Access-Control-Allow-Origin' '*'; + add_header 'Access-Control-Max-Age' 1728000; + add_header 'Content-Type' 'text/plain charset=UTF-8'; + add_header 'Content-Length' 0; + return 204; + } + } + + # This URL provides RTMP statistics in XML + location /stat { + rtmp_stat all; + rtmp_stat_stylesheet stat.xsl; # Use stat.xsl stylesheet + } + + location /stat.xsl { + # XML stylesheet to view RTMP stats. + root /app/nginx/html; + } + + } +} diff --git a/conf/nginx.conf b/conf/nginx.conf new file mode 100644 index 0000000..cece393 --- /dev/null +++ b/conf/nginx.conf @@ -0,0 +1,132 @@ +worker_processes auto; +#error_log logs/error.log; + +events { + worker_connections 1024; +} + +# RTMP configuration +rtmp { + server { + listen 1935; # Listen on standard RTMP port + chunk_size 4000; + # ping 30s; + # notify_method get; + + # This application is to accept incoming stream + application live { + live on; # Allows live input + + # for each received stream, transcode for adaptive streaming + # This single ffmpeg command takes the input and transforms + # the source into 4 different streams with different bitrates + # and qualities. # these settings respect the aspect ratio. + exec_push /usr/local/bin/ffmpeg -i rtmp://localhost:1935/$app/$name -async 1 -vsync -1 + -c:v libx264 -c:a aac -b:v 256k -b:a 64k -vf "scale=480:trunc(ow/a/2)*2" -tune zerolatency -preset superfast -crf 23 -f flv rtmp://localhost:1935/show/$name_low + -c:v libx264 -c:a aac -b:v 768k -b:a 128k -vf "scale=720:trunc(ow/a/2)*2" -tune zerolatency -preset superfast -crf 23 -f flv rtmp://localhost:1935/show/$name_mid + -c:v libx264 -c:a aac -b:v 1024k -b:a 128k -vf "scale=960:trunc(ow/a/2)*2" -tune zerolatency -preset superfast -crf 23 -f flv rtmp://localhost:1935/show/$name_high + -c:v libx264 -c:a aac -b:v 1920k -b:a 128k -vf "scale=1280:trunc(ow/a/2)*2" -tune zerolatency -preset superfast -crf 23 -f flv rtmp://localhost:1935/show/$name_hd720 + -c copy -f flv rtmp://localhost:1935/show/$name_src; + drop_idle_publisher 10s; + } + + # This is the HLS application + application show { + live on; # Allows live input from above application + deny play all; # disable consuming the stream from nginx as rtmp + + hls on; # Enable HTTP Live Streaming + hls_fragment 3; + hls_playlist_length 20; + hls_path /mnt/hls/; # hls fragments path + # Instruct clients to adjust resolution according to bandwidth + hls_variant _src BANDWIDTH=4096000; # Source bitrate, source resolution + hls_variant _hd720 BANDWIDTH=2048000; # High bitrate, HD 720p resolution + hls_variant _high BANDWIDTH=1152000; # High bitrate, higher-than-SD resolution + hls_variant _mid BANDWIDTH=448000; # Medium bitrate, SD resolution + hls_variant _low BANDWIDTH=288000; # Low bitrate, sub-SD resolution + + # MPEG-DASH + dash on; + dash_path /mnt/dash/; # dash fragments path + dash_fragment 3; + dash_playlist_length 20; + } + } +} + + +http { + sendfile off; + tcp_nopush on; + directio 512; + # aio on; + + # HTTP server required to serve the player and HLS fragments + server { + listen 8080; + + # Serve HLS fragments + location /hls { + types { + application/vnd.apple.mpegurl m3u8; + video/mp2t ts; + } + + root /mnt; + + add_header Cache-Control no-cache; # Disable cache + + # CORS setup + add_header 'Access-Control-Allow-Origin' '*' always; + add_header 'Access-Control-Expose-Headers' 'Content-Length'; + + # allow CORS preflight requests + if ($request_method = 'OPTIONS') { + add_header 'Access-Control-Allow-Origin' '*'; + add_header 'Access-Control-Max-Age' 1728000; + add_header 'Content-Type' 'text/plain charset=UTF-8'; + add_header 'Content-Length' 0; + return 204; + } + } + + # Serve DASH fragments + location /dash { + types { + application/dash+xml mpd; + video/mp4 mp4; + } + + root /mnt; + + add_header Cache-Control no-cache; # Disable cache + + + # CORS setup + add_header 'Access-Control-Allow-Origin' '*' always; + add_header 'Access-Control-Expose-Headers' 'Content-Length'; + + # Allow CORS preflight requests + if ($request_method = 'OPTIONS') { + add_header 'Access-Control-Allow-Origin' '*'; + add_header 'Access-Control-Max-Age' 1728000; + add_header 'Content-Type' 'text/plain charset=UTF-8'; + add_header 'Content-Length' 0; + return 204; + } + } + + # This URL provides RTMP statistics in XML + location /stat { + rtmp_stat all; + rtmp_stat_stylesheet stat.xsl; # Use stat.xsl stylesheet + } + + location /stat.xsl { + # XML stylesheet to view RTMP stats. + root /usr/local/nginx/html; + } + + } +} diff --git a/conf/nginx_no-ffmpeg.conf b/conf/nginx_no-ffmpeg.conf new file mode 100644 index 0000000..e59112e --- /dev/null +++ b/conf/nginx_no-ffmpeg.conf @@ -0,0 +1,115 @@ +worker_processes auto; +#error_log logs/error.log; + +events { + worker_connections 1024; +} + +# RTMP configuration +rtmp { + server { + listen 1935; # Listen on standard RTMP port + chunk_size 4000; + # ping 30s; + # notify_method get; + + # This application is to accept incoming stream + application live { + live on; # Allows live input + push rtmp://localhost:1935/show; + } + + # This is the HLS application + application show { + live on; # Allows live input from above application + deny play all; # disable consuming the stream from nginx as rtmp + + hls on; # Enable HTTP Live Streaming + hls_fragment 3; + hls_playlist_length 10; + hls_path /mnt/hls/; # hls fragments path + + # MPEG-DASH + dash on; + dash_path /mnt/dash/; # dash fragments path + dash_fragment 3; + dash_playlist_length 10; + } + } +} + + +http { + sendfile off; + tcp_nopush on; + directio 512; + # aio on; + + # HTTP server required to serve the player and HLS fragments + server { + listen 8080; + + # Serve HLS fragments + location /hls { + types { + application/vnd.apple.mpegurl m3u8; + video/mp2t ts; + } + + root /mnt; + + add_header Cache-Control no-cache; # Disable cache + + # CORS setup + add_header 'Access-Control-Allow-Origin' '*' always; + add_header 'Access-Control-Expose-Headers' 'Content-Length'; + + # allow CORS preflight requests + if ($request_method = 'OPTIONS') { + add_header 'Access-Control-Allow-Origin' '*'; + add_header 'Access-Control-Max-Age' 1728000; + add_header 'Content-Type' 'text/plain charset=UTF-8'; + add_header 'Content-Length' 0; + return 204; + } + } + + # Serve DASH fragments + location /dash { + types { + application/dash+xml mpd; + video/mp4 mp4; + } + + root /mnt; + + add_header Cache-Control no-cache; # Disable cache + + + # CORS setup + add_header 'Access-Control-Allow-Origin' '*' always; + add_header 'Access-Control-Expose-Headers' 'Content-Length'; + + # Allow CORS preflight requests + if ($request_method = 'OPTIONS') { + add_header 'Access-Control-Allow-Origin' '*'; + add_header 'Access-Control-Max-Age' 1728000; + add_header 'Content-Type' 'text/plain charset=UTF-8'; + add_header 'Content-Length' 0; + return 204; + } + } + + # This URL provides RTMP statistics in XML + location /stat { + rtmp_stat all; + rtmp_stat_stylesheet stat.xsl; # Use stat.xsl stylesheet + } + + location /stat.xsl { + # XML stylesheet to view RTMP stats. + root /usr/local/nginx/html; + } + + } +} \ No newline at end of file diff --git a/conf/nginx_rtmp_minimal_no-stats.conf b/conf/nginx_rtmp_minimal_no-stats.conf new file mode 100644 index 0000000..b1bc6b7 --- /dev/null +++ b/conf/nginx_rtmp_minimal_no-stats.conf @@ -0,0 +1,14 @@ +worker_processes auto; +rtmp_auto_push on; +events {} +rtmp { + server { + listen 1935; + listen [::]:1935; + + application live { + live on; + record off; + } + } +} \ No newline at end of file diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh new file mode 100644 index 0000000..f70139a --- /dev/null +++ b/docker-entrypoint.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +echo "/patched-lib" > /etc/ld.so.conf.d/000-patched-lib.conf && \ +mkdir -p "/patched-lib" && \ +PATCH_OUTPUT_DIR=/patched-lib /usr/local/bin/patch.sh && \ +cd /patched-lib && \ +for f in * ; do + suffix="${f##*.so}" + name="$(basename "$f" "$suffix")" + [ -h "$name" ] || ln -sf "$f" "$name" + [ -h "$name" ] || ln -sf "$f" "$name.1" +done && \ +ldconfig +[ "$OLDPWD" ] && cd - +exec "$@" diff --git a/patch.sh b/patch.sh new file mode 100644 index 0000000..30f85f6 --- /dev/null +++ b/patch.sh @@ -0,0 +1,362 @@ +#!/bin/bash +# halt on any error for safety and proper pipe handling +set -euo pipefail ; # <- this semicolon and comment make options apply +# even when script is corrupt by CRLF line terminators (issue #75) +# empty line must follow this comment for immediate fail with CRLF newlines + +backup_path="/opt/nvidia/libnvidia-encode-backup" +silent_flag='' +manual_driver_version='' + +print_usage() { printf ' +SYNOPSIS + patch.sh [-s] [-r|-h|-c VERSION|-l] + +DESCRIPTION + The patch for Nvidia drivers to remove NVENC session limit + + -s Silent mode (No output) + -r Rollback to original (Restore lib from backup) + -h Print this help message + -c VERSION Check if version VERSION supported by this patch. + Returns true exit code (0) if version is supported. + -l List supported driver versions + -d VERSION Use VERSION driver version when looking for libraries + instead of using nvidia-smi to detect it. +' +} + +# shellcheck disable=SC2209 +opmode="patch" + +while getopts 'rshc:ld:' flag; do + case "${flag}" in + r) opmode="${opmode}rollback" ;; + s) silent_flag='true' ;; + h) opmode="${opmode}help" ;; + c) opmode="${opmode}checkversion" ; checked_version="$OPTARG" ;; + l) opmode="${opmode}listversions" ;; + d) manual_driver_version="$OPTARG" ;; + *) echo "Incorrect option specified in command line" ; exit 2 ;; + esac +done + +if [[ $silent_flag ]]; then + exec 1> /dev/null +fi + +declare -A patch_list=( + ["375.39"]='s/\x85\xC0\x89\xC5\x75\x18/\x29\xC0\x89\xC5\x90\x90/g' + ["390.77"]='s/\x85\xC0\x89\xC5\x75\x18/\x29\xC0\x89\xC5\x90\x90/g' + ["390.87"]='s/\x85\xC0\x89\xC5\x75\x18/\x29\xC0\x89\xC5\x90\x90/g' + ["396.24"]='s/\x85\xC0\x89\xC5\x0F\x85\x96\x00\x00\x00/\x29\xC0\x89\xC5\x90\x90\x90\x90\x90\x90/g' + ["396.26"]='s/\x85\xC0\x89\xC5\x0F\x85\x96\x00\x00\x00/\x29\xC0\x89\xC5\x90\x90\x90\x90\x90\x90/g' + ["396.37"]='s/\x85\xC0\x89\xC5\x0F\x85\x96\x00\x00\x00/\x29\xC0\x89\xC5\x90\x90\x90\x90\x90\x90/g' #added info from https://github.com/keylase/nvidia-patch/issues/6#issuecomment-406895356 + # break nvenc.c:236,layout asm,step-mode,step,break *0x00007fff89f9ba45 + # libnvidia-encode.so @ 0x15a45; test->sub, jne->nop-nop-nop-nop-nop-nop + ["396.54"]='s/\x85\xC0\x89\xC5\x0F\x85\x96\x00\x00\x00/\x29\xC0\x89\xC5\x90\x90\x90\x90\x90\x90/g' + ["410.48"]='s/\x85\xC0\x89\xC5\x0F\x85\x96\x00\x00\x00/\x29\xC0\x89\xC5\x90\x90\x90\x90\x90\x90/g' + ["410.57"]='s/\x85\xC0\x89\xC5\x0F\x85\x96\x00\x00\x00/\x29\xC0\x89\xC5\x90\x90\x90\x90\x90\x90/g' + ["410.73"]='s/\x85\xC0\x89\xC5\x0F\x85\x96\x00\x00\x00/\x29\xC0\x89\xC5\x90\x90\x90\x90\x90\x90/g' + ["410.78"]='s/\x85\xC0\x89\xC5\x0F\x85\x96\x00\x00\x00/\x29\xC0\x89\xC5\x90\x90\x90\x90\x90\x90/g' + ["410.79"]='s/\x85\xC0\x89\xC5\x0F\x85\x96\x00\x00\x00/\x29\xC0\x89\xC5\x90\x90\x90\x90\x90\x90/g' + ["410.93"]='s/\x85\xC0\x89\xC5\x0F\x85\x96\x00\x00\x00/\x29\xC0\x89\xC5\x90\x90\x90\x90\x90\x90/g' + ["410.104"]='s/\x85\xC0\x89\xC5\x0F\x85\x96\x00\x00\x00/\x29\xC0\x89\xC5\x90\x90\x90\x90\x90\x90/g' + ["415.18"]='s/\x00\x00\x00\x84\xc0\x0f\x84\x40\xfd\xff\xff/\x00\x00\x00\x84\xc0\x90\x90\x90\x90\x90\x90/g' + ["415.25"]='s/\x00\x00\x00\x84\xc0\x0f\x84\x40\xfd\xff\xff/\x00\x00\x00\x84\xc0\x90\x90\x90\x90\x90\x90/g' + ["415.27"]='s/\x00\x00\x00\x84\xc0\x0f\x84\x40\xfd\xff\xff/\x00\x00\x00\x84\xc0\x90\x90\x90\x90\x90\x90/g' + ["418.30"]='s/\x00\x00\x00\x84\xc0\x0f\x84\x40\xfd\xff\xff/\x00\x00\x00\x84\xc0\x90\x90\x90\x90\x90\x90/g' + ["418.43"]='s/\x00\x00\x00\x84\xc0\x0f\x84\x40\xfd\xff\xff/\x00\x00\x00\x84\xc0\x90\x90\x90\x90\x90\x90/g' + ["418.56"]='s/\x00\x00\x00\x84\xc0\x0f\x84\x40\xfd\xff\xff/\x00\x00\x00\x84\xc0\x90\x90\x90\x90\x90\x90/g' + ["418.67"]='s/\x00\x00\x00\x84\xc0\x0f\x84\x40\xfd\xff\xff/\x00\x00\x00\x84\xc0\x90\x90\x90\x90\x90\x90/g' + ["418.74"]='s/\x00\x00\x00\x84\xc0\x0f\x84\x0f\xfd\xff\xff/\x00\x00\x00\x84\xc0\x90\x90\x90\x90\x90\x90/g' + ["418.87.00"]='s/\x00\x00\x00\x84\xc0\x0f\x84\x0f\xfd\xff\xff/\x00\x00\x00\x84\xc0\x90\x90\x90\x90\x90\x90/g' + ["418.87.01"]='s/\x00\x00\x00\x84\xc0\x0f\x84\x0f\xfd\xff\xff/\x00\x00\x00\x84\xc0\x90\x90\x90\x90\x90\x90/g' + ["418.88"]='s/\x00\x00\x00\x84\xc0\x0f\x84\x0f\xfd\xff\xff/\x00\x00\x00\x84\xc0\x90\x90\x90\x90\x90\x90/g' + ["418.113"]='s/\x00\x00\x00\x84\xc0\x0f\x84\x0f\xfd\xff\xff/\x00\x00\x00\x84\xc0\x90\x90\x90\x90\x90\x90/g' + ["430.09"]='s/\x00\x00\x00\x84\xc0\x0f\x84\x0f\xfd\xff\xff/\x00\x00\x00\x84\xc0\x90\x90\x90\x90\x90\x90/g' + ["430.14"]='s/\x00\x00\x00\x84\xc0\x0f\x84\x0f\xfd\xff\xff/\x00\x00\x00\x84\xc0\x90\x90\x90\x90\x90\x90/g' + ["430.26"]='s/\x00\x00\x00\x84\xc0\x0f\x84\x0f\xfd\xff\xff/\x00\x00\x00\x84\xc0\x90\x90\x90\x90\x90\x90/g' + ["430.34"]='s/\x00\x00\x00\x84\xc0\x0f\x84\x0f\xfd\xff\xff/\x00\x00\x00\x84\xc0\x90\x90\x90\x90\x90\x90/g' + ["430.40"]='s/\x00\x00\x00\x84\xc0\x0f\x84\x0f\xfd\xff\xff/\x00\x00\x00\x84\xc0\x90\x90\x90\x90\x90\x90/g' + ["430.50"]='s/\x00\x00\x00\x84\xc0\x0f\x84\x0f\xfd\xff\xff/\x00\x00\x00\x84\xc0\x90\x90\x90\x90\x90\x90/g' + ["430.64"]='s/\x00\x00\x00\x84\xc0\x0f\x84\x0f\xfd\xff\xff/\x00\x00\x00\x84\xc0\x90\x90\x90\x90\x90\x90/g' + ["435.17"]='s/\x00\x00\x00\x84\xc0\x0f\x84\x0f\xfd\xff\xff/\x00\x00\x00\x84\xc0\x90\x90\x90\x90\x90\x90/g' + ["435.21"]='s/\x00\x00\x00\x84\xc0\x0f\x84\x0f\xfd\xff\xff/\x00\x00\x00\x84\xc0\x90\x90\x90\x90\x90\x90/g' + ["435.27.08"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["440.26"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["440.31"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["440.33.01"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["440.36"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["440.43.01"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["440.44"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["440.48.02"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["440.58.01"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["440.58.02"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["440.59"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["440.64"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["440.64.00"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["440.66.02"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["440.66.03"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["440.66.04"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["440.66.08"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["440.66.09"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["440.66.11"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["440.66.12"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["440.66.14"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["440.66.15"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["440.66.17"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["440.82"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["440.95.01"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["440.100"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["440.118.02"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["450.36.06"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["450.51"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["450.51.05"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["450.51.06"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["450.56.01"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["450.56.02"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["450.56.06"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["450.56.11"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["450.57"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["450.66"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["450.80.02"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["450.102.04"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["455.22.04"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["455.23.04"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["455.23.05"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["455.26.01"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["455.26.02"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["455.28"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["455.32.00"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["455.38"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["455.45.01"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["455.46.01"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["455.46.02"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["455.46.04"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["455.50.02"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["455.50.04"]='s/\x85\xc0\x41\x89\xc4\x75\x1f/\x31\xc0\x41\x89\xc4\x75\x1f/g' + ["460.27.04"]='s/\x22\xff\xff\x85\xc0\x41\x89\xc4\x0f\x85/\x22\xff\xff\x31\xc0\x41\x89\xc4\x0f\x85/g' + ["460.32.03"]='s/\x22\xff\xff\x85\xc0\x41\x89\xc4\x0f\x85/\x22\xff\xff\x31\xc0\x41\x89\xc4\x0f\x85/g' + ["460.39"]='s/\x22\xff\xff\x85\xc0\x41\x89\xc4\x0f\x85/\x22\xff\xff\x31\xc0\x41\x89\xc4\x0f\x85/g' +) + +declare -A object_list=( + ["375.39"]='libnvidia-encode.so' + ["390.77"]='libnvidia-encode.so' + ["390.87"]='libnvidia-encode.so' + ["396.24"]='libnvidia-encode.so' + ["396.26"]='libnvidia-encode.so' + ["396.37"]='libnvidia-encode.so' + ["396.54"]='libnvidia-encode.so' + ["410.48"]='libnvidia-encode.so' + ["410.57"]='libnvidia-encode.so' + ["410.73"]='libnvidia-encode.so' + ["410.78"]='libnvidia-encode.so' + ["410.79"]='libnvidia-encode.so' + ["410.93"]='libnvidia-encode.so' + ["410.104"]='libnvidia-encode.so' + ["415.18"]='libnvcuvid.so' + ["415.25"]='libnvcuvid.so' + ["415.27"]='libnvcuvid.so' + ["418.30"]='libnvcuvid.so' + ["418.43"]='libnvcuvid.so' + ["418.56"]='libnvcuvid.so' + ["418.67"]='libnvcuvid.so' + ["418.74"]='libnvcuvid.so' + ["418.87.00"]='libnvcuvid.so' + ["418.87.01"]='libnvcuvid.so' + ["418.88"]='libnvcuvid.so' + ["418.113"]='libnvcuvid.so' + ["430.09"]='libnvcuvid.so' + ["430.14"]='libnvcuvid.so' + ["430.26"]='libnvcuvid.so' + ["430.34"]='libnvcuvid.so' + ["430.40"]='libnvcuvid.so' + ["430.50"]='libnvcuvid.so' + ["430.64"]='libnvcuvid.so' + ["435.17"]='libnvcuvid.so' + ["435.21"]='libnvcuvid.so' + ["435.27.08"]='libnvidia-encode.so' + ["440.26"]='libnvidia-encode.so' + ["440.31"]='libnvidia-encode.so' + ["440.33.01"]='libnvidia-encode.so' + ["440.36"]='libnvidia-encode.so' + ["440.43.01"]='libnvidia-encode.so' + ["440.44"]='libnvidia-encode.so' + ["440.48.02"]='libnvidia-encode.so' + ["440.58.01"]='libnvidia-encode.so' + ["440.58.02"]='libnvidia-encode.so' + ["440.59"]='libnvidia-encode.so' + ["440.64"]='libnvidia-encode.so' + ["440.64.00"]='libnvidia-encode.so' + ["440.66.02"]='libnvidia-encode.so' + ["440.66.03"]='libnvidia-encode.so' + ["440.66.04"]='libnvidia-encode.so' + ["440.66.08"]='libnvidia-encode.so' + ["440.66.09"]='libnvidia-encode.so' + ["440.66.11"]='libnvidia-encode.so' + ["440.66.12"]='libnvidia-encode.so' + ["440.66.14"]='libnvidia-encode.so' + ["440.66.15"]='libnvidia-encode.so' + ["440.66.17"]='libnvidia-encode.so' + ["440.82"]='libnvidia-encode.so' + ["440.95.01"]='libnvidia-encode.so' + ["440.100"]='libnvidia-encode.so' + ["440.118.02"]='libnvidia-encode.so' + ["450.36.06"]='libnvidia-encode.so' + ["450.51"]='libnvidia-encode.so' + ["450.51.05"]='libnvidia-encode.so' + ["450.51.06"]='libnvidia-encode.so' + ["450.56.01"]='libnvidia-encode.so' + ["450.56.02"]='libnvidia-encode.so' + ["450.56.06"]='libnvidia-encode.so' + ["450.56.11"]='libnvidia-encode.so' + ["450.57"]='libnvidia-encode.so' + ["450.66"]='libnvidia-encode.so' + ["450.80.02"]='libnvidia-encode.so' + ["450.102.04"]='libnvidia-encode.so' + ["455.22.04"]='libnvidia-encode.so' + ["455.23.04"]='libnvidia-encode.so' + ["455.23.05"]='libnvidia-encode.so' + ["455.26.01"]='libnvidia-encode.so' + ["455.26.02"]='libnvidia-encode.so' + ["455.28"]='libnvidia-encode.so' + ["455.32.00"]='libnvidia-encode.so' + ["455.38"]='libnvidia-encode.so' + ["455.45.01"]='libnvidia-encode.so' + ["455.46.01"]='libnvidia-encode.so' + ["455.46.02"]='libnvidia-encode.so' + ["455.46.04"]='libnvidia-encode.so' + ["455.50.02"]='libnvidia-encode.so' + ["455.50.04"]='libnvidia-encode.so' + ["460.27.04"]='libnvidia-encode.so' + ["460.32.03"]='libnvidia-encode.so' + ["460.39"]='libnvidia-encode.so' +) + +check_version_supported () { + local ver="$1" + [[ "${patch_list[$ver]+isset}" && "${object_list[$ver]+isset}" ]] +} + +get_supported_versions () { + for drv in "${!patch_list[@]}"; do + [[ "${object_list[$drv]+isset}" ]] && echo "$drv" + done | sort -t. -n + return 0 +} + +patch_common () { + NVIDIA_SMI="$(command -v nvidia-smi || true)" + if [[ ! "$NVIDIA_SMI" ]] ; then + echo 'nvidia-smi utility not found. Probably driver is not installed.' + exit 1 + fi + + if [[ "$manual_driver_version" ]]; then + driver_version="$manual_driver_version" + + echo "Using manually entered nvidia driver version: $driver_version" + else + cmd="$NVIDIA_SMI --query-gpu=driver_version --format=csv,noheader,nounits" + driver_versions_list=$($cmd) || ( + ret_code=$? + echo "Can not detect nvidia driver version." + echo "CMD: \"$cmd\"" + echo "Result: \"$driver_versions_list\"" + echo "nvidia-smi retcode: $ret_code" + exit 1 + ) + driver_version=$(echo "$driver_versions_list" | head -n 1) + + echo "Detected nvidia driver version: $driver_version" + fi + + if ! check_version_supported "$driver_version" ; then + echo "Patch for this ($driver_version) nvidia driver not found." + echo "Patch is available for versions: " + get_supported_versions + exit 1 + fi + + patch="${patch_list[$driver_version]}" + object="${object_list[$driver_version]}" + + declare -a driver_locations=( + '/usr/lib/x86_64-linux-gnu' + '/usr/lib/x86_64-linux-gnu/nvidia/current/' + '/usr/lib64' + "/usr/lib/nvidia-${driver_version%%.*}" + ) + + dir_found='' + for driver_dir in "${driver_locations[@]}" ; do + if [[ -e "$driver_dir/$object.$driver_version" ]]; then + dir_found='true' + break + fi + done + + [[ "$dir_found" ]] || { echo "ERROR: cannot detect driver directory"; exit 1; } + +} + +rollback () { + patch_common + if [[ -f "$backup_path/$object.$driver_version" ]]; then + cp -p "$backup_path/$object.$driver_version" \ + "$driver_dir/$object.$driver_version" + echo "Restore from backup $object.$driver_version" + else + echo "Backup not found. Try to patch first." + exit 1 + fi +} + +patch () { + patch_common + if [[ -f "$backup_path/$object.$driver_version" ]]; then + bkp_hash="$(sha1sum "$backup_path/$object.$driver_version" | cut -f1 -d\ )" + drv_hash="$(sha1sum "$driver_dir/$object.$driver_version" | cut -f1 -d\ )" + if [[ "$bkp_hash" != "$drv_hash" ]] ; then + echo "Backup exists and driver file differ from backup. Skipping patch." + return 0 + fi + else + echo "Attention! Backup not found. Copying current $object to backup." + mkdir -p "$backup_path" + cp -p "$driver_dir/$object.$driver_version" \ + "$backup_path/$object.$driver_version" + fi + sha1sum "$backup_path/$object.$driver_version" + sed "$patch" "$backup_path/$object.$driver_version" > \ + "${PATCH_OUTPUT_DIR-$driver_dir}/$object.$driver_version" + sha1sum "${PATCH_OUTPUT_DIR-$driver_dir}/$object.$driver_version" + ldconfig + echo "Patched!" +} + +query_version_support () { + if check_version_supported "$checked_version" ; then + echo "SUPPORTED" + exit 0 + else + echo "NOT SUPPORTED" + exit 1 + fi +} + +list_supported_versions () { + get_supported_versions +} + +case "${opmode}" in + patch) patch ;; + patchrollback) rollback ;; + patchhelp) print_usage ; exit 2 ;; + patchcheckversion) query_version_support ;; + patchlistversions) list_supported_versions ;; + *) echo "Incorrect combination of flags. Use option -h to get help." + exit 2 ;; +esac diff --git a/players/dash.html b/players/dash.html new file mode 100644 index 0000000..12b8df7 --- /dev/null +++ b/players/dash.html @@ -0,0 +1,23 @@ + + + + + DASH Live Streaming + + + + +

DASH Player

+ + + + + + + diff --git a/players/hls.html b/players/hls.html new file mode 100644 index 0000000..15d95b4 --- /dev/null +++ b/players/hls.html @@ -0,0 +1,23 @@ + + + + + HLS Live Streaming + + + + +

HLS Player

+ + + + + + + diff --git a/players/hls_hlsjs.html b/players/hls_hlsjs.html new file mode 100644 index 0000000..0237e7a --- /dev/null +++ b/players/hls_hlsjs.html @@ -0,0 +1,41 @@ + + + + + HLS streaming + + + + + + + + + + +

HLS Player (using hls.js)

+ +
+
+ +
+
+ + + + + + + diff --git a/players/rtmp.html b/players/rtmp.html new file mode 100644 index 0000000..d8ce856 --- /dev/null +++ b/players/rtmp.html @@ -0,0 +1,24 @@ + + + + + RTMP Live Streaming + Live Streaming + + + + + + + +

RTMP Player

+ + + + + diff --git a/players/rtmp_hls.html b/players/rtmp_hls.html new file mode 100644 index 0000000..35617e9 --- /dev/null +++ b/players/rtmp_hls.html @@ -0,0 +1,30 @@ + + + + + Live Streaming + + + + + + + + +

RTMP Player

+ + +

HLS Player

+ + + + +