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.py296
1 files changed, 148 insertions, 148 deletions
diff --git a/voctogui/lib/videodisplay.py b/voctogui/lib/videodisplay.py
index 744e1aa..9259f6c 100644
--- a/voctogui/lib/videodisplay.py
+++ b/voctogui/lib/videodisplay.py
@@ -5,152 +5,152 @@ from lib.args import Args
from lib.config import Config
from lib.clock import Clock
+
class VideoDisplay(object):
- """ Displays a Voctomix-Video-Stream into a GtkWidget """
-
- def __init__(self, drawing_area, port, width=None, height=None, play_audio=False, level_callback=None):
- self.log = logging.getLogger('VideoDisplay[%u]' % port)
-
- self.drawing_area = drawing_area
- self.level_callback = level_callback
-
- caps = Config.get('mix', 'videocaps')
- use_previews = Config.getboolean('previews', 'enabled') and Config.getboolean('previews', 'use')
-
- # Preview-Ports are Raw-Ports + 1000
- if use_previews:
- self.log.info('using jpeg-previews instead of raw-video for gui')
- port += 1000
- else:
- self.log.info('using raw-video instead of jpeg-previews for gui')
-
- # Setup Server-Connection, Demuxing and Decoding
- pipeline = """
- tcpclientsrc host={host} port={port} blocksize=1048576 !
- queue !
- matroskademux name=demux
- """
-
- if use_previews:
- pipeline += """
- demux. !
- image/jpeg !
- jpegdec !
- {previewcaps} !
- queue !
- """
-
- else:
- pipeline += """
- demux. !
- {vcaps} !
- queue !
- """
-
- # Video Display
- videosystem = Config.get('videodisplay', 'system')
- self.log.debug('Configuring for Video-System %s', videosystem)
- if videosystem == 'gl':
- pipeline += """
- glupload !
- glcolorconvert !
- glimagesinkelement
- """
-
- elif videosystem == 'xv':
- pipeline += """
- xvimagesink
- """
-
- elif videosystem == 'x':
- prescale_caps = 'video/x-raw'
- if width and height:
- prescale_caps += ',width=%u,height=%u' % (width, height)
-
- pipeline += """
- videoconvert !
- videoscale !
- {prescale_caps} !
- ximagesink
- """.format(
- prescale_caps=prescale_caps
- )
-
- else:
- raise Exception('Invalid Videodisplay-System configured: %s' % videosystem)
-
-
-
- # If an Audio-Path is required, add an Audio-Path through a level-Element
- if self.level_callback or play_audio:
- pipeline += """
- demux. !
- {acaps} !
- queue !
- level name=lvl interval=50000000 !
- """
-
- # If Playback is requested, push fo pulseaudio
- if play_audio:
- pipeline += """
- pulsesink
- """
-
- # Otherwise just trash the Audio
- else:
- pipeline += """
- fakesink
- """
-
- pipeline = pipeline.format(
- acaps=Config.get('mix', 'audiocaps'),
- vcaps=Config.get('mix', 'videocaps'),
- previewcaps=Config.get('previews', 'videocaps'),
- host=Args.host if Args.host else Config.get('server', 'host'),
- port=port,
- )
-
- self.log.debug('Creating Display-Pipeline:\n%s', pipeline)
- self.pipeline = Gst.parse_launch(pipeline)
- self.pipeline.use_clock(Clock)
-
- 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()
- bus.enable_sync_message_emission()
-
- bus.connect('message::error', self.on_error)
- bus.connect("sync-message::element", self.on_syncmsg)
-
- if self.level_callback:
- bus.connect("message::element", self.on_level)
-
- self.log.debug('Launching Display-Pipeline')
- self.pipeline.set_state(Gst.State.PLAYING)
-
-
- def on_syncmsg(self, bus, msg):
- if msg.get_structure().get_name() == "prepare-window-handle":
- self.log.info('Setting imagesink window-handle to %s', self.xid)
- msg.src.set_window_handle(self.xid)
-
- 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(self, bus, msg):
- if msg.src.name != 'lvl':
- return
-
- if msg.type != Gst.MessageType.ELEMENT:
- return
-
- rms = msg.get_structure().get_value('rms')
- peak = msg.get_structure().get_value('peak')
- decay = msg.get_structure().get_value('decay')
- self.level_callback(rms, peak, decay)
+ """Displays a Voctomix-Video-Stream into a GtkWidget"""
+
+ def __init__(self, drawing_area, port, width=None, height=None,
+ play_audio=False, level_callback=None):
+ self.log = logging.getLogger('VideoDisplay[%u]' % port)
+
+ self.drawing_area = drawing_area
+ self.level_callback = level_callback
+
+ caps = Config.get('mix', 'videocaps')
+ use_previews = (Config.getboolean('previews', 'enabled') and
+ Config.getboolean('previews', 'use'))
+
+ # Preview-Ports are Raw-Ports + 1000
+ if use_previews:
+ self.log.info('using jpeg-previews instead of raw-video for gui')
+ port += 1000
+ else:
+ self.log.info('using raw-video instead of jpeg-previews for gui')
+
+ # Setup Server-Connection, Demuxing and Decoding
+ pipeline = """
+ tcpclientsrc host={host} port={port} blocksize=1048576 !
+ queue !
+ matroskademux name=demux
+ """
+
+ if use_previews:
+ pipeline += """
+ demux. !
+ image/jpeg !
+ jpegdec !
+ {previewcaps} !
+ queue !
+ """
+
+ else:
+ pipeline += """
+ demux. !
+ {vcaps} !
+ queue !
+ """
+
+ # Video Display
+ videosystem = Config.get('videodisplay', 'system')
+ self.log.debug('Configuring for Video-System %s', videosystem)
+ if videosystem == 'gl':
+ pipeline += """
+ glupload !
+ glcolorconvert !
+ glimagesinkelement
+ """
+
+ elif videosystem == 'xv':
+ pipeline += """
+ xvimagesink
+ """
+
+ elif videosystem == 'x':
+ prescale_caps = 'video/x-raw'
+ if width and height:
+ prescale_caps += ',width=%u,height=%u' % (width, height)
+
+ pipeline += """
+ videoconvert !
+ videoscale !
+ {prescale_caps} !
+ ximagesink
+ """.format(prescale_caps=prescale_caps)
+
+ else:
+ raise Exception(
+ 'Invalid Videodisplay-System configured: %s' % videosystem
+ )
+
+ # If an Audio-Path is required,
+ # add an Audio-Path through a level-Element
+ if self.level_callback or play_audio:
+ pipeline += """
+ demux. !
+ {acaps} !
+ queue !
+ level name=lvl interval=50000000 !
+ """
+
+ # If Playback is requested, push fo pulseaudio
+ if play_audio:
+ pipeline += """
+ pulsesink
+ """
+
+ # Otherwise just trash the Audio
+ else:
+ pipeline += """
+ fakesink
+ """
+
+ pipeline = pipeline.format(
+ acaps=Config.get('mix', 'audiocaps'),
+ vcaps=Config.get('mix', 'videocaps'),
+ previewcaps=Config.get('previews', 'videocaps'),
+ host=Args.host if Args.host else Config.get('server', 'host'),
+ port=port,
+ )
+
+ self.log.debug('Creating Display-Pipeline:\n%s', pipeline)
+ self.pipeline = Gst.parse_launch(pipeline)
+ self.pipeline.use_clock(Clock)
+
+ 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()
+ bus.enable_sync_message_emission()
+
+ bus.connect('message::error', self.on_error)
+ bus.connect("sync-message::element", self.on_syncmsg)
+
+ if self.level_callback:
+ bus.connect("message::element", self.on_level)
+
+ self.log.debug('Launching Display-Pipeline')
+ self.pipeline.set_state(Gst.State.PLAYING)
+
+ def on_syncmsg(self, bus, msg):
+ if msg.get_structure().get_name() == "prepare-window-handle":
+ self.log.info('Setting imagesink window-handle to %s', self.xid)
+ msg.src.set_window_handle(self.xid)
+
+ 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(self, bus, msg):
+ if msg.src.name != 'lvl':
+ return
+
+ if msg.type != Gst.MessageType.ELEMENT:
+ return
+
+ rms = msg.get_structure().get_value('rms')
+ peak = msg.get_structure().get_value('peak')
+ decay = msg.get_structure().get_value('decay')
+ self.level_callback(rms, peak, decay)