bbc / brave

Basic Real-time AV Editor - allowing you to preview, mix, and route live audio and video streams on the cloud
Apache License 2.0
653 stars 148 forks source link

webrtc previews not working #43

Closed SriramScorp closed 4 years ago

SriramScorp commented 5 years ago

I used the Dockerfile to build a docker image and deployed an instance. While everything works fine, the webrtc previews in the web interface fails with the error "ERROR: Failed to connect WebRTC with server". The browser console states "New ICE connection state: failed".

With LOG_LEVEL=DEBUG, I get the below logs in the console.

DEBUG: [ output1] Creating with pipeline: intervideosrc name=intervideosrc timeout=86400000000000 ! videoconvert ! videoscale ! videorate ! capsfilter name=capsfilter ! vp8enc deadline=1 keyframe-max-dist=30 ! rtpvp8pay ! application/x-rtp,format=RGB,media=video,encoding-name=VP8,payload=97,width=480,height=270 ! tee name=webrtc_video_tee webrtc_video_tee. ! fakesink interaudiosrc name=interaudiosrc ! audioconvert ! level message=true ! audioresample name=webrtc-audioresample ! opusenc bandwidth=superwideband ! rtpopuspay ! application/x-rtp,media=audio,encoding-name=OPUS,payload=96 ! tee name=webrtc_audio_tee webrtc_audio_tee. ! fakesink DEBUG: [ input1] Pipeline state change from PAUSED to PAUSED (pending PAUSED) DEBUG: [ input1] Message from GStreamer: Latency from output1_interaudiosink_857589 DEBUG: [ output1] Move to state READY complete INFO: [api_routes] Created output #1 with details {'type': 'webrtc', 'source': 'input1'} DEBUG: [ output1] Pipeline state change from NULL to READY DEBUG: [ output1] Move to state PAUSED has completed but no data yet DEBUG: [ input1] Pipeline state change from PAUSED to PAUSED (pending PLAYING) DEBUG: [ input1] Pipeline state change from PAUSED to PLAYING DEBUG: [ output1] Pipeline state change from READY to PAUSED DEBUG: [ output1] Move to state PLAYING is IN PROGRESS DEBUG: [ output1] Message from GStreamer: Latency from opusenc0 DEBUG: [ output1] Message from GStreamer: Latency from vp8enc0 DEBUG: [ output1] Pipeline state change from PAUSED to PLAYING INFO: [ output1] I now have 1 peers DEBUG: [ output1] Property notify: object="webrtcbin0", property_name="stun-server", property_value="stun://stun.l.google.com:19302" DEBUG: [ output1] Pipeline state change from PLAYING to PAUSED (pending READY) DEBUG: [ output1] Pipeline state change from PAUSED to READY DEBUG: [ output1] Pipeline state change from READY to PAUSED (pending PLAYING) DEBUG: [ output1] Successfully added a new peer request DEBUG: [ output1] Message from GStreamer: Latency from opusenc0 DEBUG: [ output1] Message from GStreamer: Latency from vp8enc0 DEBUG: [ output1] Pipeline state change from PAUSED to PLAYING DEBUG: [ output1] Sending SDP offer to client (1204 chars in length) DEBUG: [ output1] Property notify: object="webrtcbin0", property_name="signaling-state", property_value="enum GST_WEBRTC_SIGNALING_STATE_HAVE_LOCAL_OFFER of type GstWebRTC.WebRTCSignalingState" DEBUG: [ output1] Property notify: object="webrtcbin0", property_name="ice-gathering-state", property_value="enum GST_WEBRTC_ICE_GATHERING_STATE_COMPLETE of type GstWebRTC.WebRTCICEGatheringState" DEBUG: [ output1] Property notify: object="webrtcbin0", property_name="signaling-state", property_value="enum GST_WEBRTC_SIGNALING_STATE_STABLE of type GstWebRTC.WebRTCSignalingState" DEBUG: [ output1] Property notify: object="webrtcbin0", property_name="ice-connection-state", property_value="enum GST_WEBRTC_ICE_CONNECTION_STATE_CHECKING of type GstWebRTC.WebRTCICEConnectionState" DEBUG: [ output1] Property notify: object="webrtcbin0", property_name="connection-state", property_value="enum GST_WEBRTC_PEER_CONNECTION_STATE_CONNECTING of type GstWebRTC.WebRTCPeerConnectionState" DEBUG: [ output1] Property notify: object="webrtcbin0", property_name="ice-connection-state", property_value="enum GST_WEBRTC_ICE_CONNECTION_STATE_FAILED of type GstWebRTC.WebRTCICEConnectionState" DEBUG: [ output1] Property notify: object="webrtcbin0", property_name="connection-state", property_value="enum GST_WEBRTC_PEER_CONNECTION_STATE_FAILED of type GstWebRTC.WebRTCPeerConnectionState" DEBUG: [ output1] In PLAYING state: pipeline, queue9, queue8, webrtcbin0, capsfilter8, capsfilter7, fakesink3, webrtc_audio_tee, rtpopuspay0, opusenc0, webrtc-audioresample, level0, audioconvert1, interaudiosrc, fakesink2, webrtc_video_tee, rtpvp8pay0, vp8enc0, capsfilter, videorate0, videoscale2, videoconvert2, intervideosrc

Enabling more verbose logging spits out too much gibberish that I can't make sense of. How do I make the webrtc previews work?

matthew1000 commented 5 years ago

Hmmm... that log output all looks fine. So Brave is running correctly, but the browser is unable to connect.

1) Is your docker image running on the same server as your web browser? 2) What browser are you using? 3) If Chrome, are there any obvious error messages at chrome://webrtc-internals/ ?

SriramScorp commented 5 years ago

I have edited my post. Some of the log info got mistaken for code blocks. BTW, answering your queries

  1. The docker instance is not on the same server as my browser
  2. I initially used Chrome before trying Firefox. However, the browser console of Firefox suggested I add a turn server.
  3. chrome://webrtc-internals reports 'iceconnectionstatechange' failed.
matthew1000 commented 5 years ago

OK, so it sounds like neither the Docker image nor your local machine can find a public port from which a WebRTC connection can be instantiated.

A Turn server would definitely fix this, and Brave can be configured to use one through a command-line variable, e.g. export TURN_SERVER=username:password@my-turn-server.com:12345. But you'd need to set up an Turn server for that.

Alternatively, I'm not a Docker expert, is it possible to open up more ports for access?

lucasdavila86 commented 5 years ago

Alternatively, I'm not a Docker expert, is it possible to open up more ports for access?

It's posible to EXPOSE more ports. I'm not familiarized with webRTC, is brave listening on a specific port for webRTC? Or does brave open a conection to the webclient?

matthew1000 commented 5 years ago

OK, I’ve managed to recreate this. It’s definitely due to Docker not exposing ports that the STUN protocol will then use to find a method of connecting client and server. AFAIK it’s not possible to influence which ports STUN will use.

Exposing a wide range of ports, e.g. EXPOSED: 30000-65000/udp doesn’t fix it as the ports need to be published (see https://medium.freecodecamp.org/expose-vs-publish-docker-port-commands-explained-simply-434593dbc9a3). And publishing that many ports is dreadfully slow and memory-intensive. It appears Docker starts a process for each one. I attempted this and did manage to get it to work. (It’s also what this project does: https://github.com/Piasy/WebRTC-Docker) But it’s not a viable solution.

The only thing I can think of, to get WebRTC working in a Docker container, is to add in a TURN server. It could live inside the container. Both of the TURN servers that Ubuntu has (coturn and resiprocate-turn-server) allow the port range to be limited. If the TURN server was set to use a small range (e.g. 50000-50100), then we could easily configure the Dockerfile to expose just that.

lucasdavila86 commented 5 years ago

Could be better to run the TURN server on another container? In this way the docker image will be leaner

SriramScorp commented 5 years ago

I added a turn server (coturn) to the brave docker container. However, I can only restrict the ports used by the turn server and not those used by brave. While running brave with the TURN_SERVER environment variable, though the ports used by the turn server fall within the configured range, brave listens on random ports (as confirmed by netstat), most of which aren't published. Hence, the webrtc previews fails most of the time.

netstat of coturn (configured port range 50000-50100)

udp 0 0 172.17.0.2:50004 0.0.0.0: 740/turnserver udp 0 0 172.17.0.2:50019 0.0.0.0: 740/turnserver udp 0 0 172.17.0.2:50086 0.0.0.0: 740/turnserver udp 0 0 172.17.0.2:50094 0.0.0.0: 740/turnserver

netstat of brave (published ports 51000-52000)

tcp 0 0 172.17.0.2:34697 0.0.0.0: LISTEN 1/python3 tcp 0 0 172.17.0.2:47754 0.0.0.0: LISTEN 1/python3 tcp 0 0 172.17.0.2:56557 0.0.0.0: LISTEN 1/python3 tcp 0 0 172.17.0.2:45752 0.0.0.0: LISTEN 1/python3 udp 0 0 172.17.0.2:53833 0.0.0.0: 1/python3 udp 0 0 172.17.0.2:41615 0.0.0.0: 1/python3 udp 0 0 172.17.0.2:37670 0.0.0.0: 1/python3 udp 0 0 239.255.255.250:1900 0.0.0.0: 1/python3 udp 0 0 172.17.0.2:1900 0.0.0.0: 1/python3 udp 0 0 239.255.255.250:1900 0.0.0.0: 1/python3 udp 0 0 127.0.0.1:1900 0.0.0.0: 1/python3 udp 0 0 172.17.0.2:36861 0.0.0.0: 1/python3 udp 0 0 127.0.0.1:45488 0.0.0.0: 1/python3 udp 0 0 172.17.0.2:47573 0.0.0.0: 1/python3`

Is there a way to restrict the ports brave uses for webrtc?

moschopsuk commented 5 years ago

Sorry for the delay in getting back to you @SriramScorp

This seems to be a limitation with the webrtcbin element, there is an issue raised and an MR but it has yet to be merged in.

https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/issues/856

moschopsuk commented 4 years ago

I'm going to close this please feel free to reopen should the changes be merged into gstreamer plug-ins.