Streaming server & FFMPEG transcoding stream & camera streaming

Environmental preparation

  1. After downloading FFMPEG, configure the environment variables. Verification command: ffmpeg -version
  2. Download ngxin-gryphon, then download nginx-rpst-module-master, move the directory to the ngxin-gryphon directory, rename it to nginx-rtmp-module, and finally configure the file nginx-win.conf (the configuration is placed below)
  3. vlc player: used to play network stream or push stream.
  4. EasyDarwin: Download and open the exe. Used to open the local rtsp port.

configuration file

nginx-win.conf


#user  nobody;
# multiple workers works !
worker_processes  2;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  8192;
    # max value 32768, nginx recycling connections+registry optimization = 
    #   this.value * 20 = max concurrent connections currently tested with one worker
    #   C1000K should be possible depending there is enough ram/cpu power
    # multi_accept on;
}

rtmp {
    server {
        listen 1935;
        chunk_size 4096;
        application live { #rtmp地址
             live on;
        }
		application hls { #如果是rtmp流这个可以不要
		     live on; 
		     # 开启hls切片
             hls on;
             # m3u8地址
			 hls_path html/hls;
			 # 一个切片多少秒
			 hls_fragment 8s;
			 # on_play http://localhost:8081/auth; #权限钩子,该自定义接口返回true才推流
			 # on_publish http://localhost:8081/auth;  #权限钩子,该自定义接口返回true才推流
			 # on_done http://localhost:8081/auth;  #权限钩子,该自定义接口返回true才推流
        }
    }
}

http {
    #include      /nginx/conf/naxsi_core.rules;
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr:$remote_port - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

#     # loadbalancing PHP
#     upstream myLoadBalancer {
#         server 127.0.0.1:9001 weight=1 fail_timeout=5;
#         server 127.0.0.1:9002 weight=1 fail_timeout=5;
#         server 127.0.0.1:9003 weight=1 fail_timeout=5;
#         server 127.0.0.1:9004 weight=1 fail_timeout=5;
#         server 127.0.0.1:9005 weight=1 fail_timeout=5;
#         server 127.0.0.1:9006 weight=1 fail_timeout=5;
#         server 127.0.0.1:9007 weight=1 fail_timeout=5;
#         server 127.0.0.1:9008 weight=1 fail_timeout=5;
#         server 127.0.0.1:9009 weight=1 fail_timeout=5;
#         server 127.0.0.1:9010 weight=1 fail_timeout=5;
#         least_conn;
#     }

    sendfile        off;
    #tcp_nopush     on;

    server_names_hash_bucket_size 128;

## Start: Timeouts ##
    client_body_timeout   10;
    client_header_timeout 10;
    keepalive_timeout     30;
    send_timeout          10;
    keepalive_requests    10;
## End: Timeouts ##

    #gzip  on;

	# 配置流媒体
    server {
        listen       2025;
        server_name  localhost;

		location /stat {
            rtmp_stat all;
            rtmp_stat_stylesheet stat.xsl;
        }
        location /stat.xsl {
            root nginx-rtmp-module/;
        }
        location /control {
            rtmp_control all;
        }
		location /hls { #如果是rtmp流,这个配置可以不要
            # Serve HLS fragments
            types {
                application/vnd.apple.mpegurl m3u8;
                video/mp2t ts;
            }
            expires -1;
            add_header Access-Control-Allow-Origin *;
        }
        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        ## Caching Static Files, put before first location
        #location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
        #    expires 14d;
        #    add_header Vary Accept-Encoding;
        #}

# For Naxsi remove the single # line for learn mode, or the ## lines for full WAF mode
        location / {
            #include    /nginx/conf/mysite.rules; # see also http block naxsi include line
            ##SecRulesEnabled;
        	  ##DeniedUrl "/RequestDenied";
	          ##CheckRule "$SQL >= 8" BLOCK;
	          ##CheckRule "$RFI >= 8" BLOCK;
	          ##CheckRule "$TRAVERSAL >= 4" BLOCK;
	          ##CheckRule "$XSS >= 8" BLOCK;
            root   html;
            index  index.html index.htm;
        }

# For Naxsi remove the ## lines for full WAF mode, redirect location block used by naxsi
        ##location /RequestDenied {
        ##    return 412;
        ##}

## Lua examples !
#         location /robots.txt {
#           rewrite_by_lua '
#             if ngx.var.http_host ~= "localhost" then
#               return ngx.exec("/robots_disallow.txt");
#             end
#           ';
#         }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000; # single backend process
        #    fastcgi_pass   myLoadBalancer; # or multiple, see example above
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}


    # HTTPS server
    #
    #server {
    #    listen       443 ssl spdy;
    #    server_name  localhost;

    #    ssl                  on;
    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_timeout  5m;

    #    ssl_prefer_server_ciphers On;
    #    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    #    ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:ECDH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!eNULL:!MD5:!DSS:!EXP:!ADH:!LOW:!MEDIUM;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

}

Start and stop nginx

Start nginx.exe -c conf/nginx-win.conf
Close nginx -s stop -c conf/nginx-win.conf

push stream, pull stream, play

Those who have a camera can obtain the rtsp stream of the camera according to the operating address of the camera. For example, the format of the Dahua camera is:

rtsp://username:password@camera IP:554/cam/realmonitor?channel=1&subtype=0

If there is no stream, we can use ffmpeg to push the local video into an rtsp stream, imitating the stream of the camera for testing.

push stream

For FFMPEG streaming, you need to download an EasyDarwin software and open the local port 554, otherwise the streaming will fail.
After starting EasyDarwin, open cmd and execute the command:

ffmpeg -re -i ./333.mp4 -vcodec libx264 -acodec aac -f rtsp rtsp://localhost:554/aaa

Push the local 333.MP4 video to the local port 554 to generate rtsp stream. We get the stream address:

rtsp://localhost:554/aaa
If it is a camera, power it on directly, and obtain the stream address of the camera according to the format of the camera. Dahua camera obtains the stream as follows: rtsp://username:
password@cameraIP:554/cam/realmonitor ?channel=1&subtype=0

FFMPEG partial commands

-re original frame rate
-vcodec video encoding
-acodec audio encoding
-f flv as flv container
-ac audio channel
-ar audio sampling rate
-strict-2 experimental parameters, with acc encoding, the default installed ffmpeg has aac encoding, so you don’t need to use it Install other audio encoding libraries
-s: scale resolution
-preset:v encoding quality ultrafast, superfast, veryfast, faster, fast, medium, slow, slower, veryslow
-analyzeduration 1000000 analysis time
-tune:v zerolatency zero-latency encoding, Unstable picture, easy to interrupt
-sc_threshold 499 Scene change monitoring, the higher the value, the smoother the picture
-fflags nobuffer Do not buffer

Transfer (here introduces rtmp and http format)

RTMP:

After the stream is pushed, you can use the vlc tool to test whether the stream can be played. Vlc can play streams in rtsp and rtmp formats (there are playback tutorials on the Internet, which are omitted here).
If the stream can be played normally, it means that the stream can be obtained. In the next step, to convert the rtsp stream into an rtmp stream, execute the ffmpeg command to convert the rtsp stream into an rtmp stream.
Soft conversion: use cpu to transcode, rely on cpu and memory, consume a lot of resources, and the consumption rate is almost 80%.

ffmpeg -re -rtsp_transport tcp -i
"rtsp://username:password@camera IP:554/cam/realmonitor?channel=1&subtype=0"
-fflags nobuffer -sc_threshold 499 -tune:v zerolatency -vcodec libx264 -vprofile baseline -acodec aac -ar 44100 -strict -2 -ac 1 -f flv -s 2304x1296 -q 10 "rtmp://localhost:1935/live/dahua"

Hard conversion: Use GPU to transcode, use the processor of the graphics card, the cpu and memory will be greatly reduced, and the consumption will be about 10%

ffmpeg -re -rtsp_transport tcp -i
“rtsp://username:password@camera IP:554/cam/realmonitor?channel=1&subtype=0” -codec:
v h264_qsv -vprofile baseline -acodec aac -ar 8000 -strict - 2 -ac 1 -f flv -s 1280x720 -q 10 “rtmp://localhost:1935/live/dahua”

Among them, dahua is a custom name, and the stream will be transferred to the live service of port 1935 of ngxin streaming media.
At this time, we can use the vlc or ffmpeg command to play this stream. If the playback is successful, the front end can call this address to play (the front end page needs to have a flash plug-in environment to play rtmp).

ffplay “rtmp://localhost:1935/live/dahua live=1”

http

The stream using http mode no longer needs ngxin_gryphon, and another http-related ngxin streaming media nginx-flv is needed. You can download the nginx-flv-file-master package from the Internet, and then start the ngxin.
nginx.conf:

#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    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  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    server {
        listen       2025;
        
        location /live {
            flv_live on;
            chunked_transfer_encoding on;
			add_header 'Access-Control-Allow-Credentials' 'true'; #add additional HTTP header
			add_header 'Access-Control-Allow-Origin' '*'; #add additional HTTP header
			add_header Access-Control-Allow-Headers X-Requested-With;
			add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
			add_header 'Cache-Control' 'no-cache';
        }

        location /hls {      
		   add_header Access-Control-Allow-Origin *;
           types{    
             application/vnd.apple.mpegurl m3u8;    
             video/mp2t ts;    
           }    
			alias /test;    
			expires -1;    
        }
        
        location /stat {
            rtmp_stat all;
            rtmp_stat_stylesheet stat.xsl;
        }

        location /stat.xsl {
            root html/nginx-http-flv-module/;
        }

        location /control {
            rtmp_control all;
        }

        location /rtmp-publisher {
            root html/nginx-http-flv-module/test;
        }
        
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root html/nginx-http-flv-module/test/www;
            index  index.html index.htm;
        }
		
		 location  ~ .*\.(gif|jpg|jpeg|png|js|css)$ {
		 root html/nginx-http-flv-module/test/www/;
		 }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}


    # HTTPS server
    #
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;

    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

}

rtmp {  
    server {  
        listen 1935;  
        chunk_size 8000;  
        application liveapp { 
            live on;
			# on_publish http://localhost:8081/auth;
			# on_publish_done http://localhost:8081/auth;
        }  
    }  
}

After startup, similar to the rtmp streaming steps above, just execute the transfer command:
soft transfer:

ffmpeg -re -rtsp_transport tcp -i
"rtsp://username:password@camera IP:554/cam/realmonitor?channel=1&subtype=0"
-fflags nobuffer -sc_threshold 499 -tune:v zerolatency -vcodec libx264 -vprofile baseline -acodec aac -ar 44100 -strict -2 -ac 1 -f flv -s 2304x1296 -q 10 "rtmp://localhost:1935/liveapp/dahua"

hard turn:

ffmpeg -re -rtsp_transport tcp -i
“rtsp://username:password@camera IP:554/cam/realmonitor?channel=1&subtype=0” -codec:
v h264_qsv -vprofile baseline -acodec aac -ar 8000 -strict - 2 -ac 1 -f flv -s 1280x720 -q 10 “rtmp://localhost:1935/liveapp/dahua”

After the transfer, you can get the stream in http form through the proxy configuration of nginx, such as:

http://localhost:2025/live?port=1935&app=liveapp&stream=dahua

Supplement: The configuration -codec:v h264_qsv in the hard transfer method is to specify the model of the graphics card. If it is an inter type graphics card, it is qsv. amd and Nvidia are the other two formats, you can find them online.

Summarize

Building streaming media by yourself requires high configuration, otherwise it will consume resources, and the specific situation needs to be analyzed in detail. It is not sure how much resources are needed, and it is not specialized in audio and video. It can only be done with existing tools. Nowadays, many browsers do not support flash, so rtmp is still not convenient enough. It is more convenient to use the html playback tag to play in http format. After my machine is configured, the delay is about 3s. If the ffmpeg command does not have the above parameter optimization, the delay is 5-9 seconds. The above -fflags nobuffer -sc_threshold 499 -tune:v zerolatency are all used to reduce the delay. But it seems to be limited to the form of soft transfer, hard transfer does not need these parameters, and the delay is similar.
It is easy to disconnect when using vlc software to push the stream. My machine will be disconnected after about ten seconds. I don’t know why. At first I always thought that there was a problem with the ffmpeg push command. Later, I found out that the vlc push stream was easy to break, which caused ffmpeg to turn off. It will be cut off when streaming, so I use the ffmpeg command to push the stream here, which is more reliable.

Guess you like

Origin blog.csdn.net/qq_42878634/article/details/128495559