Why HLS streaming take so much CPU? - nginx

I tring to restream webcams using nginx+rtmp module on Debian machine. When i restream one cam it's works nice and smooth, but its take so much CPU:
Here is my config:
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 1024;
}
rtmp_auto_push on;
rtmp {
live on;
hls on;
hls_fragment 5s;
respawn_timeout 15s;
chunk_size 8192;
server {
listen 1935;
application cam1 {
hls_path /tmp/cam1;
}
exec_static /usr/bin/ffmpeg -i http://cam-ip:8080/flv?login=user&channelid=channalid&password=pass&count=0
-acodec copy -vcodec libx264 -vprofile baseline -f flv rtmp://server-ip/cam1/stream;
}
}
http {
server {
listen 8080;
location /stat {
rtmp_stat all;
rtmp_stat_stylesheet stat.xsl;
}
location stat.xsl {
root /stat;
}
location / {
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
root /tmp/;
add_header Cache-Control no-cache;
add_header Access-Control-Allow-Origin *;
add_header 'Access-Control-Expose-Headers' 'Content-Length';
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;
}
}
}
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
gzip on;
gzip_disable "msie6";
include /etc/nginx/conf.d/*.conf;
}
After i add 12 webcams in config and i got terrible lags when look at cam. And 100% CPU usage:
Why i have so much ffmpeg processes in htop?
And why it's take so much CPU?

Related

Nginx-Rtmp not able to set latency

I'm using nginx-rtmp module to capture RTMP streams from my cameras and transmit them to further systems.
Generally my setup is working fine and generating .m3u8 files properly. For example:
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:23
#EXT-X-TARGETDURATION:50
#EXT-X-DISCONTINUITY
#EXTINF:49.957,
verification-23.ts
But the fragments that are generated are always 50s as you can see on the above example.
This is causing more than 50s delay in playback that I would like to avoid.
I tried to decrease Nginx parameters to, for example 3s for fragment and 15s for playlist:
hls_fragment 3s;
hls_playlist_length 15s;
but it didn't work. .m3u8 files were still generated with #EXTINF:49.957.
Is it possible to decrease the delay with Nginx configuration? Or it might be some kind of additional configuration on the cameras?
My current nginx.conf file:
user www-data;
worker_processes auto;
pid /run/nginx.pid;
events {
worker_connections 768;
}
rtmp {
server {
listen 1935;
chunk_size 2000;
application live {
live on;
hls on;
hls_path /tmp/hls;
hls_fragment 50s;
hls_playlist_length 60s;
deny play all;
}
}
}
http {
sendfile off;
tcp_nopush on;
directio 512;
default_type application/octet-stream;
server {
server_name stream.mydomain.pl;
location / {
# 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';
# 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/dash+xml mpd;
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
root /tmp;
}
# Certbot configuration
# ...
}

NGINX-RTMP-MODULE: [error] hls: force fragment split

I am trying to transcode incoming live RTMP stream to HLS stream using nginx-rtmp-module.
The HLS streaming works fine for few seconds and then it starts throwing the following error:
2020/08/22 00:14:18 [error] 10#10: *3 hls: force fragment split: 10.027 sec, , client: 127.0.0.1, server: 0.0.0.0:1935
This is my nginx configuration file.
daemon off;
error_log /dev/stdout info;
events {
worker_connections 1024;
}
rtmp {
server {
listen ${RTMP_PORT};
chunk_size 4000;
application stream {
live on;
exec ffmpeg -i rtmp://localhost:1935/stream/$name -v verbose
-c:a libfdk_aac -b:a 128k -c:v libx264 -b:v 2500k -f flv -g 150 -r 30 -s 1280x720 -preset superfast -profile:v baseline rtmp://localhost:1935/hls/$name_720p2628kbs;
}
application hls {
live on;
hls on;
hls_fragment_naming sequential;
hls_fragment 5s;
hls_max_fragment 10s;
hls_playlist_length 20s;
hls_path /opt/data/hls;
hls_nested on;
hls_variant _720p2628kbs BANDWIDTH=2628000,RESOLUTION=1280x720;
}
}
}
http {
access_log /dev/stdout combined;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
server {
listen ${HTTP_PORT};
location /hls {
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
root /opt/data;
add_header Cache-Control no-cache;
add_header Access-Control-Allow-Origin *;
}
location /live {
alias /opt/data/hls;
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
add_header Cache-Control no-cache;
add_header Access-Control-Allow-Origin *;
}
location /stat {
rtmp_stat all;
rtmp_stat_stylesheet static/stat.xsl;
}
location /static {
alias /www/static;
}
location = /crossdomain.xml {
root /www/static;
default_type text/xml;
expires 24h;
}
}
}
Can someone please help me with this issue?

nginx streaming server serving stream that causes VLC to reload in a loop

I explained the problem in this Video Stack Exchange Question as I don't believe this is something code related (e.g. a bug).
It may be a useful information for dev's however, that I did not compile nginx from source. I mention that explicitly, because searching the web, it seems like building from source is the recommended way for nginx/rtmp setups. I could not find a bug report, however, that would explain this behavior.
I feel like I am overseeing something stupid.
For the sake of completeness, I will post the configuration files. Also, dont miss out the live-demo and have fun playing around with the streaming server linked in the other Post ;)
Happy Coding!
nginx.conf:
events {
worker_connections 768;
# multi_accept on;
}
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# SSL Settings
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
##
# Gzip Settings
##
gzip on;
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
rtmp {
include /etc/nginx/streams-enabled/*;
}
rtmp server (in streams-enabled/)
server {
listen 1935;
chunk_size 4096;
application live {
live on;
hls on;
hls_path /home/streamer/hls;
hls_nested on;
hls_fragment 3s;
hls_playlist_length 30s;
hls_base_url http://0.0.0.0:3456/hls;
on_publish http://0.0.0.0:3456/auth;
# Recent versions of IE need this for normal playback.
wait_video on; # start audio with video
# force hls
deny play all;
}
}
http-server (in sites-enabled/)
server {
listen 3456;
location /hls {
add_header Cache-Control no-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;
}
types {
application/dash+xml mpd;
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
root /home/streamer/;
}
}
The problem is with the stream configuration.
vlc -vv http://104.248.36.47:3644/hls/debug/index.m3u8 ouput revealed:
[00007f0594002580] main stream debug: connecting to 0.0.0.0 port 3644 ...
[00007f0594002580] main stream error: connection error: Connection refused
...
[00007f0594002580] adaptive stream debug: Retrieving http://0.0.0.0:3644/hlsdebug/75.ts #0
Note that it says hlsdebug instead of the expected hls/debug
After adding a '/' to the hls_base_url, and changing 0.0.0.0 to the public IP, it works.
I do not understand fully tho why 0.0.0.0 would not work..

Nginx RTMP module output HLS not found

I set up Nginx for live stream edge server which pull RTMP from origin server. For my case RTMP is work fine but hls return not found.
I pull rtmp like dynamic stream based on origin for example "pull rtmp://ORIGIN_IP:1935/appname" and I can play "rtmp://EDGE_IP:1935/stream/origin_streamname" but I can't play "http://EDGE_IP:8080/stream/origin_streamname.m3u8" always return "not found" port 8080 opened.
below is nginx.conf
worker_processes auto;
error_log /var/log/nginx/error.log warn;
events {
worker_connections 1024;
}
# RTMP configuration
rtmp {
server {
listen 1935;
chunk_size 4000;
application show {
live on;
hls on;
hls_path /mnt/hls/;
hls_fragment 3;
hls_playlist_length 60;
deny play all;
}
application vod {
play /mnt/mp4s;
}
application stream {
live on;
pull rtmp://ORIGIN_IP:1935/appname;
}
}
}
http {
sendfile off;
tcp_nopush on;
aio on;
directio 512;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
server {
listen 8080;
server_name 127.0.0.1;
location /nginx_status {
stub_status on;
allow 127.0.0.1;
deny all;
}
location / {
add_header 'Cache-Control' 'no-cache';
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Expose-Headers' 'Content-Length';
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/dash+xml mpd;
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
root /mnt/;
}
}
}
I solved it by adding
hls on;
hls_path /mnt/hls/;
hls_fragment 3;
hls_playlist_length 60;
then you need to play rtmp://EDGE_IP:1935/stream/origin_streamname and http://EDGE_IP:8080/hls/origin_streamname.m3u8 at the same time.

NGINX suddenty stops proxying requests

I have an NGINX server set up to serve static content. Moreover, this NGINX proxies requests coming from bots to a pre-rendering service. Suddenly, and for no apparent reason at all, NGINX stops redirecting these requests to the service. Instead, NGINX keeps on responding with 504 timeouts. I do not understand why it happens abruptly (instead of regularly), and the reasons behind it. I analyzed the request logs, and could not find a pattern.
I have NGINX v1.10.3 running on Ubuntu 16.04 machine.
Below is the configuration files for NGINX:
nginx.conf:
events {
worker_connections 768;
# multi_accept on;
}
http {
##
# Basic Settings
##
client_max_body_size 20M;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
proxy_connect_timeout 10s;
proxy_send_timeout 10s;
proxy_read_timeout 10s;
send_timeout 10s;
keepalive_timeout 65;
types_hash_max_size 2048;
# server_tokens off;
real_ip_header X-Forwarded-For;
set_real_ip_from 10.0.0.0/8;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# SSL Settings
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
##
# Logging Settings
##
log_format main '"$time_local" client=$remote_addr '
'method=$request_method request="$request" '
'request_length=$request_length '
'status=$status bytes_sent=$bytes_sent '
'body_bytes_sent=$body_bytes_sent '
'referer=$http_referer '
'user_agent="$http_user_agent" '
'upstream_addr=$upstream_addr '
'upstream_status=$upstream_status '
'request_time=$request_time '
'upstream_response_time=$upstream_response_time '
'upstream_connect_time=$upstream_connect_time '
'upstream_header_time=$upstream_header_time';
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
gzip on;
gzip_disable "msie6";
# gzip_vary on;
# gzip_proxied any;
# gzip_comp_level 6;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
virtual server:
server {
listen 443 ssl http2;
server_name serverName.com;
ssl on;
ssl_certificate <crtLocation>;
ssl_certificate_key <keyLocation>;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
add_header 'Access-Control-Allow-Origin' "$http_origin" always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Requested-With' always;
client_body_timeout 7s;
client_header_timeout 7s;
location / {
set $prerender 0;
if ($http_user_agent ~* "Google|Googlebot|Googlebot\-News|Googlebot\-Image|Googlebot\-Video|Mediapartners\-Google|AdsBot\-Google|Bingbot|MSNBot|MSNBot\-Media|AdIdxBot|BingPreview|Slurp|DuckDuckBot|Baiduspider|Baiduspider|Baiduspider|Yandexbot|facebookexternalhit|FacebookExternalHit|Facebot|Twitterbot|LinkedInBot|rogerbot|DotBot|MJ12bot|AhrefsBot|ia\_archiver|embedly|quora\ link\ preview|showyoubot|outbrain|pinterest|slackbot|vkShare|W3C_Validator"){
set $prerender 1;
}
if ($args ~ "_escaped_fragment_") {
set $prerender 1;
}
if ($http_user_agent ~ "Prerender") {
set $prerender 0;
}
if ($uri ~* "\.(js|css|xml|less|png|jpg|jpeg|gif|pdf|doc|txt|ico|rss|zip|mp3|rar|exe|wmv|doc|avi|ppt|mpg|mpeg|tif|wav|mov|psd|ai|xls|mp4|m4a|swf|dat|dmg|iso|flv|m4v|torrent|ttf|woff|svg|eot)"){
set $prerender 0;
}
if ($prerender = 1) {
rewrite .* /$scheme://$host$request_uri? break;
proxy_pass <proxy server>;
}
try_files $uri $uri/ /index.php;
}
location ~ .php/ { ## Forward paths like /js/index.php/x.js to relevant handler
rewrite ^(.*.php)/ $1 last;
}
location ~ \.php$ {
include fastcgi.conf;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
try_files $uri =404;
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
fastcgi_index index.php;
}
}

Resources