summaryrefslogtreecommitdiff
path: root/voctogui/lib/videodisplay.py
diff options
context:
space:
mode:
Diffstat (limited to 'voctogui/lib/videodisplay.py')
-rw-r--r--voctogui/lib/videodisplay.py81
1 files changed, 41 insertions, 40 deletions
diff --git a/voctogui/lib/videodisplay.py b/voctogui/lib/videodisplay.py
index 42724ac..a2f7f5a 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:
+class VideoDisplay(object):
""" 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)