diff options
Diffstat (limited to 'voctogui/lib/videodisplay.py')
-rw-r--r-- | voctogui/lib/videodisplay.py | 79 |
1 files changed, 40 insertions, 39 deletions
diff --git a/voctogui/lib/videodisplay.py b/voctogui/lib/videodisplay.py index 42724ac..00648ef 100644 --- a/voctogui/lib/videodisplay.py +++ b/voctogui/lib/videodisplay.py @@ -1,52 +1,65 @@ import logging -from gi.repository import Gst, Gtk +from gi.repository import Gst class VideoDisplay: """ Displays a Voctomix-Video-Stream into a GtkWidget """ - def __init__(self, port, videowidget, audiolevelwidget=None, playaudio=False, allowoverlay=False): - self.log = logging.getLogger('VideoDisplay[%u]' % port) + def __init__(self, drawing_area, port, play_audio=False, draw_callback=None, level_callback=None): + self.log = logging.getLogger('VideoDisplay[%s]' % drawing_area.get_name()) + self.drawing_area = drawing_area + self.draw_callback = draw_callback + self.level_callback = level_callback + + # Setup Server-Connection, Demuxing and Decoding pipeline = """ videotestsrc ! timeoverlay ! - video/x-raw,width=1920,height=1080 ! + video/x-raw,width=1920,height=1080,framerate=25/1 ! """.format( port=port ) - if allowoverlay: + + # If an overlay is required, add an cairooverlay-Element into the Video-Path + if self.draw_callback: pipeline += """ videoconvert ! cairooverlay name=overlay ! videoconvert ! """ + # Video Display pipeline += """ xvimagesink name=v """ - if audiolevelwidget or playaudio: + + # If an Audio-Path is required, add an Audio-Path through a level-Element + if self.level_callback or play_audio: pipeline += """ audiotestsrc wave=blue-noise ! audio/x-raw ! level name=lvl interval=50000000 ! """ - if playaudio: + # If Playback is requested, push fo alsa + if play_audio: pipeline += """ alsasink """ + + # Otherwise just trash the Audio else: pipeline += """ fakesink """ - self.log.info('launching gstreamer-pipeline for widget %s "%s":\n%s', videowidget.get_name(), Gtk.Buildable.get_name(videowidget), pipeline) - + self.log.debug('Creating Display-Pipeline:\n%s', pipeline) self.pipeline = Gst.parse_launch(pipeline) - videowidget.realize() - self.xid = videowidget.get_property('window').get_xid() + self.drawing_area.realize() + self.xid = self.drawing_area.get_property('window').get_xid() + self.log.debug('Realized Drawing-Area with xid %u', self.xid) bus = self.pipeline.get_bus() bus.add_signal_watch() @@ -55,41 +68,26 @@ class VideoDisplay: bus.connect('message::error', self.on_error) bus.connect("sync-message::element", self.on_syncmsg) - self.draw_callback = None - - if audiolevelwidget: - self.levelrms = [0, 0] - self.audiolevelwidget = audiolevelwidget - self.audiolevelwidget.connect('draw', self.on_level_draw) + if self.level_callback: bus.connect("message::element", self.on_level) - def run(self): + if self.draw_callback: + self.pipeline.get_by_name('overlay').connect('draw', self.on_draw) + + self.log.debug('Launching Display-Pipeline') self.pipeline.set_state(Gst.State.PLAYING) - def set_overlay_callback(self, callback): - if callback: - if not self.draw_callback: - self.draw_callback = self.pipeline.get_by_name('overlay').connect('draw', callback) - else: - print('disconnect') - self.pipeline.get_by_name('overlay').disconnect(self.draw_callback) - self.draw_callback = None def on_syncmsg(self, bus, msg): if msg.get_structure().get_name() == "prepare-window-handle": - self.log.info('setting xvimagesink window-handle to %s', self.xid) + self.log.info('Setting xvimagesink window-handle to %s', self.xid) msg.src.set_window_handle(self.xid) - def on_error(self, bus, msg): - self.log.error('on_error(): %s', msg.parse_error()) + def on_error(self, bus, message): + self.log.debug('Received Error-Signal on Display-Pipeline') + (error, debug) = message.parse_error() + self.log.debug('Error-Details: #%u: %s', error.code, debug) - def on_level_draw(self, widget, cr): - cr.set_source_rgb(1, 1, 1) - cr.set_line_width(10) - - cr.move_to(15, 0) - cr.line_to(15, self.levelrms[0]*-20) - cr.stroke() def on_level(self, bus, msg): if msg.src.name != 'lvl': @@ -98,6 +96,9 @@ class VideoDisplay: if msg.type != Gst.MessageType.ELEMENT: return - self.levelpeaks = msg.get_structure().get_value('peak') - self.levelrms = msg.get_structure().get_value('rms') - self.audiolevelwidget.queue_draw() + peaks = msg.get_structure().get_value('peak') + rms = msg.get_structure().get_value('rms') + self.level_callback(peaks, rms) + + def on_draw(self, cairooverlay, cr, timestamp, duration): + self.draw_callback(cr, timestamp, duration) |