arut / nginx-rtmp-module

NGINX-based Media Streaming Server
http://nginx-rtmp.blogspot.com
BSD 2-Clause "Simplified" License
13.22k stars 3.49k forks source link

Simple redirect (publisher) #645

Open lossius30 opened 9 years ago

lossius30 commented 9 years ago

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

sergey-dryabzhinsky commented 9 years ago

Check location url:

lossius30 commented 9 years ago

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

sergey-dryabzhinsky commented 9 years ago

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 ...

      }
lossius30 commented 9 years ago

Thank you ! I will test this tomorrow, i come back after testing :)

sergey-dryabzhinsky commented 9 years ago

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"
lossius30 commented 9 years ago

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 !

lossius30 commented 9 years ago

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 ...

sergey-dryabzhinsky commented 9 years ago

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.

lossius30 commented 9 years ago

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 :

  1. Connect to hello.mydomain.com
  2. hello.mydomain.com search for available slot
  3. hello.mydomain.com redirect broadcaster to server A, B, C...

It's like twitch.tv, but not for gamers :)

Thank you if you can help again !

lossius30 commented 9 years ago

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

VackerSimon commented 9 years ago

@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.

sergey-dryabzhinsky commented 9 years ago

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.

sergey-dryabzhinsky commented 9 years ago

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.

sergey-dryabzhinsky commented 9 years ago

And don't forget about HLS/DASH clients - they need to be redirected too.

sergey-dryabzhinsky commented 9 years ago

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.

lossius30 commented 9 years ago

@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 :)

lossius30 commented 8 years ago

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

sergey-dryabzhinsky commented 8 years ago

Seems you are using 'master' branch, not 'add-publisher-redirect-support'.

lossius30 commented 8 years ago

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

lossius30 commented 8 years ago

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

sergey-dryabzhinsky commented 8 years ago

What system you are using? Compiler, version, CFLAGS? It's like your build environment treat all warnings like errors.

lossius30 commented 8 years ago

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

sergey-dryabzhinsky commented 8 years ago

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.

pdashford commented 8 years ago

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.

pdashford commented 8 years ago

@sergey-dryabzhinsky do you know if chat could be added to the rtmp module?

sergey-dryabzhinsky commented 8 years ago

@paulashford1975 Please open new issue about that.

lossius30 commented 8 years ago

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 ?

sergey-dryabzhinsky commented 8 years ago

And what in debug log? There must be line: notify: send 302 redirect for stream 'blahblah' to new location 'some-rtmp-url'

lossius30 commented 8 years ago

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

sergey-dryabzhinsky commented 8 years ago

Did you set notify_send_redirect = 1; in server A config? Did you send 302 http code in notify response?

lossius30 commented 8 years ago

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 {}

sergey-dryabzhinsky commented 8 years ago

It means that you are compiled sources not from branch.

lossius30 commented 8 years ago

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 ??

sergey-dryabzhinsky commented 8 years ago

You should try:

git clone https://github.com/sergey-dryabzhinsky/nginx-rtmp-module.git
git checkout add-publisher-redirect-support
lossius30 commented 8 years ago

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

sergey-dryabzhinsky commented 8 years ago

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.

lossius30 commented 8 years ago

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 :)

sergey-dryabzhinsky commented 8 years ago

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.

lossius30 commented 8 years ago

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

sergey-dryabzhinsky commented 8 years ago

Branch updated. nginx don't segfault anymore.

I continue investigation.

cadesalaberry commented 8 years ago
                                                                                  ‎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.

sergey-dryabzhinsky commented 8 years ago

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.

marcencov commented 8 years ago

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

sergey-dryabzhinsky commented 8 years ago

@marchenkov That code was merged into my master branch and fixed.

marcencov commented 8 years ago

How I can download this?

git clone https://github.com/sergey-dryabzhinsky/nginx-rtmp-module.git git checkout add-publisher-redirect-support

sergey-dryabzhinsky commented 8 years ago

@marchenkov @bashsiz

git clone https://github.com/sergey-dryabzhinsky/nginx-rtmp-module.git

You don't need to checkout that branch. Just use master.

sergey-dryabzhinsky commented 8 years ago

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

sergey-dryabzhinsky commented 8 years ago

And you may check if redirect via onStatus callback with NetConnection.Connect.Rejected: ffplay -loglevel debug rtmp://192.168.2.4/live/aaa

sergey-dryabzhinsky commented 8 years ago

Stop. Play redirect not supported by now. Only publish.

sergey-dryabzhinsky commented 8 years ago

@bashsiz I'll address you to https://github.com/sergey-dryabzhinsky/nginx-rtmp-module/issues/111