Browse Source

resume playback (one client only)

split-pipe
Hendrik Langer 4 years ago
parent
commit
ea764da5be
  1. 4
      README.md
  2. 58
      raspberry/roberto/camera/camera_gstreamer_webrtc.py
  3. 11
      raspberry/roberto/views/websocket/routes.py
  4. 2
      raspberry/roberto/views/websocket/templates/camera.html

4
README.md

@ -38,6 +38,10 @@ Sender (Pi): gst-launch-1.0 -e v4l2src do-timestamp=true ! video/x-h264,width=64
Receiver: gst-launch-1.0 -v udpsrc port=5000 ! gdpdepay ! rtph264depay ! avdec_h264 ! fpsdisplaysink sync=false text-overlay=false
## debugging
export GST_DEBUG=*webrtc*:7
## documentation
https://flask-socketio.readthedocs.io/en/latest/

58
raspberry/roberto/camera/camera_gstreamer_webrtc.py

@ -2,6 +2,7 @@ import os
import sys
from threading import Thread
from queue import Queue
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.
'''
#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):
def __init__(self):
self.pipe = 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.exitFlag = False
self.server = 'ws://localhost:5000'
self._queue = Queue(maxsize=10)
Thread.__init__(self)
@ -40,30 +58,52 @@ class WebRTCCamera(Thread):
sys.exit(1)
def run(self):
print("Starting WebRTCCamera background thread")
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):
sio.connect(self.server, namespaces=['/webrtc'], transports=['websocket'])
print('my sid is', sio.sid)
sio.emit('message', 'starting camera', namespace='/webrtc')
self.start_pipeline()
self.sid = sio.sid
self.connected = True
def disconnect(self):
self.connected = False
self.close_pipeline()
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.webrtc = self.pipe.get_by_name('sendrecv')
self.webrtc.connect('on-negotiation-needed', self.on_negotiation_needed)
self.webrtc.connect('on-ice-candidate', self.on_ice_candidate)
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 = None
self.webrtc = None

11
raspberry/roberto/views/websocket/routes.py

@ -74,18 +74,19 @@ def webrtc_message(data):
def disconnect():
sid = request.sid
print("Received Disconnect message from %s" % sid)
if webrtccamera.connected:
webrtccamera.disconnect()
webrtccamera.disconnect_client(sid)
@socketio.on('connect', namespace='/webrtc')
def connect():
sid = request.sid
print("Received Connect message from %s" % sid)
if not webrtccamera.connected:
webrtccamera.start()
socketio.emit('message', 'test2', namespace='/webrtc')
webrtccamera.connect_client(sid)
@socketio.on_error_default
def default_error_handler(e):
print(request.event["message"]) # "my error event"
print(request.event["args"]) # (data,)
keys = request.keys()
keys.sort()
for key in request:
print('%s: %s' % (key, repr(request[key])))

2
raspberry/roberto/views/websocket/templates/camera.html

@ -10,7 +10,7 @@
<script src="{{ url_for('static', filename='js/jquery.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/bootstrap.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/socket.io.js') }}"></script>
<script type="text/javascript" src="https://webrtc.github.io/adapter/adapter-latest.js"></script><!-- DEBUG REMOVE ME //-->
<!--<script type="text/javascript" src="https://webrtc.github.io/adapter/adapter-latest.js"></script>-->
</head>
<body>

Loading…
Cancel
Save