Kevin
Kevin

Reputation: 3239

How does "on-negotiation-needed" work when trying to stream using gstreamer webrtc?

How does the webrtc pipeline get any information about its peers?

This is what I assume what the on_negotiation_needed callback does?

def start_pipeline(self):
        self.pipe = Gst.parse_launch(PIPELINE_DESC)
        self.webrtc = self.pipe.get_by_name('sendrecv')
        **self.webrtc.connect('on-negotiation-needed', self.on_negotiation_needed)**
        self.webrtc.connect('on-ice-candidate', self.send_ice_candidate_message)
        self.webrtc.connect('pad-added', self.on_incoming_stream)
        self.pipe.set_state(Gst.State.PLAYING)

I see that it has the on_negotiation_needed callback but its unclear where the element variable comes from? I looked here: http://blog.nirbheek.in/2018/02/gstreamer-webrtc.html and here: https://github.com/centricular/gstwebrtc-demos and I am still confused as to how this negotiation works? From what I understand there are 2 (or more) peers and both of them must connect to the signaling server, then one of them has to create an offer.

I await for the message from (I assume) the gstreamer webrtcbin on the signaling server:

print (websocket.remote_address)
#get message from client
message = await asyncio.wait_for(websocket.recv(), 3000)

and I get this error when the pipline starts:

('192.168.11.138', 44120)
Error in connection handler
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/websockets/protocol.py", line 674, in transfer_data
    message = yield from self.read_message()
  File "/usr/local/lib/python3.6/dist-packages/websockets/protocol.py", line 742, in read_message
    frame = yield from self.read_data_frame(max_size=self.max_size)
  File "/usr/local/lib/python3.6/dist-packages/websockets/protocol.py", line 815, in read_data_frame
    frame = yield from self.read_frame(max_size)
  File "/usr/local/lib/python3.6/dist-packages/websockets/protocol.py", line 884, in read_frame
    extensions=self.extensions,
  File "/usr/local/lib/python3.6/dist-packages/websockets/framing.py", line 99, in read
    data = yield from reader(2)
  File "/usr/lib/python3.6/asyncio/streams.py", line 672, in readexactly
    raise IncompleteReadError(incomplete, n)
asyncio.streams.IncompleteReadError: 0 bytes read on a total of 2 expected bytes

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/websockets/server.py", line 169, in handler
    yield from self.ws_handler(self, path)
  File "signaling_server.py", line 34, in signaling
    message = await asyncio.wait_for(websocket.recv(), 3000)
  File "/usr/lib/python3.6/asyncio/tasks.py", line 358, in wait_for
    return fut.result()
  File "/usr/local/lib/python3.6/dist-packages/websockets/protocol.py", line 434, in recv
    yield from self.ensure_open()
  File "/usr/local/lib/python3.6/dist-packages/websockets/protocol.py", line 646, in ensure_open
    ) from self.transfer_data_exc
websockets.exceptions.ConnectionClosed: WebSocket connection is closed: code = 1006 (connection closed abnormally [internal]), no reason

Upvotes: 1

Views: 1488

Answers (1)

user3188639
user3188639

Reputation:

I cannot say about Python (unfortunately, cannot make Python bindings for GStreamer work on Windows), however, demo works from C# (I just checked).

First you should connect with your browser to https://webrtc.nirbheek.in/, and get the 'Our id' value.

Your Python Gstreamer should connect to wss://webrtc.nirbheek.in:8443, and use the Id value from the browser.

The browser will get the test image stream from the GStreamer, and the GStreamer application will get the Webcam image from the browser.

HTH, Tom

Here's a screenshot:

enter image description here

Upvotes: 1

Related Questions