Server:
Linux CentOS 6.(x)
NGINX with RTMP module enabled (compiled myself using an online
tutorial)
I use FFmpeg to stream to this server, and one stream works perfectly.
Example of perfectly working stream from IP camera:
ffmpeg -loglevel verbose -rtsp_transport tcp -i rtsp://admin:admin@[ip
cam
address]:554/channel1 -c copy -f flv rtmp://[nginx
server]:1935/live/test1
and to pull the stream, I use VLC/FFplay, and rtmp url is like so:
ffplay rtmp://[nginx server]:1935/live/test1
Problem comes when I try to stream two streams simultaneously, like so:
ffmpeg -loglevel verbose -rtsp_transport tcp -i rtsp://admin:admin@[ip
cam
address]:554/channel1 -c copy -f flv rtmp://[nginx
server]:1935/live/test1
ffmpeg -loglevel verbose -rtsp_transport tcp -i rtsp://admin:admin@[ip
cam
address]:554/channel1 -c copy -f flv rtmp://[nginx
server]:1935/live/test2
in this case, both streams is mostly choppy, and sometimes one stream
fails
to load at all.
If I extend this to 10 inputs like so:
ffmpeg -loglevel verbose -rtsp_transport tcp -i rtsp://admin:admin@[ip
cam
address]:554/channel1 -c copy -f flv rtmp://[nginx
server]:1935/live/test1
ffmpeg -loglevel verbose -rtsp_transport tcp -i rtsp://admin:admin@[ip
cam
address]:554/channel1 -c copy -f flv rtmp://[nginx
server]:1935/live/test2
ffmpeg -loglevel verbose -rtsp_transport tcp -i rtsp://admin:admin@[ip
cam
address]:554/channel1 -c copy -f flv rtmp://[nginx
server]:1935/live/test3
ffmpeg -loglevel verbose -rtsp_transport tcp -i rtsp://admin:admin@[ip
cam
address]:554/channel1 -c copy -f flv rtmp://[nginx
server]:1935/live/test4
ffmpeg -loglevel verbose -rtsp_transport tcp -i rtsp://admin:admin@[ip
cam
address]:554/channel1 -c copy -f flv rtmp://[nginx
server]:1935/live/test5
ffmpeg -loglevel verbose -rtsp_transport tcp -i rtsp://admin:admin@[ip
cam
address]:554/channel1 -c copy -f flv rtmp://[nginx
server]:1935/live/test6
ffmpeg -loglevel verbose -rtsp_transport tcp -i rtsp://admin:admin@[ip
cam
address]:554/channel1 -c copy -f flv rtmp://[nginx
server]:1935/live/test7
ffmpeg -loglevel verbose -rtsp_transport tcp -i rtsp://admin:admin@[ip
cam
address]:554/channel1 -c copy -f flv rtmp://[nginx
server]:1935/live/test8
ffmpeg -loglevel verbose -rtsp_transport tcp -i rtsp://admin:admin@[ip
cam
address]:554/channel1 -c copy -f flv rtmp://[nginx
server]:1935/live/test9
ffmpeg -loglevel verbose -rtsp_transport tcp -i rtsp://admin:admin@[ip
cam
address]:554/channel1 -c copy -f flv rtmp://[nginx
server]:1935/live/test10
Then although I can see all console are streaming perfectly fine, like
so:
ffmpeg -loglevel verbose -rtsp_transport tcp -i rtsp://admin:admin@[ip
cam
address]:554/channel1 -c copy -f flv rtmp://[nginx
server]:1935/live/test10
ffmpeg version N-80801-gc0cb53c Copyright © 2000-2016 the FFmpeg
developers
built with gcc 4.4.7 (GCC) 20120313 (Red Hat 4.4.7-17)
configuration: --extra-cflags=-I/root/ffmpeg_build/include
–extra-ldflags=-L/root/ffmpeg_build/lib --pkg-config-flags=–static
–enable-gpl --enable-nonfree --enable-libfdk-aac --enable-libfreetype
–enable-libmp3lame --enable-libopus --enable-libvorbis --enable-libvpx
–enable-libx264 --enable-libx265
libavutil 55. 27.100 / 55. 27.100
libavcodec 57. 48.101 / 57. 48.101
libavformat 57. 40.101 / 57. 40.101
libavdevice 57. 0.102 / 57. 0.102
libavfilter 6. 46.102 / 6. 46.102
libswscale 4. 1.100 / 4. 1.100
libswresample 2. 1.100 / 2. 1.100
libpostproc 54. 0.100 / 54. 0.100
[rtsp @ 0x46594e0] SDP:
v=0
o=- 45356132 1 IN IP4 192.168.5.100
s=Session streamed by stream
i=1
t=0 0
a=tool:LIVE555 Streaming Media v2009.01.26
a=type:broadcast
a=control:*
a=range:npt=0-
a=x-qt-text-nam:Session streamed by stream
a=x-qt-text-inf:1
m=video 0 RTP/AVP 96
c=IN IP4 0.0.0.0
b=AS:506
a=framerate:30.00
a=rtpmap:96 H264/90000
a=fmtp:96
packetization-mode=1;profile-level-id=640028;sprop-parameter-sets=Z2QAKKzoB4
AiflQ=,aO48MA==
a=control:track1
m=audio 0 RTP/AVP 0
c=IN IP4 0.0.0.0
b=AS:64
a=control:track2
[rtsp @ 0x46594e0] setting jitter buffer size to 0
Last message repeated 1 times
Guessed Channel Layout for Input Stream #0.1 : mono
Input #0, rtsp, from ‘rtsp://admin:admin@[ip cam address]:554/channel1’:
Metadata:
title : Session streamed by stream
comment : 1
Duration: N/A, start: 0.000000, bitrate: N/A
Stream #0:0: Video: h264 (High), 1 reference frame, yuv420p,
1920x1080
(1920x1088), 30 tbr, 90k tbn, 180k tbc
Stream #0:1: Audio: pcm_mulaw, 8000 Hz, 1 channels, s16, 64 kb/s
[flv @ 0x4696240] Using AVStream.codec to pass codec parameters to
muxers is
deprecated, use AVStream.codecpar instead.
Last message repeated 1 times
Output #0, flv, to ‘rtmp://[nginx server]:1935/live/test10’:
Metadata:
title : Session streamed by stream
comment : 1
encoder : Lavf57.40.101
Stream #0:0: Video: h264, 1 reference frame ([7][0][0][0] / 0x0007),
yuv420p, 1920x1080 (0x0), q=2-31, 30 tbr, 1k tbn, 90k tbc
Stream #0:1: Audio: pcm_mulaw ([8][0][0][0] / 0x0008), 8000 Hz,
mono, 64
kb/s
Stream mapping:
Stream #0:0 -> #0:0 (copy)
Stream #0:1 -> #0:1 (copy)
Press [q] to stop, [?] for help
[flv @ 0x4696240] Timestamps are unset in a packet for stream 0. This is
deprecated and will stop working in the future. Fix your code to set the
timestamps properly
frame= 42 fps=0.0 q=-1.0 size= 56kB time=00:00:02.83 bitrate=
163.1kbits
frame= 54 fps= 46 q=-1.0 size= 62kB time=00:00:03.43 bitrate=
147.6kbits
frame= 66 fps= 39 q=-1.0 size= 77kB time=00:00:04.03 bitrate=
157.1kbits
frame= 76 fps= 34 q=-1.0 size= 83kB time=00:00:04.53 bitrate=
149.9kbits
…
But when I try to pull it using FFplay, I always get this error (Invalid
data found when processing input):
ffplay rtmp://[nginx server]:1935/live/test10
ffplay version N-80386-g5f5a97d Copyright © 2003-2016 the FFmpeg
developers
built with gcc 5.4.0 (GCC)
configuration: --enable-gpl --enable-version3 --disable-w32threads
–enable-nv
enc --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r
–enabl
e-gnutls --enable-iconv --enable-libass --enable-libbluray
–enable-libbs2b
–en
able-libcaca --enable-libfreetype --enable-libgme --enable-libgsm
–enable-libil
bc --enable-libmodplug --enable-libmfx --enable-libmp3lame
–enable-libopencore-
amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus
–enable-
librtmp --enable-libschroedinger --enable-libsnappy --enable-libsoxr
–enable-li
bspeex --enable-libtheora --enable-libtwolame --enable-libvidstab
–enable-libvo
-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack
–enable-libweb
p --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid
–enable-l
ibzimg --enable-lzma --enable-decklink --enable-zlib
libavutil 55. 24.100 / 55. 24.100
libavcodec 57. 46.100 / 57. 46.100
libavformat 57. 38.100 / 57. 38.100
libavdevice 57. 0.101 / 57. 0.101
libavfilter 6. 46.101 / 6. 46.101
libswscale 4. 1.100 / 4. 1.100
libswresample 2. 1.100 / 2. 1.100
libpostproc 54. 0.100 / 54. 0.100
RTMP_ReadPacket, failed to read RTMP packet headersq= 0B f=0/0
rtmp://64.49.234.250:1935/live/test10: Invalid data found when
processing
input
nan : 0.000 fd= 0 aq= 0KB vq= 0KB sq= 0B f=0/0
If I enabled verbose log, then this is generated at FFplay:
ffplay -loglevel verbose rtmp://[nginx server]:1935/live/test10
ffplay version N-80386-g5f5a97d Copyright © 2003-2016 the FFmpeg
developers
built with gcc 5.4.0 (GCC)
configuration: --enable-gpl --enable-version3 --disable-w32threads
–enable-nv
enc --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r
–enabl
e-gnutls --enable-iconv --enable-libass --enable-libbluray
–enable-libbs2b
–en
able-libcaca --enable-libfreetype --enable-libgme --enable-libgsm
–enable-libil
bc --enable-libmodplug --enable-libmfx --enable-libmp3lame
–enable-libopencore-
amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus
–enable-
librtmp --enable-libschroedinger --enable-libsnappy --enable-libsoxr
–enable-li
bspeex --enable-libtheora --enable-libtwolame --enable-libvidstab
–enable-libvo
-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack
–enable-libweb
p --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid
–enable-l
ibzimg --enable-lzma --enable-decklink --enable-zlib
libavutil 55. 24.100 / 55. 24.100
libavcodec 57. 46.100 / 57. 46.100
libavformat 57. 38.100 / 57. 38.100
libavdevice 57. 0.101 / 57. 0.101
libavfilter 6. 46.101 / 6. 46.101
libswscale 4. 1.100 / 4. 1.100
libswresample 2. 1.100 / 2. 1.100
libpostproc 54. 0.100 / 54. 0.100
Parsing… : 0.000 fd= 0 aq= 0KB vq= 0KB sq= 0B f=0/0
Parsed protocol: 0
Parsed host : 64.49.234.250
Parsed app : live
RTMP_Connect1, … connected, handshaking= 0KB sq= 0B f=0/0
HandShake: Type Answer : 03q= 0KB vq= 0KB sq= 0B f=0/0
HandShake: Server Uptime : 353698523
HandShake: FMS Version : 0.0.0.0
HandShake: Handshaking finished…0KB vq= 0KB sq= 0B f=0/0
RTMP_Connect1, handshaked
Invoking connect
HandleServerBW: server BW = 50000000KB vq= 0KB sq= 0B f=0/0
HandleClientBW: client BW = 5000000 2B vq= 0KB sq= 0B f=0/0
HandleChangeChunkSize, received: chunk size change to 4096
RTMP_ClientPacket, received: invoke 190 bytes
(object begin)
Property: <Name: no-name., STRING: _result>
Property: <Name: no-name., NUMBER: 1.00>
Property: <Name: no-name., OBJECT>
(object begin)
Property: <Name: fmsVer, STRING: FMS/3,0,1,123>
Property: <Name: capabilities, NUMBER: 31.00>
(object end) 0.000 fd= 0 aq= 0KB vq= 0KB sq= 0B f=0/0
Property: <Name: no-name., OBJECT>
(object begin)
Property: <Name: level, STRING: status>
Property: <Name: code, STRING:
NetConnection.Connect.Success>
Property: <Name: description, STRING: Connection succeeded.>
Property: <Name: objectEncoding, NUMBER: 0.00>
(object end)
(object end)
HandleInvoke, server invoking <_result>
HandleInvoke, received result for method call
sending ctrl. type: 0x0003
Invoking createStream
RTMP_ClientPacket, received: invoke 29 bytes 0KB sq= 0B f=0/0
(object begin)
Property: <Name: no-name., STRING: _result>
Property: <Name: no-name., NUMBER: 2.00>
Property: NULL
Property: <Name: no-name., NUMBER: 1.00>
(object end)
HandleInvoke, server invoking <_result>
HandleInvoke, received result for method call
SendPlay, seekTime=0, stopTime=0, sending play: test10
Invoking play
sending ctrl. type: 0x0003
RTMP_ClientPacket, received: invoke 96 bytes 0KB sq= 0B f=0/0
(object begin)
Property: <Name: no-name., STRING: onStatus>
Property: <Name: no-name., NUMBER: 0.00>
Property: NULL
Property: <Name: no-name., OBJECT>
(object begin)
Property: <Name: level, STRING: status>
Property: <Name: code, STRING: NetStream.Play.Start>
Property: <Name: description, STRING: Start live>
(object end)
(object end)
HandleInvoke, server invoking
HandleInvoke, onStatus: NetStream.Play.Start
RTMP_ClientPacket, received: notify 24 bytes 0KB sq= 0B f=0/0
(object begin)
Property: <Name: no-name., STRING: |RtmpSampleAccess>
Property: <Name: no-name., BOOLEAN: TRUE>
Property: <Name: no-name., BOOLEAN: TRUE>
(object end)
RTMPSockBuf_Fill, recv returned -1. GetSockError(): 10060 (Unknown
error)
RTMP_ReadPacket, failed to read RTMP packet header
Invoking deleteStreamd= 0 aq= 0KB vq= 0KB sq= 0B f=0/0
rtmp://[nginx server]:1935/live/test10: Invalid data found when
processing
input
This is my nginx.conf:
#user nobody;
worker_processes 4;
#error_log logs/error.log;
#error_log logs/error.log notice;
error_log logs/error.log info;
#error_log logs/error.log debug;
#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 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME
$document_root$fastcgi_script_name;
include fastcgi_params;
}
#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 4096;
application live {
live on;
record off;
}
application vod {
play /var/flvs;
}
}
}
Can anyone tell why multiple RTMP streams are not being entertained? Is
there any streaming restriction on nginx I am unaware of?