# Copyright (c) 2016 David Testé
from os import rename
+from os import listdir
import gi
from gi.repository import Gst
AUDIO_DEFAULT = PATHNAME + 'AUDIO_DEFAULT'
RAWVIDEO_DEFAULT = PATHNAME + 'RAWVIDEO_DEFAULT'
STREAM_DEFAULT = PATHNAME + 'STREAM_DEFAULT'
-WEBCAMUSB_DEFAULT = '/dev/video1'
class New_user_pipeline():
- def __init__(self):
- self.user_pipeline = self.create_gstreamer_pipeline()
-
+ def __init__(self, feed='main'):
+ self.feed = feed
+ if self.feed == 'main':
+ self.user_pipeline = self.create_gstreamer_pipeline()
+ elif self.feed == 'backup':
+ self.user_pipeline = self.create_gstreamer_pipeline(feed='backup')
+
def create_video_sources(self):
"""Create video inputs from various sources."""
self.videosrc = Gst.ElementFactory.make('rtspsrc', 'videosrc')
self.videosrc.set_property('location', 'rtsp://192.168.48.2:554')
self.videosrc.set_property('latency', 0)
-## self.videosrc = Gst.ElementFactory.make('v4l2src', 'videosrc')
-## self.videosrc.set_property('device', '/dev/video1')
+ if self.feed == 'backup':
+ self.videosrc_backup = Gst.ElementFactory.make('v4l2src',
+ 'videosrc_backup')
+ device_location = self.find_webcam_device()
+ print ('[INFO] Webcam device location: ', device_location)
+ self.videosrc_backup.set_property('device', device_location)
+
+ def find_webcam_device(self):
+ """Look out for the USB webcam device."""
+ devices = [dev for dev in listdir('/dev/') if 'video' in dev]
+ for item in devices:
+ # In case of computer having a built-in webcam
+ if item != 'video0' and len(devices) > 1:
+ return '/dev/' + item
+ # Without built-in webcam
+ elif len(devices) == 1:
+ return '/dev/video0'
+ print('[ERROR] No webcam device found.')
- def create_audio_sources(self):
- """Create audio inputs from various sources."""
- self.audiosrc = Gst.ElementFactory.make('pulsesrc', 'audiosrc')
-## self.videosrc.set_property('latency', 0)
-
def create_pipeline_callbacks(self):
"""Callbacks to connect dynamically created pads."""
- self.videosrc.connect("pad-added", self.on_pad_added_to_rtspsrc)
+ self.videosrc.connect('pad-added', self.on_pad_added_to_rtspsrc)
def on_pad_added_to_rtspsrc(self, rtspsrc, pad):
"""Connect the dynamic 'src'pad of an RTSP source."""
sinkpad = self.queuev_1.get_static_pad('sink')
pad.link(sinkpad)
+ def create_audio_sources(self):
+ """Create audio inputs from various sources."""
+ self.audiosrc = Gst.ElementFactory.make('pulsesrc', 'audiosrc')
+## self.videosrc.set_property('latency', 0)
+
def create_audiolevel_plugin(self):
"""Create audio level plugin to feed a vu-meter."""
self.audiolevel = Gst.ElementFactory.make('level', 'audiolevel')
"""Create streamable output elements."""
# To local screen:
self.screensink = Gst.ElementFactory.make('xvimagesink', 'screensink')
+ self.screensink.set_property('sync', False)
# To icecast server:
self.icecastsink_audio = Gst.ElementFactory.make('shout2send', 'icecastsink_audio')
## Configuration should be written on a file locally to keep safe private addresses
caps = Gst.caps_from_string('video/x-raw, width=(int)640, height=(int)360')
self.capsfilter = Gst.ElementFactory.make('capsfilter', 'capsfilter')
self.capsfilter.set_property('caps', caps)
+
+ caps_backup = Gst.caps_from_string('video/x-raw, width=(int)640, height=(int)360')
+ self.capsfilter_backup = Gst.ElementFactory.make('capsfilter', 'capsfilter_backup')
+ self.capsfilter_backup.set_property('caps', caps_backup)
def create_tee_elements(self):
"""Create tee elements to divide feeds."""
print('Pipeline creation state: adding elements... ', end='')
if feed == 'main':
- pass
# Add here the elments associated with the RTSP feed
+ # Inputs elements:
+ self.streampipe.add(self.videosrc)
+ self.streampipe.add(self.audiosrc)
+ # Middle elements:
+ self.streampipe.add(self.audiolevel)
+ self.streampipe.add(self.rtpjpegdepay)
+ self.streampipe.add(self.jpegdec)
+ self.streampipe.add(self.tee_rawvideo)
+ self.streampipe.add(self.mkvmux)
+ self.streampipe.add(self.vorbisenc)
+ self.streampipe.add(self.oggmux)
+ self.streampipe.add(self.scaling)
+ self.streampipe.add(self.capsfilter)
+ self.streampipe.add(self.vp8enc)
+ self.streampipe.add(self.webmmux)
+ self.streampipe.add(self.tee_rawaudio)
+ self.streampipe.add(self.tee_streamaudio)
+ self.streampipe.add(self.tee_videodecoded)
+ self.streampipe.add(self.tee_streamfull)
+ self.streampipe.add(self.queuev_1)
+ self.streampipe.add(self.queuev_2)
+ self.streampipe.add(self.queuev_3)
+ self.streampipe.add(self.queuev_4)
+ self.streampipe.add(self.queuev_5)
+ self.streampipe.add(self.queuev_6)
+ self.streampipe.add(self.queuea_1)
+ self.streampipe.add(self.queuea_2)
+ self.streampipe.add(self.queuea_3)
+ self.streampipe.add(self.queuea_4)
+ self.streampipe.add(self.queuea_5)
+ self.streampipe.add(self.queuem_1)
+ self.streampipe.add(self.queuem_2)
+ # Outputs elements:
+ self.streampipe.add(self.screensink)
+ self.streampipe.add(self.disksink_rawvideo)
+ self.streampipe.add(self.disksink_audio)
+ self.streampipe.add(self.disksink_stream)
+ self.streampipe.add(self.icecastsink_audio)
+ self.streampipe.add(self.icecastsink_stream)
elif feed == 'backup':
- pass
# Add here the elments associated with the WEBCAM feed
-
- # Inputs elements:
- self.streampipe.add(self.videosrc)
- self.streampipe.add(self.audiosrc)
- # Middle elements:
- self.streampipe.add(self.audiolevel)
- self.streampipe.add(self.rtpjpegdepay)
- self.streampipe.add(self.jpegdec)
- self.streampipe.add(self.tee_rawvideo)
- self.streampipe.add(self.mkvmux)
- self.streampipe.add(self.vorbisenc)
- self.streampipe.add(self.oggmux)
- self.streampipe.add(self.scaling)
- self.streampipe.add(self.capsfilter)
- self.streampipe.add(self.vp8enc)
- self.streampipe.add(self.webmmux)
- self.streampipe.add(self.tee_rawaudio)
- self.streampipe.add(self.tee_streamaudio)
- self.streampipe.add(self.tee_videodecoded)
- self.streampipe.add(self.tee_streamfull)
- self.streampipe.add(self.queuev_1)
- self.streampipe.add(self.queuev_2)
- self.streampipe.add(self.queuev_3)
- self.streampipe.add(self.queuev_4)
- self.streampipe.add(self.queuev_5)
- self.streampipe.add(self.queuev_6)
- self.streampipe.add(self.queuea_1)
- self.streampipe.add(self.queuea_2)
- self.streampipe.add(self.queuea_3)
- self.streampipe.add(self.queuea_4)
- self.streampipe.add(self.queuea_5)
- self.streampipe.add(self.queuem_1)
- self.streampipe.add(self.queuem_2)
- # Outputs elements:
- self.streampipe.add(self.screensink)
- self.streampipe.add(self.disksink_rawvideo)
- self.streampipe.add(self.disksink_audio)
- self.streampipe.add(self.disksink_stream)
- self.streampipe.add(self.icecastsink_audio)
- self.streampipe.add(self.icecastsink_stream)
+ self.streampipe.add(self.videosrc_backup)
+ self.streampipe.add(self.capsfilter_backup)
+ self.streampipe.add(self.queuev_1)
+ self.streampipe.add(self.screensink)
+ print ('BACKUP OK...', end='')
print('added')
def link_pipeline_elements(self, feed='main'):
print('Pipeline creation state: linking elements... ', end='')
if feed == 'main':
- pass
# linking here RTSP feed
+ # Video feed:
+ self.queuev_1.link(self.rtpjpegdepay)
+ self.connect_tee(self.tee_rawvideo,
+ self.rtpjpegdepay,
+ self.queuev_2,
+ self.jpegdec,)
+ self.queuev_2.link(self.mkvmux)
+ self.mkvmux.link(self.queuev_4)
+ self.queuev_4.link(self.disksink_rawvideo)
+ self.connect_tee(self.tee_videodecoded,
+ self.jpegdec,
+ self.queuev_3,
+ self.scaling,)
+ self.queuev_3.link(self.screensink)
+ # Audio feed:
+ self.audiosrc.link(self.audiolevel)
+ self.audiolevel.link(self.queuea_1)
+ self.queuea_1.link(self.vorbisenc)
+ self.connect_tee(self.tee_rawaudio,
+ self.vorbisenc,
+ self.queuea_2,
+ self.queuea_5,)
+ self.queuea_2.link(self.oggmux)
+ self.connect_tee(self.tee_streamaudio,
+ self.oggmux,
+ self.queuea_3,
+ self.queuea_4,)
+ self.queuea_3.link(self.disksink_audio)
+ self.queuea_4.link(self.icecastsink_audio)
+ self.queuea_5.link(self.webmmux)
+ # Stream (audio+video) feed:
+ self.scaling.link(self.capsfilter)
+ self.capsfilter.link(self.vp8enc)
+ self.vp8enc.link(self.queuev_6)
+ self.queuev_6.link(self.webmmux)
+ self.connect_tee(self.tee_streamfull,
+ self.webmmux,
+ self.queuem_1,
+ self.queuem_2,)
+ self.queuem_1.link(self.disksink_stream)
+ self.queuem_2.link(self.icecastsink_stream)
elif feed == 'backup':
- pass
# linking here backup feed (WEBCAM)
-
- # Video feed:
- self.queuev_1.link(self.rtpjpegdepay)
- self.connect_tee(self.tee_rawvideo,
- self.rtpjpegdepay,
- self.queuev_2,
- self.jpegdec,)
- self.queuev_2.link(self.mkvmux)
- self.mkvmux.link(self.queuev_4)
- self.queuev_4.link(self.disksink_rawvideo)
- self.connect_tee(self.tee_videodecoded,
- self.jpegdec,
- self.queuev_3,
- self.scaling,)
- self.queuev_3.link(self.screensink)
- # Audio feed:
- self.audiosrc.link(self.audiolevel)
- self.audiolevel.link(self.queuea_1)
- self.queuea_1.link(self.vorbisenc)
- self.connect_tee(self.tee_rawaudio,
- self.vorbisenc,
- self.queuea_2,
- self.queuea_5,)
- self.queuea_2.link(self.oggmux)
- self.connect_tee(self.tee_streamaudio,
- self.oggmux,
- self.queuea_3,
- self.queuea_4,)
- self.queuea_3.link(self.disksink_audio)
- self.queuea_4.link(self.icecastsink_audio)
- self.queuea_5.link(self.webmmux)
- # Stream (audio+video) feed:
- self.scaling.link(self.capsfilter)
- self.capsfilter.link(self.vp8enc)
- self.vp8enc.link(self.queuev_6)
- self.queuev_6.link(self.webmmux)
- self.connect_tee(self.tee_streamfull,
- self.webmmux,
- self.queuem_1,
- self.queuem_2,)
- self.queuem_1.link(self.disksink_stream)
- self.queuem_2.link(self.icecastsink_stream)
+ self.videosrc_backup.link(self.capsfilter_backup)
+ self.capsfilter_backup.link(self.queuev_1)
+ self.queuev_1.link(self.screensink)
+ print('BACKUP OK...', end='')
print('linked')
- def create_gstreamer_pipeline(self):
+ def create_gstreamer_pipeline(self, feed='main'):
# New empty pipeline:
self.streampipe = Gst.Pipeline()
- # Setting-up:
self.create_pipeline_elements()
- self.add_elements_to_pipeline()
- self.link_pipeline_elements()
- self.create_pipeline_callbacks()
+ # Setting-up:
+ if feed == 'main':
+ self.add_elements_to_pipeline()
+ self.link_pipeline_elements()
+ self.create_pipeline_callbacks()
+ elif feed == 'backup':
+ self.add_elements_to_pipeline(feed='backup')
+ self.link_pipeline_elements(feed='backup')
global bus
bus = self.streampipe.get_bus()
print("CREATE HERE A BACKUP PIPELINE")
def on_message(self, bus, message):
+ #
+## print("[MESSAGE]", message.get_structure().get_name()) # [DEBUG]
+ #
t = message.type
if t == Gst.MessageType.EOS:
self.streampipe.set_state(Gst.State.NULL)
- self.stream_button.set_label('Stream')
elif t == Gst.MessageType.ERROR:
err, debug = message.parse_error()
print ("Error: %s" % err, debug)
self.streampipe.set_state(Gst.State.NULL)
- self.create_gstreamer_backup_pipeline()
-
+## self.create_gstreamer_backup_pipeline()
+## return 'ERROR'
+
def stream_play(self):
self.streampipe.set_state(Gst.State.PLAYING)
+ print('[INFO] PLAYING State resquested')
def stream_stop(self):
self.streampipe.set_state(Gst.State.NULL)