|
@ -2,6 +2,7 @@ import os |
|
|
import sys |
|
|
import sys |
|
|
|
|
|
|
|
|
from threading import Thread |
|
|
from threading import Thread |
|
|
|
|
|
from queue import Queue |
|
|
|
|
|
|
|
|
import socketio |
|
|
import socketio |
|
|
|
|
|
|
|
@ -25,13 +26,30 @@ webrtcbin name=sendrecv bundle-policy=max-bundle stun-server=stun://stun.l.googl |
|
|
queue ! application/x-rtp,media=audio,encoding-name=OPUS,payload=96 ! sendrecv. |
|
|
queue ! application/x-rtp,media=audio,encoding-name=OPUS,payload=96 ! sendrecv. |
|
|
''' |
|
|
''' |
|
|
|
|
|
|
|
|
|
|
|
#PIPELINE_DESC = ''' |
|
|
|
|
|
#webrtcbin name=webrtcbin stun-server=stun://stun://stun.l.google.com:19302 |
|
|
|
|
|
#rpicamsrc bitrate=600000 annotation-mode=12 preview=false ! video/x-h264,profile=constrained-baseline,width=640,height=360,level=3.0 ! queue max-size-time=100000000 ! h264parse ! |
|
|
|
|
|
#rtph264pay config-interval=-1 name=payloader ! |
|
|
|
|
|
#application/x-rtp,media=video,encoding-name=H264,payload=96 ! sendrecv. |
|
|
|
|
|
#''' |
|
|
|
|
|
|
|
|
|
|
|
#PIPELINE_DESC = ''' |
|
|
|
|
|
#v4l2src ! queue ! vp8enc ! rtpvp8pay ! |
|
|
|
|
|
# application/x-rtp,media=video,encoding-name=VP8,payload=96 ! |
|
|
|
|
|
# webrtcbin name=sendrecv |
|
|
|
|
|
#''' |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class WebRTCCamera(Thread): |
|
|
class WebRTCCamera(Thread): |
|
|
def __init__(self): |
|
|
def __init__(self): |
|
|
self.pipe = None |
|
|
self.pipe = None |
|
|
self.webrtc = None |
|
|
self.webrtc = None |
|
|
self.server = 'ws://localhost:5000' |
|
|
self.sid = None |
|
|
|
|
|
self.current_client_sid = None |
|
|
|
|
|
self.num_clients = 0 |
|
|
self.connected = False |
|
|
self.connected = False |
|
|
self.exitFlag = False |
|
|
self.server = 'ws://localhost:5000' |
|
|
|
|
|
self._queue = Queue(maxsize=10) |
|
|
|
|
|
|
|
|
Thread.__init__(self) |
|
|
Thread.__init__(self) |
|
|
|
|
|
|
|
@ -40,30 +58,52 @@ class WebRTCCamera(Thread): |
|
|
sys.exit(1) |
|
|
sys.exit(1) |
|
|
|
|
|
|
|
|
def run(self): |
|
|
def run(self): |
|
|
|
|
|
print("Starting WebRTCCamera background thread") |
|
|
self.connect() |
|
|
self.connect() |
|
|
while not self.exitFlag: |
|
|
|
|
|
sio.sleep(1) |
|
|
while True: |
|
|
|
|
|
item = self._queue.get() |
|
|
|
|
|
if item['job'] == "connect_client": |
|
|
|
|
|
self.current_client_sid = item['sid'] |
|
|
|
|
|
self.start_pipeline(item['sid']) |
|
|
|
|
|
self.num_clients += 1 |
|
|
|
|
|
elif item['job'] == "disconnect_client": |
|
|
|
|
|
self.current_client_sid = item['sid'] |
|
|
|
|
|
self.close_pipeline(item['sid']) |
|
|
|
|
|
self.num_clients -= 1 |
|
|
|
|
|
else: |
|
|
|
|
|
print("unknown job: %s" % item['job']) |
|
|
|
|
|
self._queue.task_done() |
|
|
|
|
|
|
|
|
|
|
|
self.disconnect() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def connect(self): |
|
|
def connect(self): |
|
|
sio.connect(self.server, namespaces=['/webrtc'], transports=['websocket']) |
|
|
sio.connect(self.server, namespaces=['/webrtc'], transports=['websocket']) |
|
|
print('my sid is', sio.sid) |
|
|
print('my sid is', sio.sid) |
|
|
sio.emit('message', 'starting camera', namespace='/webrtc') |
|
|
self.sid = sio.sid |
|
|
self.start_pipeline() |
|
|
|
|
|
self.connected = True |
|
|
self.connected = True |
|
|
|
|
|
|
|
|
def disconnect(self): |
|
|
def disconnect(self): |
|
|
self.connected = False |
|
|
self.connected = False |
|
|
self.close_pipeline() |
|
|
|
|
|
sio.disconnect() |
|
|
sio.disconnect() |
|
|
|
|
|
|
|
|
def start_pipeline(self): # ok |
|
|
def connect_client(self, sid): |
|
|
|
|
|
if not self.is_alive(): |
|
|
|
|
|
self.start() |
|
|
|
|
|
self._queue.put({'job':'connect_client', 'sid':sid}) |
|
|
|
|
|
|
|
|
|
|
|
def disconnect_client(self, sid): |
|
|
|
|
|
self._queue.put({'job':'disconnect_client', 'sid':sid}) |
|
|
|
|
|
|
|
|
|
|
|
def start_pipeline(self, client_sid): # ok |
|
|
self.pipe = Gst.parse_launch(PIPELINE_DESC) |
|
|
self.pipe = Gst.parse_launch(PIPELINE_DESC) |
|
|
self.webrtc = self.pipe.get_by_name('sendrecv') |
|
|
self.webrtc = self.pipe.get_by_name('sendrecv') |
|
|
self.webrtc.connect('on-negotiation-needed', self.on_negotiation_needed) |
|
|
self.webrtc.connect('on-negotiation-needed', self.on_negotiation_needed) |
|
|
self.webrtc.connect('on-ice-candidate', self.on_ice_candidate) |
|
|
self.webrtc.connect('on-ice-candidate', self.on_ice_candidate) |
|
|
self.pipe.set_state(Gst.State.PLAYING) |
|
|
self.pipe.set_state(Gst.State.PLAYING) |
|
|
|
|
|
|
|
|
def close_pipeline(self): |
|
|
def close_pipeline(self, client_sid): |
|
|
self.pipe.set_state(Gst.State.NULL) |
|
|
self.pipe.set_state(Gst.State.NULL) |
|
|
self.pipe = None |
|
|
self.pipe = None |
|
|
self.webrtc = None |
|
|
self.webrtc = None |
|
|