Open caleblanchard opened 7 years ago
You can put them in your first RTMP request and It'll push them to your destination RTMP server. Just change it to
application live {
live on;
meta copy;
push rtmp://differentserver/live;
}
Either way if you want to give the destination RTMP server (which is rtmp://differentserver here) from Database of somewhere else just use on_publish and 3xx redirect.
Through looking at the log file i found that just like there are $name and $app variables, there is an $args variable that I can use. However, it looks like the variables don't work when using the normal push directive. They work when using exec_push but not just push. Right now I am using a work around of using exec_push ffmpeg to redirect the stream so that I can use the $name and $args variables.
It's not efficent then because FFMPEG needs some hardware stuff like CPU and RAM. Like I said you can use on_publish and call a HTTP rest service like this:
application live {
live on;
on_publish http://localhost:8000/rtmp-redirect
}
take a look at https://github.com/arut/nginx-rtmp-module/wiki/Directives#on_publish
I guess I am not clear on what on_publish does. What is the http://localhost:8000/rtmp-redirect going to do?
It's a callback that you can work on yours parameters there. http://localhost:8000/rtmp-redirect this is just an example. E.g imagine that I have a webservice on above URL. I can catch the parameters is first RTMP URL and then use a HTTP redirect in my webservice to tell the Nginx-rtmp what to do. All things are happend in here: http://localhost:8000/rtmp-redirect.
@massoudAfrashteh
But: How create push duplication with on_publish?
i try push (clone) to many services (1 in X out) and push is really great directive for this:
My encoder uri is:
rtmp://service0/livepp/?service1_secret=foo&service2_secret=bar&service3_secret=blah
rtmp {
server {
listen 1935;
chunk_size 4096;
application livepp {
live on;
record off;
meta copy;
push rtmp://service1/live/$arg_service1_secret;
push rtmp://service2/live/$arg_service2_secret;
push rtmp://service3/live/$arg_service3_secret;
}
}
}
but this not working, because args is not working in simple "push" directive (what is crazy)...
Can you got me some advices to figure this out?
Thank you.
Hi just can use $args not any other parameters that are not listed in rtmp-module
rtmp {
server {
listen 1935;
application live {
live on;
push rtmp://otherserver/live/$name?$args;
}
}
}
e.g rtmp://server/live/stream?t=123 >>> rtmp://otherserver/live/stream?t=123
I want to use $name and $args in push directive, but is not working... Can you tell me how to figure this out? Thank you.
@massoudAfrashteh
Hi $args will contain all arguments after "?" E.g "rtmp://server/live/stream?t=123&a=10&p=20&u=11" then $args will be "t=123&a=10&p=20&u=11". I suggest to run a bash file inside your application then send your variables there and check values.
Thanks, but I use $name and $args in exec_publish directive to run a bash is work, but in push directive $name and $args can't parse variables, it just "$name" and "args" string.
@czb1n could you please share your bash example with $name and $args?
@massoudAfrashteh like i said, run a bash is work. but in the 'push' directive, $name and $args can't parse. example :
rtmp {
server {
listen 1935;
application live {
live on;
push rtmp://otherserver/live/$name?$args;
exec_publish bash -c "echo $name'?'$args >> test.txt";
}
}
}
push rtmp://otherserver/live/$name?$args -> can't not parse variables. exec_publish bash -c "echo $name'?'$args >> test.txt" -> can parse variables.
Did you ever find a way? Running into this exact issue.
@gavalierm @czb1n @denniskrol Forget "push" it does not work with "$args" if you want to pass some parameters to another server there are some ways:
In Origin Server(s)
Then in Target Server(s):
Note: Just read "on_publish" documentation. Choosing each of these depending on your architecture. If you still have problems please read wiki carefully.
Does $arg_varname work? Have not tested it out yet.
I am having the same problem: I want to push to youtube, which changes its secret from time to time. When I push to my nginx, I want to add a GET parameter like rtmp://localhost/live/foo?yt=<secrect>
. This secret should the passed to to the push directive like push rtmp://youtube.com/live2/<secret>
.
I feel like I have a similar situation. I would like to be able to receive streams on multiple addresses then push them to corresponding remote addresses. Eg: In: Rtmp://server1/live/abc Out: Push rtmp://server2/live/abc In: Rtmp://server1/live/def Out:Push rtmp://server2/live/def
Has anyone managed to get the parameters? It is not clear how to do this with the on_publish method. Could you give a real working example? @coditori
rtpm url: rtmp://ip:1935/test/1?ykey=1234
here is my test config:
worker_processes auto;
events {
worker_connections 1024;
}
# RTMP configuration
rtmp {
server {
listen 1935; # Listen on standard RTMP port
chunk_size 4000;
application test{
live on;
on_publish http://192.168.99.100:8090/onpublishtest ;
}
}
}
http {
sendfile off;
tcp_nopush on;
aio on;
directio 512;
default_type application/octet-stream;
server {
listen 8090;
location / {
# some
}
location /onpublishtest {
rewrite ^.*$ rtmp://a.rtmp.youtube.com/live2/$arg_ykey permanent
}
}
}
Has anyone found a way to deal with this?
Essentially, I'm just trying to access request variables that were sent in rtmp url (rtmp://example.com/app?id=123&id2=abc).
I understand you can hook into events like publish or play to access these parameters, but you can only return 1 url and status code, and I'm trying to push out to 3 different ingests.
E.g.:
push rtmp://a.rtmp.youtube.com/live1?id=123; push rtmp://a.rtmp.youtube.com/live2?id=456; push rtmp://a.rtmp.youtube.com/live3?id=789;
Would appreciate any help.
I couldn't find any easy ways. I did it by changing the source code in _ngx_rtmp_relaymodule.c in nginx-rtmp-module.
I added a flag (forward_auth) for nginx.conf:
rtmp {
server {
max_message 5M;
listen 1936;
chunk_size 4000;
application live{
live on;
push rtmp://next_rtmp_server_url:1935/live;
forward_auth on;
}
}
}
to make your nginx pass the arguments you should add _forwardauth on;
and here is my _ngx_rtmp_relaymodule.c : ngx_rtmp_relay_module.txt
Hello guys!
You can use this solution that works for me for Instagram live. I wrote a webservice method to redirect rtmp with $name and $args in C# language.
For example you want to redirect "rtmp://source/app/name?p1=foo&p2=blah" to "rtmp://destination/app/name?p1=foo&p2=blah"
Source RTMP block:
rtmp {
server {
listen 1935;
buflen 500ms;
notify_method get;
publish_time_fix off;
allow play all;
application app {
live on;
record off;
on_publish http://mywebsite/api/v1/live/MyRedirect;
}
}
}
Inside webservice method, is up to you to write a webservice or simple callback method in any language.
public HttpResponseMessage MyRedirect()
{
//Nginx posts $name and $args to this method
//we handle params and recreate $args here
string args = "p1=" + HttpContext.Current.Request.Params["p1"] + "&p2=" + HttpContext.Current.Request.Params["p2"];
//get stream name here you can change it if destination is diffrent
string name = HttpContext.Current.Request.Params["name"];
//Url to redirect
string url = "rtmp://destination/app/" + name + "?" + args;
//--------> 301 redirect
var response = Request.CreateResponse(HttpStatusCode.Moved);
// put your final url in header
response.Headers.Location = new Uri(url);
return response;
}
Above method returns 301 redirect or move with destination url in response header.
FYI for Facebook and Instagram you should use Stunnel to relay rtmp to rtmps. In my case my destination is rtmp://127.0.01:19350/rtmp/name?args which is set in the Stunnel config.
hope this helps.
When utilizing the push directive is there a way to redirect any parameters passed in to the source url to the target url?
Example: Publishing to application via rtmp://server/live/stream?parm1=1&parm2=2
config file: