arut / nginx-rtmp-module

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

Redirecting RTMP? #1270

Open rayj00 opened 6 years ago

rayj00 commented 6 years ago

So I have an Ubuntu server with 4 LXD containers. I want to redirect the incoming rtmp stream to one of the containers. The target container has to be based on who originated the rtmp stream.
So for example, if OBS sends a url as rtmp://"nginx"/user1 can nginx redirect based on the "user1"? The containers are on the same server as nginx.

Thanks,

Ray

rayj00 commented 6 years ago

I am now getting this error: 2018/06/07 20:33:22 [alert] 6152#0: *400 too big RTMP chunk size:134217728, client: 10.57.215.214:1935, server: ngx-relay

Any idea how to troubleshoot this?

rayj00 commented 6 years ago
So the client is OBS on my Windows 7 PC. (192.168.0.5)
I have an Ubuntu Vbox VM (192.168.0.47) on the client PC.
And I have an LXD container (10.57.215.214) on the VM which has the 
media server application on it on port 1935. 

The media server on the container never shows anything in it's log so it seems OBS connects with the VM nginx, , but nginx cannot forward to the Container for some reason?

I can ping from the VM to the container and from the container to the VM. I can ping out to google and yahoo from the container. So it's not a networking problem.

Here is some of the debug log:

2018/06/08 08:58:58 [info] 4738#0: 1 client connected '192.168.0.5' 2018/06/08 08:58:58 [info] 4738#0: 1 connect: app='LPC1' args='' flashver='FMLE/3.0 (compatible; FMSc/1.0)' swf_url='rtmp://192.168.0.47:1935/LPC1' tc_url='rtmp://192.168.0.47:1935/LPC1' page_url='' acodecs=0 vcodecs=0 object_encoding=0, client: 192.168.0.5, server: 0.0.0.0:1935 2018/06/08 08:58:58 [info] 4738#0: 1 createStream, client: 192.168.0.5, server: 0.0.0.0:1935 2018/06/08 08:58:58 [info] 4738#0: 1 publish: name='' args='' type=live silent=0, client: 192.168.0.5, server: 0.0.0.0:1935 2018/06/08 08:58:58 [info] 4738#0: 1 relay: create push name='' app='' playpath='' url='10.57.215.214:1935', client: 192.168.0.5, server: 0.0.0.0:1935 2018/06/08 08:58:58 [alert] 4738#0: 2 too big RTMP chunk size:134217728, client: 10.57.215.214:1935, server: ngx-relay 2018/06/08 08:58:58 [info] 4738#0: 2 too big message: 1048576, client: 10.57.215.214:1935, server: ngx-relay 2018/06/08 08:58:58 [info] 4738#0: 2 disconnect, client: 10.57.215.214:1935, server: ngx-relay 2018/06/08 08:58:58 [info] 4738#0: *2 deleteStream, client: 10.57.215.214:1935, server: ngx-relay

Ideas? Anyone?

rayj00 commented 6 years ago

If I use IPtables to forward incoming rtmp port 1935 to the container ip:port 1935, this works but not a final solution, as there are multiple containers.

Is anyone supporting the rtmp module? I hope so!

rayj00 commented 6 years ago

Does anyone follow these issues?

rayj00 commented 6 years ago

I am wondering if it is legal to have multiple servers of the same type. In my case, I need multiple rtmp servers that service specific users. Rather than having multiple physical machines, I am thinking LXD containers would be nice to use. Each container has a media server.

I am using OBS on my PC (192.168.0.5) to stream rtmp. I am using a Vboxt PC VM 192.168.0.47 Ubuntu 16.04 to host the two containers which are also Ubuntu 16.04.

So, initially I tried with only the push directive. That did not work as I was getting chunk size failures all over the place. Apparently the rtmp module is not being supported any longer? Arun does not respond to my emails. This is a bummer!

But anyway, I'm thinking I can configure the OBS stream settings as such: rtmp://192.168.0.47:1935/LPC1, or rtmp://192.168.0.47:1936/LPC2 and the rtmp will be routed to the proper container using iptables.

So now I am using iptables to forward incoming rtmp to specific containers. Here are the iptables commands:

iptables -t nat -A PREROUTING -p tcp -i enp0s3 --dport 1935 -j DNAT --to-destination 10.57.215.214 :1935 iptables -t nat -A PREROUTING -p tcp -i enp0s3 --dport 1936 -j DNAT --to-destination 10.57.215.247 :1935

This works for the first route....input port 1935 gets routed to the proper container port 1935. However, if I try to stream to port 1936, it also gets routed to the first container rather than the second one.

Here is my .conf:

user nobody;

worker_processes 2;

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

pid logs/nginx.pid;

events { worker_connections 1024; }

rtmp { server { listen 1935; ping 30s; ping_timeout 10s; chunk_size 4096;

application LPC1 { live on;

push rtmp://10.57.215.214:1935;

} } }

rtmp { server { listen 1936; ping 30s; ping_timeout 10s; chunk_size 4096;

application LPC2 { live on;

push rtmp://10.57.215.247:1935;

} } }

And here is the netstat output. As you can see, both ports are being listened to:

sudo netstat -tulpn [sudo] password for ray: Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:22 0.0.0.0: LISTEN 1011/sshd tcp 0 0 0.0.0.0:1935 0.0.0.0: LISTEN 5752/nginx tcp 0 0 0.0.0.0:1936 0.0.0.0: LISTEN 5752/nginx tcp 0 0 10.57.215.1:53 0.0.0.0: LISTEN 1481/dnsmasq tcp6 0 0 :::22 ::: LISTEN 1011/sshd tcp6 0 0 fd42:2bf8:ea23:1a35::53 ::: LISTEN 1481/dnsmasq tcp6 0 0 fe80::78af:32ff:fe9e:53 ::: LISTEN 1481/dnsmasq udp 0 0 10.57.215.1:53 0.0.0.0: 1481/dnsmasq udp 0 0 0.0.0.0:67 0.0.0.0: 1481/dnsmasq udp 0 0 0.0.0.0:68 0.0.0.0: 823/dhclient udp6 0 0 :::547 ::: 1481/dnsmasq udp6 0 0 fd42:2bf8:ea23:1a35::53 ::: 1481/dnsmasq udp6 0 0 fe80::78af:32ff:fe9e:53 :::* 1481/dnsmasq

Any idea why this is not working? Why is port 1936 going to 10.57.215.214 rather than 10.57.215.247?

Thanks, this is driving me crazy!

Ray

karlisk commented 6 years ago

Look into HA proxy - I've had good progress of using it to have a central "point of entry" which receives all the RTMP streams and forwards them to a couple of servers, I haven't gotten around to tweaking it so that it works exactly like I want it but from what I've seen it holds potential to work the way you're looking to (I'm trying to achieve that too).

rayj00 commented 6 years ago

Thanks Karlisk!

As I don't have any experience with HAproxy, perhaps you can show me a config file to forward RTMP to specific servers..in my case LXD containers.

Thanks

Ray

karlisk commented 6 years ago

Currently the config is nothing too impressive or complex and admittedly I haven't looked into getting a client to playback/pull an RTMP stream through HA proxy, but in theory it should work without a problem. Also, a problem that I ran into - I couldn't get "sticky session" to work (an RTMP streamer would get proxied to the same server unless a timeout period reset it, otherwise, under the 'round robin' load balancing method, each new stream would get proxied to the next server with the least ammount of streams), I think it was due to inaccurate/incorrect configuration.

Here's a pretty basic HA proxy config that I use:

global
    log         127.0.0.1 local2
    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     1024
    daemon
    stats socket /var/lib/haproxy/stats

defaults
    log                     global
    option                  tcplog
    option                  dontlognull
    retries                 6
    timeout queue           1m
    timeout connect         15s
    timeout client          1m
    timeout server          30s
    timeout check           10s
    maxconn                 256

frontend rtmp-proxy-front
#listen 0.0.0.0:1935
    bind :1935
    mode tcp
    default_backend rtmp-proxy-backend

backend rtmp-proxy-backend
    balance static-rr
    server Wowza-Old 10.10.10.25:1935 check maxconn 3 weight 100
    server NGINX-Primary 10.10.10.30:1935 check maxconn 50 weight 200
    server NGINX-Backup 10.10.10.35:2000 check maxconn 50 weight 300

listen stats 0.0.0.0:9000       #Listen on all IP's on port 9000
    mode http
    timeout client 5000
    timeout connect 4000
    timeout server 30000

    #This is the virtual URL to access the stats page
    stats uri /haproxy_stats

    #Authentication realm. This can be set to anything. Escape space characters with a backslash.
    stats realm HAProxy\ Statistics

    #The user/pass you want to use. Change this password!
    stats auth admin:zuperpazzword

    #This allows you to take down and bring up back end servers.
    #This will produce an error on older versions of HAProxy.
    stats admin if TRUE

In my situation RTMP is used to receive the streams and playback is done over HTTPS 2 by HLS, hence I don't usually worry about RTMP playback. Also, in your case, if all the containerized NGINX'es are on the same server, you could substitute the IP's that I've mentioned with the single IP that the corresponding server has and just change the individual RTMP ports each container uses. Worth noting that the 'weight' and 'maxconn' are optional parameters.

Also, the http://-haproxy-ip-here-:9000/haproxy_stats is useful to see where the incoming RTMP streams get proxied to. And, according to info I've come across, you can do some pretty wild things when you couple HA proxy with NGINX+RTMP and Lua modules.

rayj00 commented 6 years ago

Actually the RTMP would come into the server that has HAproxy which would then relay to the specific containers which are on the same server. The containers each have the Media server which would then send the HLS onto the live streaming network. Make sense?

karlisk commented 6 years ago

Yeah, it makes sense - I had the same idea but I sorta dropped it after I figured it would make a bit more sense to have the proxy and containers on at least two different servers (for redundancy purposes). Since all the containers are on the same server, you can just specify the IPs in HA proxy as 127.0.0.1 and just change the ports to each container accordingly.

mgl-pub commented 6 years ago

牛掰