Hello,
I would make a simple redirect (to other server) when a user begins broadcasting.
The problem is that a "push xxx", the stream is redirected to all those push servers, when my goal is to redirect the user to a single server.
When the user start broadcast, i try to redirected with a header Location: rtmp://x.x.x.x/app/test
nginx.conf :
rtmp {
server {
listen 1935;
ping 30s;
notify_method post;
application app {
live on;
notify_update_timeout 15s;
on_publish http://x.x.x.1/publishStart;
}
}
}
The script located at http://x.x.x.1/publishStart make some stuff and end with an header Location: rtmp://x.x.x.2/app/test
The following error occur, nginx-error.log:
2015/07/04 14:17:38 [error] 27994#0: *35 notify: push 'test' to 'rtmp://x.x.x.x:1935/app/test', client: x.x.x.x, server: 0.0.0.0:1935
2015/07/04 14:17:38 [error] 27994#0: relay: no address
Any help would be appreciated
Thanks
Check location url:
Thanks for your answer.
I tried Location:rtmp://123.45.6.7/app/stream and Location:rtmp://123.45.6.7/app/stream/ but always the same result
2015/07/04 14:17:38 [error] 27994#0: *35 notify: push 'test' to 'rtmp://x.x.x.x/app/stream', client: x.x.x.x, server: 0.0.0.0:1935
2015/07/04 14:17:38 [error] 27994#0: relay: no address
What version nginx and rtmp module you running?
Can you switch rtmp log to debug level for test?
error_log /var/log/nginx/rtmp-error.log debug;
And after testing look for lines like these:
2015/07/05 20:02:40 [info] 31912#0: *1 notify: publish 'localhost/publish-redirect.php', client: x.x.x.x, server: 0.0.0.0:1935
... skip ...
2015/07/05 20:02:40 [debug] 31912#0: *1 notify: HTTP retcode: 3xx
2015/07/05 20:02:40 [debug] 31912#0: *1 notify: publish redirect received
2015/07/05 20:02:40 [error] 31912#0: *1 notify: push 'test/path' to 'rtmp://127.0.0.1/rtmp-slow', client: x.x.x.x, server: 0.0.0.0:1935
2015/07/05 20:02:40 [info] 31912#0: *1 relay: create push name='test/path' app='' playpath='' url='127.0.0.1/rtmp-slow', client: x.x.x.x, server: 0.0.0.0:1935
2015/07/05 20:02:40 [debug] 31912#0: relay: create remote context
To test rtmp redirect I wrote simple php script: publish-redirect.php
<?php
header("HTTP/1.0 302 Publish Here");
header("Location: rtmp://127.0.0.1/rtmp-slow");
No other output is generated.
And add it into application section:
application rtmp {
live on;
... skip ...
on_publish http://localhost/publish-redirect.php;
... more lines ...
}
Thank you !
I will test this tomorrow, i come back after testing :)
Update:
array (
'call' => 'publish',
'app' => 'rtmp', // only with https://github.com/arut/nginx-rtmp-module/pull/649
'name' => 'test/path',
'type' => 'live'
)
ffmpeg -f alsa -i pulse -f v4l2 -framerate 15 -video_size 640x360 -i /dev/video0 \
-c:v libx264 -threads 0 -pix_fmt yuv420p -g 20 -profile:v main -b:v 500k \
-tune zerolatency -movflags +faststart \
-c:a libfdk_aac -b:a 64k -ar 44100 -cutoff 19000 -ac 1 \
-f flv "rtmp://nginx-domain-name app=rtmp playpath=test/path live=1 timeout=0 buffer=0"
Hello, thank you again for your answer.
I'm stupid, i didn't check nginx version, i use 1.2.4....
I compile nginx 1.9.2 and try again !
THANK YOU VERY MUCH
it's been several days that I was looking to solve the problem ... A BEER 4 YOU :)
However, the behavior is not what I expected, I thought the redirect would send the stream to the new address, but the server creates a relay A to Server B, if A nginx server is stopped, the stream is interrupted.
And the notifications (publish, publish_done etc...) are triggered to server A and server B.
After going through all the documentation and probably the internet, I think it is impossible to make a real redirection with this rtmp module.
It's a shame we do not know what relay may consumes (bandwidth, processor, ram...), I imagine that with 1,000 or more users, server A is bound to be overloaded at one time or another ...
Ah, you need the nginx to send rtmp-redirect command to clients and publisher?
Not to relay incoming streams.
For now it should be done by client-side I think. Something like back-end notify handler to cometh/websocket + cometh/websocket/js command-to-flash handler on client.
sorry for my explanation, I'm French, i will try to explain more clearly.
My goal is to do some sort of load balancing : one ingest server treat new connections and find available slot on server #X, then i start ffmpeg process on many other servers who connect on the ingest server to output via HLS and other formats & treatments.
Step by step for the broadcaster :
It's like twitch.tv, but not for gamers :)
Thank you if you can help again !
The problem with
header("HTTP/1.0 302 Publish Here");
header("Location: rtmp://127.0.0.1/rtmp-slow");
Is the first nginx server continue to handle the stream after redirecting, so the stream is "duplicated" and dependent of main ingest server, if the main ingest server die, all the streams die :s
@lossius30 I wish to do the same thing, unfortunately nginx-rtmp doesn't do that as far as I know. It will only relay as you've found out. Unless I've missed something.
Yes, nginx-rtmp don't send RTMP redirect command, just pass stream through self.
If ffmpeg support such thing - may be it is possible to patch nginx-rtmp to support RTMP-redirect.
If redirecting is supported by RTMP protocol.
Update:
Adobe FMS 3 have this:
application.redirectConnection(clientObj, url[, description[, errorObj]])
Rejects a connection and provides a redirect URL. You must write logic in the
NetConnection.onStatus() handler that detects redirection and passes the new connection URL to the
NetConnection.connect() method.
And it passes data to client:
| Property | Value |
| --- | --- |
| info.code | "NetConnection.Connect.Rejected" |
| info.description | The value passed in the description parameter; if no value is passed in the parameter, the default value is "Connection failed" |
| info.ex.code | 302 |
| info.ex.redirect | The new connection URL |
| info.level | "Error" |
Now the question is how to simulate this, and will ffmpeg, FMLE and others support such thing.
And don't forget about HLS/DASH clients - they need to be redirected too.
You can try this branch of my fork: https://github.com/sergey-dryabzhinsky/nginx-rtmp-module/tree/add-publisher-redirect-support
It's not tested and experimental. Trying to send onStatus like FMS do.
HLS/DASH redirect not supported, just RTMP.
Compile nginx with that version of module, add new option to config:
notify_send_redirect = 1;
And try to redirect stream.
@sergey-dryabzhinsky thank you, i will test this, i don't need to redirect viewers or ffmpeg stream, because the redirect will be performed only when the publisher connect, i try and come back :)
Hi, after a long week I can finally try your branch of the module.
I tried to compile but an error occured : line 1059 and 1061 (unused var)
In function ‘ngx_rtmp_live_data’:
/nginx-rtmp-module/ngx_rtmp_live_module.c:1059:37: error: unused variable ‘msg_type’ [-Werror=unused-variable]
So i opened the file, commented the line and started new compilation, another error occured :
/nginx-rtmp-module/ngx_rtmp_stat_module.c: In function ‘ngx_rtmp_stat_live’:
/nginx-rtmp-module/ngx_rtmp_stat_module.c:524:41: error: comparison between signed and unsigned integer expressions [-Werror=sign-compare]
But for this, i was unable to fix the error
for (rn = 0; rn < rctx->rec.nelts; ++rn, ++recctx) {
i think rn is signed and rec.nelts is unsigned, but do you know what to do ?
Thanks
Seems you are using 'master' branch, not 'add-publisher-redirect-support'.
Hello,
I tried with the add-publisher-redirect-support branch, but the result is the same.
Commands :
cd ~/build/nginx
git clone -b add-publisher-redirect-support git://github.com/sergey-dryabzhinsky/nginx-rtmp-module.git
wget http://nginx.org/download/nginx-1.9.2.tar.gz
tar xzf nginx-1.9.2.tar.gz
cd nginx-1.9.2
./configure --prefix=/home/oneill/bin/nginx --error-log-path=/home/oneill/logs/nginx-error.log --http-log-path=/home/oneill/logs/nginx.log --user=oneill --group=www-data --add-module=/home/oneill/build/nginx/nginx-rtmp-module --with-http_ssl_module
make
Result :
/home/oneill/build/nginx/nginx-rtmp-module/ngx_rtmp_live_module.c: In function ‘ngx_rtmp_live_data’:
/home/oneill/build/nginx/nginx-rtmp-module/ngx_rtmp_live_module.c:1059:37: error: variable ‘msg_type’ set but not used [-Werror=unused-but-set-variable]
cc1: all warnings being treated as errors
make[1]: ** [objs/addon/nginx-rtmp-module/ngx_rtmp_live_module.o] Error 1
make[1]: Leaving directory `/home/oneill/build/nginx/nginx-1.9.2'
make: ** [build] Error 2
I fixed the first error in ngx_rtmp_live_module.c @ 1059
Then retry make, new error :
/home/oneill/build/nginx/nginx-rtmp-module/ngx_rtmp_relay_module.c: In function ‘ngx_rtmp_relay_create_connection’:
/home/oneill/build/nginx/nginx-rtmp-module/ngx_rtmp_relay_module.c:504:5: error: value computed is not used [-Werror=unused-value]
cc1: all warnings being treated as errors
make[1]: ** [objs/addon/nginx-rtmp-module/ngx_rtmp_relay_module.o] Error 1
make[1]: Leaving directory `/home/oneill/build/nginx/nginx-1.9.2'
make: ** [build] Error 2
So i opened the file ngx_rtmp_relay_module.c @ 504 :
ngx_cpymem(&rs->app, &rctx->app, sizeof(rctx->app));
but i was unable to fix the error, i think this is the last, but i can't do anything, any idea ?
Thanks
What system you are using? Compiler, version, CFLAGS?
It's like your build environment treat all warnings like errors.
my dedicated server run under Debian Wheezy x64, compilers :
ii g++ 4:4.7.2-1 amd64 GNU C++ compiler
ii g++-4.7 4.7.2-5 amd64 GNU C++ compiler
ii gcc 4:4.7.2-1 amd64 GNU C compiler
ii gcc-4.7 4.7.2-5 amd64 GNU C compiler
it's an fresh and up to date install, and i didn't configured anything to treat all warnings as errors... i don't know what the fuck is happening !
Thank you again for your patience and your help, it's really appreciated :D
Try to unset vars before build:
unset CFLAGS CXXFLAGS LDFLAGS
export CFLAGS="-O2 -pipe"
export LDFLAGS="-Wl,--as-needed"
CFLAGS="${CFLAGS}" CORE_LINK="${LDFLAGS}" ./configure ... long line of enabled modules ...
make -j2
And maybe nginx-1.9 is too fresh. Try 1.8 version.
If you have a bespoke client/publisher app this could check for available slots on a server and then return the publisher/client url to be used.
@sergey-dryabzhinsky do you know if chat could be added to the rtmp module?
@paulashford1975 Please open new issue about that.
hi :)
@paulashford1975 by app you mean program used to broadcast like open broadcaster software ? if you mean that, no i don't have, and i don't want the users have to change app url each time. They select the closest server and that's all
@sergey-dryabzhinsky I installed nginx 1.8.0, unsetted vars, compiled again and this time, the installation is good, but when i try to redirect the stream to server B, this is the same as nginx rtmp module by arut, the publish command is triggered on server B but if i stop nginx of server B, the stream continue, if i stop nginx of server A, the stream is disconnected.
Do you how twitch work ? did they use the relay method ?
And what in debug log?
There must be line: notify: send 302 redirect for stream 'blahblah' to new location 'some-rtmp-url'
yep forgot to add log entry !
Server A :
2015/07/14 16:30:10 [info] 28948#0: *1 client connected '89.91.146.92'
2015/07/14 16:30:10 [info] 28948#0: *1 connect: app='app' args='' flashver='FMLE/3.0 (compatible; FMSc/1.0)' swf_url='rtmp://dev-rbx.lossius.ovh/app' tc_url='rtmp://dev-rbx.lossius.ovh/app' page_url='' acodecs=0 vcodecs=0 object_encoding=0, client: 89.91.146.92, server: 0.0.0.0:1935
2015/07/14 16:30:10 [info] 28948#0: *1 createStream, client: 89.91.146.92, server: 0.0.0.0:1935
2015/07/14 16:30:10 [info] 28948#0: *1 publish: name='test' args='' type=live silent=0, client: 89.91.146.92, server: 0.0.0.0:1935
2015/07/14 16:30:10 [info] 28948#0: *1 notify: publish 'dev-rbx.lossius.ovh/publishStart', client: 89.91.146.92, server: 0.0.0.0:1935
2015/07/14 16:30:10 [error] 28948#0: *1 notify: push 'test' to 'rtmp://5.135.155.223/app/test', client: 89.91.146.92, server: 0.0.0.0:1935
2015/07/14 16:30:10 [info] 28948#0: *1 relay: create push name='test' app='' playpath='' url='5.135.155.223/app/test', client: 89.91.146.92, server: 0.0.0.0:1935
Server B :
2015/07/14 16:32:58 [info] 1867#0: *1 client connected '91.121.160.63'
2015/07/14 16:32:58 [info] 1867#0: *1 connect: app='app' args='' flashver='LNX.11,1,102,55' swf_url='' tc_url='rtmp://5.135.155.223/app' page_url='' acodecs=3575 vcodecs=252 object_encoding=0, client: 91.121.160.63, server: 0.0.0.0:1935
2015/07/14 16:32:58 [info] 1867#0: *1 createStream, client: 91.121.160.63, server: 0.0.0.0:1935
2015/07/14 16:32:58 [info] 1867#0: *1 publish: name='test' args='' type=live silent=0, client: 91.121.160.63, server: 0.0.0.0:1935
2015/07/14 16:32:58 [info] 1867#0: *1 notify: publish 'dev-rbx-i01.lossius.ovh/publishStart', client: 91.121.160.63, server: 0.0.0.0:1935
2015/07/14 16:33:13 [info] 1867#0: *1 notify: update 'dev-rbx-i01.lossius.ovh/publishUpdate', client: 91.121.160.63, server: 0.0.0.0:1935
2015/07/14 16:33:16 [info] 1867#0: *1 disconnect, client: 91.121.160.63, server: 0.0.0.0:1935
2015/07/14 16:33:16 [info] 1867#0: *1 deleteStream, client: 91.121.160.63, server: 0.0.0.0:1935
2015/07/14 16:33:16 [info] 1867#0: *1 notify: publish_done 'dev-rbx-i01.lossius.ovh/publishDone', client: 91.121.160.63, server: 0.0.0.0:1935
89.91.146.92 is ip of publisher, 91.121.160.63 is the ip of server A
Did you set notify_send_redirect = 1; in server A config?
Did you send 302 http code in notify response?
Yes, i send http header :
header('HTTP/1.0 302 Publish Here');
header('Location: rtmp://5.135.155.223/app/'.$_POST['name']);
For the notify_send_redirect, an error occur :
nginx: [emerg] unknown directive "notify_send_redirect" in /.....
i also tried send_redirect in server {} and app {}
It means that you are compiled sources not from branch.
WTF, there is my commands :
git clone -b add-publisher-redirect-support git://github.com/sergey-dryabzhinsky/nginx-rtmp-module.git
wget http://nginx.org/download/nginx-1.8.0.tar.gz && tar xzf nginx-1.8.0.tar.gz && cd nginx-1.8.0
unset CFLAGS CXXFLAGS LDFLAGS
export CFLAGS="-O2 -pipe"
export LDFLAGS="-Wl,--as-needed"
CFLAGS="${CFLAGS}" CORE_LINK="${LDFLAGS}" ./configure --prefix=/home/oneill/bin/nginx --error-log-path=/home/oneill/logs/nginx-error.log --http-log-path=/home/oneill/logs/nginx.log --user=oneill --group=www-data --add-module=/home/oneill/build/nginx/nginx-rtmp-module --with-http_ssl_module
make -j2
make install
maybe an error in the git clone command ??
You should try:
git clone https://github.com/sergey-dryabzhinsky/nginx-rtmp-module.git
git checkout add-publisher-redirect-support
Hello,
I come back with some news.
I successfully installed nginx 1.8.0 with your git's branch "add-publisher-redirect-support", added "notify_send_redirect on;" in my app {}
Now when i connect to server A :
2015/07/19 11:59:14 [info] 3962#0: *5 client connected '89.91.146.92'
2015/07/19 11:59:14 [info] 3962#0: *5 connect: app='app' args='' flashver='FMLE/3.0 (compatible; FMSc/1.0)' swf_url='rtmp://dev-rbx.lossius.ovh/app' tc_url='rtmp://dev-rbx.lossius.ovh/app' page_url='' acodecs=0 vcodecs=0 object_encoding=0, client: 89.91.146.92, server: 0.0.0.0:1935
2015/07/19 11:59:14 [info] 3962#0: *5 createStream, client: 89.91.146.92, server: 0.0.0.0:1935
2015/07/19 11:59:14 [info] 3962#0: *5 publish: name='test' args='' type=live silent=0, client: 89.91.146.92, server: 0.0.0.0:1935
2015/07/19 11:59:14 [info] 3962#0: *5 notify: publish 'dev-rbx.lossius.ovh/publishStart', client: 89.91.146.92, server: 0.0.0.0:1935
2015/07/19 11:59:14 [error] 3962#0: *5 notify: send 302 redirect for stream 'test' to new location 'rtmp://5.135.155.223/app/test', client: 89.91.146.92, server: 0.0.0.0:1935
2015/07/19 11:59:14 [notice] 1706#0: signal 17 (SIGCHLD) received
2015/07/19 11:59:14 [alert] 1706#0: worker process 3962 exited on signal 11
2015/07/19 11:59:14 [notice] 1706#0: start worker process 512
This seems to send redirect signal, but with OBS, i got :
RTMPSockBuf_Fill, remote host closed connection
And nothing on the logs of server B
Seems like I wrote buggy redirect sender. I'll try to fix it.
// update
Try to pull update from git and build.
And if you use ffmpeg to push - try to watch debug logs with -loglevel debug. It would be nice to see what is it receiving.
Hello,
I updated and rebuilded module but the log output is the same as before.
I will download a video and then try again with ffmpeg with loglevel debug :)
If something like this in log
2015/07/19 11:59:14 [alert] 1706#0: worker process 3962 exited on signal 11
When redirect sender still buggy. I'll try to investigate this.
Yes, there is
2015/07/31 17:42:27 [alert] 14051#0: worker process 15417 exited on signal 11
With previous lines
2015/07/31 17:42:27 [error] 15417#0: *3 notify: send 302 redirect for stream 'test' to new location 'rtmp://5.235.155.213/app/test', client: 89.91.146.92, server: 0.0.0.0:1935
2015/07/31 17:42:27 [notice] 14051#0: signal 17 (SIGCHLD) received
2015/07/31 17:42:27 [alert] 14051#0: worker process 15417 exited on signal 11
2015/07/31 17:42:27 [notice] 14051#0: start worker process 30520
And to be sure have your lastest module, i used an
rm -rf nginx-rtmp-module
and executed the git clone again then recompile nginx
Branch updated. nginx don't segfault anymore.
I continue investigation.
‎R Sent from my BlackBerry 10 smartphone. From: SergeySent: Saturday, August 1, 2015 04:07To: arut/nginx-rtmp-moduleReply To: arut/nginx-rtmp-moduleSubject: Re: [nginx-rtmp-module] Simple redirect (publisher) (#645)Branch updated. nginx don't segfault anymore.
But nor ffmpeg nor FMLE don't redirect self.
I suggest this works only on connection opening. Not on publishing start.
—Reply to this email directly or view it on GitHub.
I update my branch with new RTMP messages for redirection.
FFmpeg works only with highly patched version of rtmpdump library.
Look for it at https://launchpad.net/~sergey-dryabzhinsky/+archive/ubuntu/ffmpeg
FMLE just pushing into old location like nothing sended to it.
It would be great if anyone check other publishing software.
Hi.
When I try to build 1.8.0 with add-publisher-redirect-support I've receive error:
OS: Ubuntu 14.04 x64, 12.04 x64. With nginx 1.10 same error.
cc -c -O2 -pipe -I/usr/src/nginx-1.8.0/nginx-rtmp-module -I src/core -I src/event -I src/event/modules -I src/os/unix -I objs -I src/http -I src/http/modules -I src/mail \
-o objs/addon/nginx-rtmp-module/ngx_rtmp_log_module.o \
/usr/src/nginx-1.8.0/nginx-rtmp-module/ngx_rtmp_log_module.c
/usr/src/nginx-1.8.0/nginx-rtmp-module/ngx_rtmp_notify_module.c: In function 'ngx_rtmp_notify_publish_handle':
/usr/src/nginx-1.8.0/nginx-rtmp-module/ngx_rtmp_notify_module.c:1164:9: error: too few arguments to function 'ngx_rtmp_send_close_method'
/usr/src/nginx-1.8.0/nginx-rtmp-module/ngx_rtmp.h:585:11: note: declared here
make[1]: ** [objs/addon/nginx-rtmp-module/ngx_rtmp_notify_module.o] Error 1
make[1]: ** Waiting for unfinished jobs....
make[1]: Leaving directory `/usr/src/nginx-1.8.0'
make: *** [build] Error 2
@marchenkov That code was merged into my master branch and fixed.
How I can download this?
git clone https://github.com/sergey-dryabzhinsky/nginx-rtmp-module.git
git checkout add-publisher-redirect-support
hi sergey
i do the following commands to get nginx & nginx-rtmp-module after configure , make & make install i get an error that i dont know how can i resolve it
please !!! HELP !!! me
the commands
git clone -b add-publisher-redirect-support git://github.com/sergey-dryabzhinsky/nginx-rtmp-module.git
wget http://nginx.org/download/nginx-1.9.2.tar.gz
tar xzf nginx-1.9.2.tar.gz
[root@crtmp opt]# pwd
/opt
[root@crtmp opt]# ls
nginx-1.9.2 nginx-1.9.2.tar.gz nginx-rtmp-module rh
[root@crtmp opt]# cd nginx-1.9.2/
[root@crtmp nginx-1.9.2]# ./configure --prefix=/usr/local/nginx --error-log-path=/var/log/nginx-error.log --http-log-path=/var/log/nginx.log --add-module=../nginx-rtmp-module --with-http_ssl_module
[root@crtmp nginx-1.9.2]# make
[root@crtmp nginx-1.9.2]# make install
the error after make install command
-o objs/addon/nginx-rtmp-module/ngx_rtmp_notify_module.o \
../nginx-rtmp-module/ngx_rtmp_notify_module.c
../nginx-rtmp-module/ngx_rtmp_notify_module.c: In function ‘ngx_rtmp_notify_publish_handle’:
../nginx-rtmp-module/ngx_rtmp_notify_module.c:1164:9: error: too few arguments to function ‘ngx_rtmp_send_close_method’
send = ngx_rtmp_send_close_method(s);
^
In file included from ../nginx-rtmp-module/ngx_rtmp_notify_module.c:10:0:
../nginx-rtmp-module/ngx_rtmp.h:585:11: note: declared here
ngx_int_t ngx_rtmp_send_close_method(ngx_rtmp_session_t _s, char methodName);
^
make[1]: *_* [objs/addon/nginx-rtmp-module/ngx_rtmp_notify_module.o] Error 1
make[1]: Leaving directory `/opt/nginx-1.9.2'
make: ** [install] Error 2
i guess the problem does not solve
@marchenkov @bashsiz
git clone https://github.com/sergey-dryabzhinsky/nginx-rtmp-module.git
You don't need to checkout that branch. Just use master.
OK
You are Grate dude
i was wrong and i will come back with more questions
thank you very much
Hi again
i will explain my problem please help me to solve it
first of all i want to redirect rtmp request from one server to another
server A = 192.168.2.4
server B = 192.168.2.2
client C = 192.168.2.1
I have a live stream on Server B by address "rtmp://192.168.2.2/live/aaa"
in server A 192.168.2.4 my nginx config is :
http {
.....
server {
listen 80;
server_name localhost;
......
location /play {
return 301 rtmp://192.168.2.2/live/aaa;
}
.......
}
rtmp {
server {
access_log /var/log/nginx/rtmp_access.log;
listen 1935;
notify_method post;
notify_send_redirect on;
application live {
live on;
on_play http://localhost/play;
}
}
}
and when in client i play the stream in 192.168.2.4 with ffplay
the stream play from Server A 192.168.2.4 and it can not redirect client to server B 192.168.2.2 and works like a proxy
please help me if the rtmp requests can be redirect like http
FFmpeg must be builded against patched librtmp (rtmpdump project).
By default librtmp don't recognize redirects.
As I mentioned here: https://github.com/arut/nginx-rtmp-module/issues/645#issuecomment-126937308
And you may check if redirect via onStatus callback with NetConnection.Connect.Rejected:
ffplay -loglevel debug rtmp://192.168.2.4/live/aaa
Stop.
Play redirect not supported by now. Only publish.
@bashsiz I'll address you to https://github.com/sergey-dryabzhinsky/nginx-rtmp-module/issues/111
hello again and thank you i come back after a week
i replace on_play with on_publish in my config file and try again to play the video and the following text is my rtmpdump command output
[root@bashsiz~]# rtmpdump --verbose --live -r "rtmp://192.168.2.4/live/aaa"
RTMPDump v2.4
(c) 2010 Andrej Stepanchuk, Howard Chu, The Flvstreamer Team; license: GPL
DEBUG: Parsing...
DEBUG: Parsed protocol: 0
DEBUG: Parsed host : 192.168.2.4
DEBUG: Parsed app : live
WARNING: You haven't specified an output file (-o filename), using stdout
DEBUG: Protocol : RTMP
DEBUG: Hostname : 192.168.2.4
DEBUG: Port : 1935
DEBUG: Playpath : aaa
DEBUG: tcUrl : rtmp://192.168.2.4:1935/live
DEBUG: app : live
DEBUG: live : yes
DEBUG: timeout : 30 sec
DEBUG: Setting buffer time to: 36000000ms
Connecting ...
DEBUG: RTMP_Connect1, ... connected, handshaking
DEBUG: HandShake: Type Answer : 03
DEBUG: HandShake: Server Uptime : 111717694
DEBUG: HandShake: FMS Version : 0.0.0.0
DEBUG: HandShake: Handshaking finished....
DEBUG: RTMP_Connect1, handshaked
DEBUG: Invoking connect
INFO: Connected...
DEBUG: HandleServerBW: server BW = 5000000
DEBUG: HandleClientBW: client BW = 5000000 2
DEBUG: HandleChangeChunkSize, received: chunk size change to 4096
DEBUG: RTMP_ClientPacket, received: invoke 190 bytes
DEBUG: (object begin)
DEBUG: (object begin)
DEBUG: Property: Name: fmsVer, STRING: FMS/3,0,1,123
DEBUG: Property: Name: capabilities, NUMBER: 31.00
DEBUG: (object end)
DEBUG: (object begin)
DEBUG: Property: Name: level, STRING: status
DEBUG: Property: Name: code, STRING: NetConnection.Connect.Success
DEBUG: Property: Name: description, STRING: Connection succeeded.
DEBUG: Property: Name: objectEncoding, NUMBER: 0.00
DEBUG: (object end)
DEBUG: (object end)
DEBUG: HandleInvoke, server invoking _result
DEBUG: HandleInvoke, received result for method call connect
DEBUG: sending ctrl. type: 0x0003
DEBUG: Invoking createStream
DEBUG: FCSubscribe: aaa
DEBUG: Invoking FCSubscribe
DEBUG: RTMP_ClientPacket, received: invoke 29 bytes
DEBUG: (object begin)
DEBUG: Property: NULL
DEBUG: (object end)
DEBUG: HandleInvoke, server invoking _result
DEBUG: HandleInvoke, received result for method callDEBUG: SendPlay, seekTime=0, stopTime=0, sending play: aaa
DEBUG: Invoking play
DEBUG: sending ctrl. type: 0x0003
DEBUG: RTMP_ClientPacket, received: invoke 96 bytes
DEBUG: (object begin)
DEBUG: Property: NULL
DEBUG: (object begin)
DEBUG: Property: Name: level, STRING: status
DEBUG: Property: Name: code, STRING: NetStream.Play.Start
DEBUG: Property: Name:description, STRING: Start live
DEBUG: (object end)
DEBUG: (object end)
DEBUG: HandleInvoke, server invoking onStatus
DEBUG: HandleInvoke, onStatus: NetStream.Play.Start
Starting Live Stream
DEBUG: RTMP_ClientPacket, received: notify 24 bytes
DEBUG: (object begin)
DEBUG: (object end)
DEBUG: RTMPSockBuf_Fill, recv returned -1. GetSockError(): 11 (Resource temporarily unavailable)
ERROR: RTMP_ReadPacket, failed to read RTMP packet header
-0.001 kB / 0.00 sec
DEBUG: RTMP_Read returned: 0
Download may be incomplete (downloaded about 0.00%), try resuming
DEBUG: Closing connection.
DEBUG: Invoking deleteStream
but when i use on_play instead of on_publish my rtmpdump output is
[root@bashsizi~]# rtmpdump --verbose --live -r "rtmp://192.168.2.4/live/aaa"
RTMPDump v2.4
(c) 2010 Andrej Stepanchuk, Howard Chu, The Flvstreamer Team; license: GPL
DEBUG: Parsing...
DEBUG: Parsed protocol: 0
DEBUG: Parsed host : 192.168.2.4
DEBUG: Parsed app : live
WARNING: You haven't specified an output file (-o filename), using stdout
DEBUG: Protocol : RTMP
DEBUG: Hostname : 192.168.2.4
DEBUG: Port : 1935
DEBUG: Playpath : aaa
DEBUG: tcUrl : rtmp://192.168.2.4:1935/live
DEBUG: app : live
DEBUG: live : yes
DEBUG: timeout : 30 sec
DEBUG: Setting buffer time to: 36000000ms
Connecting ...
DEBUG: RTMP_Connect1, ... connected, handshaking
DEBUG: HandShake: Type Answer : 03
DEBUG: HandShake: Server Uptime : 112415824
DEBUG: HandShake: FMS Version : 0.0.0.0
DEBUG: HandShake: Handshaking finished....
DEBUG: RTMP_Connect1, handshaked
DEBUG: Invoking connect
INFO: Connected...
DEBUG: HandleServerBW: server BW = 5000000
DEBUG: HandleClientBW: client BW = 5000000 2
DEBUG: HandleChangeChunkSize, received: chunk size change to 4096
DEBUG: RTMP_ClientPacket, received: invoke 190 bytes
DEBUG: (object begin)
DEBUG: (object begin)
DEBUG: Property: Name: fmsVer, STRING: FMS/3,0,1,123
DEBUG: Property: Name: capabilities, NUMBER: 31.00
DEBUG: (object end)
DEBUG: (object begin)
DEBUG: Property: Name: level, STRING: status
DEBUG: Property: Name: code, STRING: NetConnection.Connect.Success
DEBUG: Property: Name: description, STRING: Connection succeeded.
DEBUG: Property: Name: objectEncoding, NUMBER: 0.00
DEBUG: (object end)
DEBUG: (object end)
DEBUG: HandleInvoke, server invoking _result
DEBUG: HandleInvoke, received result for method call connect
DEBUG: sending ctrl. type: 0x0003
DEBUG: Invoking createStream
DEBUG: FCSubscribe: aaa
DEBUG: Invoking FCSubscribe
DEBUG: RTMP_ClientPacket, received: invoke 29 bytes
DEBUG: (object begin)
DEBUG: Property: NULL
DEBUG: (object end)
DEBUG: HandleInvoke, server invoking _result
DEBUG: HandleInvoke, received result for method call createStream
DEBUG: SendPlay, seekTime=0, stopTime=0, sending play: aaa
DEBUG: Invoking play
DEBUG: sending ctrl. type: 0x0003
DEBUG: RTMP_ClientPacket, received: invoke 168 bytes
DEBUG: (object begin)
DEBUG: Property: NULL
DEBUG: (object begin)
DEBUG: Property: Name: level, STRING: error
DEBUG: Property: Name: code, STRING: NetConnection.Connect.Rejected
DEBUG: Property: Name: description, STRING: Connect here
DEBUG: Property: Name: ex, OBJECT
DEBUG: (object begin)
DEBUG: Property: Name: code, NUMBER: 302.00
DEBUG: Property: Name: redirect, STRING: rtmp://192.168.2.2/live/aaa
DEBUG: (object end)
DEBUG: (object end)
DEBUG: (object end)
DEBUG: HandleInvoke, server invoking _error
ERROR: rtmp server sent error
DEBUG: RTMP_ClientPacket, received: invoke 17 bytes
DEBUG: (object begin)
DEBUG: (object end)
DEBUG: HandleInvoke, server invoking
ERROR: rtmp server requested close
DEBUG: Invoking deleteStream
DEBUG: Closing connection.
as you see in output there is a line with redirect
DEBUG: Property: Name: redirect, STRING: rtmp://192.168.2.2/live/aaa
I had a similar issue with ffmpeg and on_play redirects. Thanks to @sergey-dryabzhinsky 's comment on ffmpeg I noticed that ffmpeg 2.x was working fine while 3.x was giving issues.
So I just used avconv instead on the machine having ffmpeg 3.x installed and that works fine with on_play reirects. Do note that I am using nginx-rtmp 1.1.7 and "notify_relay_redirect on" to achieve this
@sergey-dryabzhinsky Hi Sergey. I'm not sure if this feature covers my use case. I want to use notify_send_redirect to create a load balancer for publishers. The load balancer server has no ffmpeg, and will not accept play requests. This server's only purpose is to take publish requests, and return a 302 redirect so that the publisher will be sent to another server that will accept the publish and support playing.
Without notify_send_redirect, the "redirect" works properly - but of course the stream exists on both the original publish URL and where it was redirected to (keeping the original connection open and using double bandwidth). Once I enable notify_send_redirect, it just doesn't want to work. Whether the on_publish request for rtmp://10.10.10.2/app1 with stream name "hello" returns a 302 for rtmp://10.10.10.2/app2 or rtmp://10.10.10.2/app2/hello the publisher is not getting redirected. Right now I have app1 and app2 on the same machine for testing; later it would be a public IP equivalent for 10.10.10.3/app2 for example.
Do I understand this feature properly? I want the publisher to receive the new url and connect to that server instead. I don't want any ffmpeg or push involved, just purely forcing the publisher onto a different URL.
Separately, someone else here mentioned OBS (the most popular streaming client). Assuming this feature should do what I want, do we know if OBS supports handling 302 redirects?
@frickenate https://github.com/winshining/nginx-http-flv-module covers you use case. You can use it as following:
server {
application app1 {
proxy_pass rtmp://host(ip or domain name)[:port]/app2;
}
}
Am I wrong in thinking that notify_send_redirect in the fork of rtmp-module already supports this use case? Can you briefly explain what exactly it does if not sending the redirect to the client? No real documentation to find :)
@frickenate Sorry, I have no idea about directive 'notify_send_redirect'. What I've done is similar to what nginx does when it is used on Unix-like platforms (Windows doesn't support unix domain socket) and used in multi-processes mode: a process serves as a publisher, and relays streams to other processes, this is done through the locally unix domain sockets on a single machine. I extended the feature according to proxy & upstream features used in HTTP modules in nginx, simple redirect can be automatically done by it, without the help of sending redirect to the client. In addition, with it, you can play the stream both on the redirected servers and the balancer, since your play will also be relayed to the upstream servers.
We're talking about different functionality then. I'm looking for a "simple" redirect from one rtmp server to another, the same way I can do an http redirect from http://example1.com/ to http://example2.com/. What you are talking about is a reverse proxy, where http://example1.com/ would proxy the request to http://example2.com/, instead of telling the client to go look at example2.com themselves. That is not acceptable as it requires twice the bandwidth (as well as cpu and memory overhead). I believe this is what rtmp notify redirect is supposed to accomplish - but I might be wrong. I'm trying to avoid the extremely complicated and prohibitively expensive requirement of a setup known as "Direct Server Return", which heavily manipulates the TCP stack.
Basically: I should be able to handle thousands of publishers connecting to a single load balancer on publish.example.com, whereby each incoming publish connection is redirected to one of a hundred backend servers (ie: publish001.example.com through publish100.example.com). Having publish.example.com be a reverse proxy to 100 backend servers doesn't work - you can't support a reverse proxy of 1,000+ clients at 1000-3000 KB bitrate each.
@frickenate The main issue is publisher itself. It must understand "redirect" status error response.
Like I mention
I suppose that simplest way is to make a pool of receivers (domains).
And each of them will have several IPs defined in DNS.
Which may round-robin them or stick some to sender IP.
Or use some CDN, like Akamai / Cloudflare.
@frickenate Yeah, you gave the scenario not pratical for reverse proxy which I didn't take into consideration. Maybe 'notify_send_redirect' is a good solution, but it requires clients to support 302 redirection, whereas not every client meets the requirement. Hope someone can work it out!
@frickenate If you want to support any client, this is unfortunately not the solution. You need to manage a load balancer which support DSR. All ingress servers directly respond to client without pass thru the load balancer. Take a coffee and watch this https://www.youtube.com/watch?v=bxhYNfFeVF4
No L7 for RTMP, no anycast at start and not obliged to used ECMP, round robin will be ok.
Hello, is the rtmp publishing redirect feature working with the patched module? I was checking the above conversation but lost track along the way. Idea is to completely redirect publisher to a given server instead of relaying from server to server Thank you
Hello, is the rtmp publishing redirect feature working with the patched module? I was checking the above conversation but lost track along the way. Idea is to completely redirect publisher to a given server instead of relaying from server to server Thank you
I don't think OBS supports this redirect. I tested it and checked with WireShark, OBS keeps staying connected to the nginx instead of following redirect so Load Balancing is not working unfortunately.
Most helpful comment
We're talking about different functionality then. I'm looking for a "simple" redirect from one rtmp server to another, the same way I can do an http redirect from http://example1.com/ to http://example2.com/. What you are talking about is a reverse proxy, where http://example1.com/ would proxy the request to http://example2.com/, instead of telling the client to go look at example2.com themselves. That is not acceptable as it requires twice the bandwidth (as well as cpu and memory overhead). I believe this is what rtmp notify redirect is supposed to accomplish - but I might be wrong. I'm trying to avoid the extremely complicated and prohibitively expensive requirement of a setup known as "Direct Server Return", which heavily manipulates the TCP stack.
Basically: I should be able to handle thousands of publishers connecting to a single load balancer on publish.example.com, whereby each incoming publish connection is redirected to one of a hundred backend servers (ie: publish001.example.com through publish100.example.com). Having publish.example.com be a reverse proxy to 100 backend servers doesn't work - you can't support a reverse proxy of 1,000+ clients at 1000-3000 KB bitrate each.