user www-data; worker_processes 1; error_log logs/error.log debug; events { worker_connections 1024; } rtmp { server { listen 1935; ping 5m; ping_timeout 4m; ### Use case option (max_streams; default is 32 ) #max_streams 10; allow play all; #creates our "live" full-resolution HLS videostream from our incoming encoder stream and tells where to put the HLS video manifest and video fragments application live { allow play all; live on; hls on; hls_nested on; hls_path /HLS/live; hls_playlist_length 60m; hls_fragment 6s; drop_idle_publisher 30s; sync 500ms; hls_keys on; hls_fragments_per_key 100; #Experimental. Force dropped stream, or ended stream from being watched. (idle_streams) #idle_streams off; on_publish http://localhost/AVideo/plugin/Live/on_publish.php; on_publish_done http://localhost/AVideo/plugin/Live/on_publish_done.php; on_play http://localhost/AVideo/plugin/Live/on_play.php; on_record_done http://localhost/AVideo/plugin/Live/on_record_done.php; #exec ffmpeg -re -i rtmp://localhost/live/$name # -c:v libx264 -preset ultrafast -profile:v baseline -level 3.0 -vf scale=-2:240 -r 30 -g 120 -keyint_min 120 -crf 29 -maxrate 300k -bufsize 600k -c:a aac -b:a 64k -ar 32000 -ac 1 -f flv rtmp://localhost/adaptive/$name_low # -c:v libx264 -preset ultrafast -profile:v baseline -level 3.0 -vf scale=-2:480 -r 30 -g 120 -keyint_min 120 -crf 27 -maxrate 900k -bufsize 1800k -c:a aac -b:a 96k -ar 32000 -ac 1 -f flv rtmp://localhost/adaptive/$name_mid # -c:v libx264 -preset ultrafast -profile:v baseline -level 3.0 -vf scale=-2:720 -r 30 -g 120 -keyint_min 120 -crf 23 -maxrate 2000k -bufsize 4000k -c:a aac -b:a 128k -ar 32000 -ac 2 -f flv rtmp://localhost/adaptive/$name_hi; #exec ffmpeg -re -analyzeduration 10M -probesize 10M -i rtmp://localhost/live/$name # -thread_queue_size 512 -filter_complex "[0:v]split=3[v1][v2][v3];[v1]scale=-2:480[v480];[v2]scale=-2:720[v720];[v3]scale=-2:1080[v1080]" # -map "[v480]" -map 0:a:0? -c:v libx264 -preset ultrafast -profile:v baseline -level 3.0 -r 30 -g 120 -keyint_min 120 -crf 27 -maxrate 900k -bufsize 1800k -c:a aac -b:a 96k -ar 32000 -ac 1 -f flv rtmp://localhost/adaptive/${name}_low # -map "[v720]" -map 0:a:0? -c:v libx264 -preset ultrafast -profile:v baseline -level 3.0 -r 30 -g 120 -keyint_min 120 -crf 23 -maxrate 2000k -bufsize 4000k -c:a aac -b:a 128k -ar 32000 -ac 2 -f flv rtmp://localhost/adaptive/${name}_mid # -map "[v1080]" -map 0:a:0? -c:v libx264 -preset ultrafast -profile:v baseline -level 3.0 -r 30 -g 120 -keyint_min 120 -crf 20 -maxrate 4500k -bufsize 9000k -c:a aac -b:a 160k -ar 48000 -ac 2 -f flv rtmp://localhost/adaptive/${name}_hi 2>>/var/www/tmp/ffmpeg_nginx.log; # this is required for the audio toggle button to work exec ffmpeg -i rtmp://localhost/live/$name -vn -c:a aac -b:a 64k -ar 44100 -ac 2 -f flv rtmp://localhost/audio/${name}; #recorder video { # record all manual; # record_path /var/www/tmp; # record_notify on; # record_max_size 20480M; # record_suffix -%d-%b-%y-%T.flv; #} ### Record Audio Separately ( For podcast ) #recorder audio { # record audio; # record_path /var/www/tmp; # record_max_size 1024M; # record_suffix -%d-%b-%y-%T.mp3; #} } #application adaptive { # live on; # hls on; # hls_path /HLS/live; # hls_nested on; # hls_playlist_length 60m; # hls_fragment 6s; # allow play all; # allow publish 127.0.0.1; # deny publish all; # hls_keys on; # hls_fragments_per_key 20; # hls_variant _low BANDWIDTH=800000; # hls_variant _mid BANDWIDTH=1500000; # hls_variant _hi BANDWIDTH=2500000; # hls_variant _hi BANDWIDTH=4000000; # for 1080p #} # this is required for the audio toggle button to work application audio { live on; hls on; hls_path /HLS/audio; hls_nested on; hls_playlist_length 60m; hls_fragment 4s; allow play all; allow publish 127.0.0.1; deny publish all; hls_variant _audio BANDWIDTH=64000 CODECS="mp4a.40.2"; } } } http { include mime.types; default_type application/octet-stream; server { #listen 8443 ssl; #listen [::]:8443 ssl; #include /usr/local/nginx/snippets/self-signed.conf; #include /usr/local/nginx/snippets/ssl-params.conf; listen 8080; server_name localhost; #creates the http-location for our full-resolution (desktop) HLS stream - "http://my-ip/live/my-stream-key/index.m3u8" location /live { root /HLS; # Use root instead of alias location ~ \.m3u8$ { expires -1; # Disable cache add_header 'Cache-Control' 'no-cache'; # CORS setup add_header 'Access-Control-Allow-Origin' '*' always; add_header 'Access-Control-Expose-Headers' 'Content-Length'; } location ~ \.ts$ { # Sem cache para live add_header 'Cache-Control' 'no-cache'; add_header 'Access-Control-Allow-Origin' '*' always; add_header 'Access-Control-Expose-Headers' 'Content-Length'; add_header 'Content-Type' 'video/mp2t'; } location ~ \.key$ { # Call an external authorization service auth_request /auth_key_check; # Only serve the key if the authorization service returns 200 add_header 'Content-Type' 'application/octet-stream'; # Disable cache add_header 'Cache-Control' 'no-cache'; # CORS setup add_header 'Access-Control-Allow-Origin' '*' always; add_header 'Access-Control-Expose-Headers' 'Content-Length'; } # 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; } types { application/vnd.apple.mpegurl m3u8; video/mp2t ts; } } location /audio { root /HLS; location ~ \.m3u8$ { expires -1; add_header 'Cache-Control' 'no-cache'; add_header 'Access-Control-Allow-Origin' '*' always; add_header 'Access-Control-Expose-Headers' 'Content-Length'; } location ~ \.ts$ { add_header 'Access-Control-Allow-Origin' '*' always; add_header 'Cache-Control' 'no-cache'; add_header 'Content-Type' 'video/mp2t'; add_header 'Access-Control-Expose-Headers' 'Content-Length'; } # CORS setup geral add_header 'Access-Control-Allow-Origin' '*' always; add_header 'Access-Control-Expose-Headers' 'Content-Length'; # 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; } types { application/vnd.apple.mpegurl m3u8; video/MP2T ts; } } # Authorization endpoint location = /auth_key_check { internal; # Make this location internal so it cannot be accessed directly proxy_pass http://localhost/AVideo/plugin/Live/authorizeKeyAccess.php; proxy_pass_request_body off; # Do not send the client request body to the auth service proxy_set_header Content-Length ""; # Set headers to pass information to the PHP script proxy_set_header X-Original-URI $request_uri; # Pass the original request URI proxy_set_header X-Forwarded-For $remote_addr; # Pass the client IP address proxy_set_header User-Agent $http_user_agent; # Pass the client User-Agent } #allows us to see how stats on viewers on our Nginx site using a URL like: "http://my-ip/stats" #location /stats { # stub_status; #} location /stat { rtmp_stat all; rtmp_stat_stylesheet stat.xsl; } location /stat.xsl { root html; } location /control { # replace this with the IP of your AVideo site allow 127.0.0.1; deny all; rtmp_control all; } #allows us to host some webpages which can show our videos: "http://my-ip/my-page.html" location / { root html; index index.html index.htm; } #location ~ \.php$ { # include /etc/nginx/snippets/fastcgi-php.conf; # fastcgi_pass unix:/var/run/php/php7.2-fpm.sock; #} } }