GRVYDEV / Project-Lightspeed

A self contained OBS -> FTL -> WebRTC live streaming server. Comprised of 3 parts once configured anyone can achieve sub-second OBS to the browser livestreaming
MIT License
3.63k stars 137 forks source link

Can't get Video Stream over network (public domain) #41

Open KartoffelToby opened 3 years ago

KartoffelToby commented 3 years ago

I patch the webrtc with the pr for wss

and add a SSL Cert.

All looks great, Websocket commucation is loaded, but the Video Stream isn't shown.

Used the docker-compose file with my modifed webrtc version.

Yavos commented 3 years ago

I get the same issue with the docker-compose files. No changes made outside of environment variables.

It appears that when using a domain name instead of an ip the communication via websocket doesn't work properly anymore. Resulting in a

lightspeed-webrtc    | InvalidModificationError: invalid SDP type supplied to SetLocalDescription(): unknown

on docker and a

Uncaught (in promise) TypeError: RTCPeerConnection.setRemoteDescription: 'unknown' (value of 'type' member of RTCSessionDescriptionInit) is not a valid value for enumeration RTCSdpType.

in my browser.

This is the relevant part of the message I get with public domain name:

data: "{\"event\":\"offer\",\"data\":{\"type\":\"unknown\",\"sdp\":\"\"}}"

This is the same part on IP:

data: "{\"event\":\"offer\",\"data\":{\"type\":\"offer\",\"sdp\":\"v=0\\r\\no=- 414267429760773870 1624918222 IN IP4 0.0.0.0\\r\\ns=-\\r\\nt=0 0\\r\\na=fingerprint:sha-256 52:70:4C:86:65:31:DC:73:5E:AA:0C:33:C4:08:E3:89:45:05:95:18:F2:4C:17:DB:86:02:A6:C9:D9:B2:07:C7\\r\\na=group:BUNDLE 0 1\\r\\nm=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99 100 101 102 121 127 120 125 107 108 109 127 120 123 118 116\\r\\nc=IN IP4 0.0.0.0\\r\\na=setup:actpass\\r\\na=mid:0\\r\\na=ice-ufrag:LQTWyZIrSiiCFGrh\\r\\na=ice-pwd:SBGwylBSTuhMGzqJVXmxWAnaAEwBncbZ\\r\\na=rtcp-mux\\r\\na=rtcp-rsize\\r\\na=rtpmap:96 vp8/90000\\r\\na=rtcp-fb:96 goog-remb \\r\\na=rtcp-fb:96 ccm fir\\r\\na=rtcp-fb:96 nack \\r\\na=rtcp-fb:96 nack pli\\r\\na=rtcp-fb:96 nack \\r\\na=rtcp-fb:96 nack pli\\r\\na=rtpmap:97 rtx/90000\\r\\na=fmtp:97 apt=96\\r\\na=rtcp-fb:97 nack \\r\\na=rtcp-fb:97 nack pli\\r\\na=rtpmap:98 vp9/90000\\r\\na=fmtp:98 profile-id=0\\r\\na=rtcp-fb:98 goog-remb \\r\\na=rtcp-fb:98 ccm fir\\r\\na=rtcp-fb:98 nack \\r\\na=rtcp-fb:98 nack pli\\r\\na=rtcp-fb:98 nack \\r\\na=rtcp-fb:98 nack pli\\r\\na=rtpmap:99 rtx/90000\\r\\na=fmtp:99 apt=98\\r\\na=rtcp-fb:99 nack \\r\\na=rtcp-fb:99 nack pli\\r\\na=rtpmap:100 vp9/90000\\r\\na=fmtp:100 profile-id=1\\r\\na=rtcp-fb:100 goog-remb \\r\\na=rtcp-fb:100 ccm fir\\r\\na=rtcp-fb:100 nack \\r\\na=rtcp-fb:100 nack pli\\r\\na=rtcp-fb:100 nack \\r\\na=rtcp-fb:100 nack pli\\r\\na=rtpmap:101 rtx/90000\\r\\na=fmtp:101 apt=100\\r\\na=rtcp-fb:101 nack \\r\\na=rtcp-fb:101 nack pli\\r\\na=rtpmap:102 h264/90000\\r\\na=fmtp:102 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f\\r\\na=rtcp-fb:102 goog-remb \\r\\na=rtcp-fb:102 ccm fir\\r\\na=rtcp-fb:102 nack \\r\\na=rtcp-fb:102 nack pli\\r\\na=rtcp-fb:102 nack \\r\\na=rtcp-fb:102 nack pli\\r\\na=rtpmap:121 rtx/90000\\r\\na=fmtp:121 apt=102\\r\\na=rtcp-fb:121 nack \\r\\na=rtcp-fb:121 nack pli\\r\\na=rtpmap:127 h264/90000\\r\\na=fmtp:127 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42001f\\r\\na=rtcp-fb:127 goog-remb \\r\\na=rtcp-fb:127 ccm fir\\r\\na=rtcp-fb:127 nack \\r\\na=rtcp-fb:127 nack pli\\r\\na=rtcp-fb:127 nack \\r\\na=rtcp-fb:127 nack pli\\r\\na=rtpmap:120 rtx/90000\\r\\na=fmtp:120 apt=127\\r\\na=rtcp-fb:120 nack \\r\\na=rtcp-fb:120 nack pli\\r\\na=rtpmap:125 h264/90000\\r\\na=fmtp:125 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f\\r\\na=rtcp-fb:125 goog-remb \\r\\na=rtcp-fb:125 ccm fir\\r\\na=rtcp-fb:125 nack \\r\\na=rtcp-fb:125 nack pli\\r\\na=rtcp-fb:125 nack \\r\\na=rtcp-fb:125 nack pli\\r\\na=rtpmap:107 rtx/90000\\r\\na=fmtp:107 apt=125\\r\\na=rtcp-fb:107 nack \\r\\na=rtcp-fb:107 nack pli\\r\\na=rtpmap:108 h264/90000\\r\\na=fmtp:108 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42e01f\\r\\na=rtcp-fb:108 goog-remb \\r\\na=rtcp-fb:108 ccm fir\\r\\na=rtcp-fb:108 nack \\r\\na=rtcp-fb:108 nack pli\\r\\na=rtcp-fb:108 nack \\r\\na=rtcp-fb:108 nack pli\\r\\na=rtpmap:109 rtx/90000\\r\\na=fmtp:109 apt=108\\r\\na=rtcp-fb:109 nack \\r\\na=rtcp-fb:109 nack pli\\r\\na=rtpmap:127 h264/90000\\r\\na=fmtp:127 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42001f\\r\\na=rtcp-fb:127 goog-remb \\r\\na=rtcp-fb:127 ccm fir\\r\\na=rtcp-fb:127 nack \\r\\na=rtcp-fb:127 nack pli\\r\\na=rtcp-fb:127 nack \\r\\na=rtcp-fb:127 nack pli\\r\\na=rtpmap:120 rtx/90000\\r\\na=fmtp:120 apt=127\\r\\na=rtcp-fb:120 nack \\r\\na=rtcp-fb:120 nack pli\\r\\na=rtpmap:123 h264/90000\\r\\na=fmtp:123 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=640032\\r\\na=rtcp-fb:123 goog-remb \\r\\na=rtcp-fb:123 ccm fir\\r\\na=rtcp-fb:123 nack \\r\\na=rtcp-fb:123 nack pli\\r\\na=rtcp-fb:123 nack \\r\\na=rtcp-fb:123 nack pli\\r\\na=rtpmap:118 rtx/90000\\r\\na=fmtp:118 apt=123\\r\\na=rtcp-fb:118 nack \\r\\na=rtcp-fb:118 nack pli\\r\\na=rtpmap:116 ulpfec/90000\\r\\na=rtcp-fb:116 nack \\r\\na=rtcp-fb:116 nack pli\\r\\na=extmap:1 urn:ietf:params:rtp-hdrext:sdes:mid\\r\\na=extmap:2 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id\\r\\na=extmap:3 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id\\r\\na=ssrc:769024987 cname:pion\\r\\na=ssrc:769024987 msid:pion video\\r\\na=ssrc:769024987 mslabel:pion\\r\\na=ssrc:769024987 label:video\\r\\na=msid:pion video\\r\\na=sendonly\\r\\nm=audio 9 UDP/TLS/RTP/SAVPF 111 9 0 8\\r\\nc=IN IP4 0.0.0.0\\r\\na=setup:actpass\\r\\na=mid:1\\r\\na=ice-ufrag:LQTWyZIrSiiCFGrh\\r\\na=ice-pwd:SBGwylBSTuhMGzqJVXmxWAnaAEwBncbZ\\r\\na=rtcp-mux\\r\\na=rtcp-rsize\\r\\na=rtpmap:111 opus/48000/2\\r\\na=fmtp:111 minptime=10;useinbandfec=1\\r\\na=rtpmap:9 G722/8000\\r\\na=rtpmap:0 PCMU/8000\\r\\na=rtpmap:8 PCMA/8000\\r\\na=extmap:1 urn:ietf:params:rtp-hdrext:sdes:mid\\r\\na=extmap:2 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id\\r\\na=extmap:3 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id\\r\\na=ssrc:2849247153 cname:pion\\r\\na=ssrc:2849247153 msid:pion video\\r\\na=ssrc:2849247153 mslabel:pion\\r\\na=ssrc:2849247153 label:video\\r\\na=msid:pion video\\r\\na=sendonly\\r\\n\"}}"
Yavos commented 3 years ago

I tried skipping through the code and understanding what it does. The error appears to be created in

// Set a NAT IP if one is given
    if *ip != "none" {
        s.SetNAT1To1IPs([]string{*ip}, webrtc.ICECandidateTypeHost)
    }

in createWebrtcApi() when using a domain name instead of an actual IP.

After changing WEBSOCKET_HOST in .env to the actual IP the offer and candidates seem to work properly again. However, this leads to another error with the client apparently trying to access ports which aren't forwarded correctly and a local address (see candidates below) resulting in following log lines:

lightspeed-webrtc    | could not read message: read tcp 172.18.0.4:8080-><PUBLIC_IP>:57819: use of closed network connection
lightspeed-webrtc    | could not read message: read tcp 172.18.0.4:8080-><PUBLIC_IP>:58045: use of closed network connection
lightspeed-webrtc    | could not read message: read tcp 172.18.0.4:8080-><PUBLIC_IP>:58063: use of closed network connection
lightspeed-webrtc    | could not read message: read tcp 172.18.0.4:8080-><PUBLIC_IP>:58074: use of closed network connection
lightspeed-webrtc    | could not read message: read tcp 172.18.0.4:8080-><PUBLIC_IP>:58086: use of closed network connection
lightspeed-webrtc    | could not read message: read tcp 172.18.0.4:8080-><PUBLIC_IP>:58103: use of closed network connection
lightspeed-webrtc    | could not read message: read tcp 172.18.0.4:8080-><PUBLIC_IP>:58113: use of closed network connection
lightspeed-webrtc    | could not read message: read tcp 172.18.0.4:8080-><PUBLIC_IP>:58124: use of closed network connection
lightspeed-webrtc    | could not read message: read tcp 172.18.0.4:8080-><PUBLIC_IP>:64899: use of closed network connection

The candidates appear to be giving local addresses looking like these:

candidate:0 1 UDP 2122187007 94f86248-812d-469e-9fef-0800b6db5ed7.local 52352 typ host
candidate:1 1 UDP 2122252543 22451db4-a7c0-4cab-a0b9-6ab86e17d93d.local 52353 typ host
candidate:2 1 TCP 2105458943 94f86248-812d-469e-9fef-0800b6db5ed7.local 9 typ host tcptype active
candidate:3 1 TCP 2105524479 22451db4-a7c0-4cab-a0b9-6ab86e17d93d.local 9 typ host tcptype active

Here's also console output from the browser:

Connected to websocket SocketContext.jsx:80:14
Offer App.js:83:18
Candidate App.js:101:18
Candidate success 5 App.js:55:14
WebRTC: ICE failed, add a STUN server and see about:webrtc for more details

Everything works fine if WEBSOCKET_HOST is set to the local ip of the machine docker is running on. It's not accessible from outside then, though.

Yavos commented 2 years ago

In case anybody still runs into this problem I was able to workaround it in my case (having a public domain with dynamic dns)

Necessary preparations

The stream is now accessible from outside though http://my.public.domain:8888

Meister1593 commented 2 years ago

Can anyone help me? i can reach stream locally with external ip to my server, but outside - it either unreachable, or completely not reachable. Basically, locally - website loads. On the same network - loads (with stream). Outside of network - either barely loading (quite randomly it loaded but i wouldn't count on that at all) or not loading at all (this is 99% of times). Website loads just fine, play button inacessible from external network. From other side theres zero webrtc requests (viewed through chrome://webrtc-internals) My ISP is not covering me under CGN so it's not issue here either.

I opened all possible ports in firewall and router configuration, so theres no way that it is related to port forwarding (at least not obvious) I use docker compose solution, on Archlinux

GenocideStomper commented 2 years ago
  • port forwarding for 8887, 8888 (TCP)

  • port forwarding for 8080 (TCP) - not sure if necessary

  • port forwarding for 20000-20100 (TCP & UDP) - ports used can be altered in docker-compose.yml <= this is the part I was missing before

I'm running Project-Lightspeed in docker containers, and through trial & error I figured out I had to open the following ports in the firewall in my VPS:

IP-restricted to the streamer:

IP-restricted to the viewers (and possibly the streamer):

I haven't figured out yet how to secure the :8888 site with SSL in an nginx reverse proxy, the configuration in the Ubuntu installer script didn't work for me (touched on in #47).

adammpolak commented 1 year ago

In case anybody still runs into this problem I was able to workaround it in my case (having a public domain with dynamic dns)

Necessary preparations

  • port forwarding for 8887, 8888 (TCP)
  • port forwarding for 8080 (TCP) - not sure if necessary
  • port forwarding for 20000-20100 (TCP & UDP) - ports used can be altered in docker-compose.yml <= this is the part I was missing before
  • figure out your public ip and set WEBSOCKET_HOST in your .env to that public ip (must be changed every time the public ip changes)

The stream is now accessible from outside though http://my.public.domain:8888

@Yavos did you do the port forwarding at the firewall level in a VM, or were these linux commands?

Yavos commented 1 year ago

I did set up the forwarding (and dynamic dns) in my router. (using a non-modified fritz box) Firewall at the system running the docker image must be set to allow these ports as well. I don't remember if I had to do anything about that at all, though.