diff options
-rw-r--r-- | voctocore/controlserver.py | 43 | ||||
-rw-r--r-- | voctocore/videomix.py | 77 |
2 files changed, 91 insertions, 29 deletions
diff --git a/voctocore/controlserver.py b/voctocore/controlserver.py index da27408..beaa565 100644 --- a/voctocore/controlserver.py +++ b/voctocore/controlserver.py @@ -1,6 +1,11 @@ import socket, threading, queue from gi.repository import GObject +def controlServerEntrypoint(f): + # mark the method as something that requires view's class + f.is_control_server_entrypoint = True + return f + class ControlServer(): def __init__(self, videomix): '''Initialize server and start listening.''' @@ -10,12 +15,16 @@ class ControlServer(): sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.bind(('0.0.0.0', 23000)) sock.listen(1) + + # register socket for callback inside the GTK-Mainloop GObject.io_add_watch(sock, GObject.IO_IN, self.listener) def listener(self, sock, *args): '''Asynchronous connection listener. Starts a handler for each connection.''' conn, addr = sock.accept() - print("Connected") + print("Connection from ", addr) + + # register data-received handler inside the GTK-Mainloop GObject.io_add_watch(conn, GObject.IO_IN, self.handler) return True @@ -25,9 +34,31 @@ class ControlServer(): if not len(line): print("Connection closed.") return False - - livevideo = self.videomix.pipeline.get_by_name('livevideo') - pad = livevideo.get_static_pad('sink_1') - pad.set_property('alpha', 00) - print(line) + + r = self.processLine(line.decode('utf-8')) + if isinstance(r, str): + conn.send((r+'\n').encode('utf-8')) + return False + + conn.send('OK\n'.encode('utf-8')) return True + + + + + def processLine(self, line): + command, argstring = (line+' ').split(' ', 1) + args = argstring.strip().split(' ') + print(command, args) + + if not hasattr(self.videomix, command): + return 'unknown command {}'.format(command) + + f = getattr(self.videomix, command) + if not hasattr(f, 'is_control_server_entrypoint'): + return 'method {} not callable from controlserver'.format(command) + + try: + return f(*args) + except Exception as e: + return str(e) diff --git a/voctocore/videomix.py b/voctocore/videomix.py index 2574a8d..7674cae 100644 --- a/voctocore/videomix.py +++ b/voctocore/videomix.py @@ -1,6 +1,7 @@ import sys, inspect, math from pprint import pprint from gi.repository import GLib, Gst +from controlserver import controlServerEntrypoint class Videomix: # size of the monitor-streams @@ -214,12 +215,15 @@ class Videomix: ### below are access-methods for the ControlServer - # return number of available audio sources - def numAudioSources(): + @controlServerEntrypoint + def numAudioSources(self): + """ return number of available audio sources """ pass - # switch audio to the selected audio - def switchAudio(audiosrc): + + @controlServerEntrypoint + def switchAudio(self, audiosrc): + """ switch audio to the selected audio """ liveaudio = self.pipeline.get_by_name('liveaudio') pad = liveaudio.get_static_pad('sink_{}'.format(audiosrc)) if pad is None: @@ -229,43 +233,70 @@ class Videomix: return True - # return number of available video sources - def numVideoSources(): + @controlServerEntrypoint + def numVideoSources(self): + """ return number of available video sources """ pass - # switch audio to the selected video - def switchVideo(videosrc): + + @controlServerEntrypoint + def switchVideo(self, videosrc): + """ switch audio to the selected video """ livevideo = self.pipeline.get_by_name('livevideo') pad = livevideo.get_static_pad('sink_{}'.format(videosrc)) # TODO set other videos to alpha = 0 - pad.set_property('alpha', 1) + pad.set_property('alpha', 0.5) - # fade video to the selected video - def fadeVideo(videosrc): + + @controlServerEntrypoint + def fadeVideo(self, videosrc): + """ fade video to the selected video """ pass - # switch video-source in the PIP to the selected video - def setPipVideo(videosrc): + @controlServerEntrypoint + def setPipVideo(self, videosrc): + """ switch video-source in the PIP to the selected video """ pass - # fade video-source in the PIP to the selected video - def fadePipVideo(videosrc): + + @controlServerEntrypoint + def fadePipVideo(self, videosrc): + """ fade video-source in the PIP to the selected video """ pass - # enumeration of possible PIP-Placements - class PipPlacements(): + + class PipPlacements: + """ enumeration of possible PIP-Placements """ TopLeft, TopRight, BottomLeft, BottomRight = range(4) - # place PIP in the selected position - def setPipPlacement(placement): + + @controlServerEntrypoint + def setPipPlacement(self, placement): + """ place PIP in the selected position """ assert(isinstance(placement, PipPlacements)) pass - # show or hide PIP - def setPipStatus(enabled): + + @controlServerEntrypoint + def setPipStatus(self, enabled): + """ show or hide PIP """ pass - # fade PIP in our out - def fadePipStatus(enabled): + + @controlServerEntrypoint + def fadePipStatus(self, enabled): + """ fade PIP in our out """ + pass + + + class StreamContents: + """ enumeration of possible PIP-Placements """ + Live, Pause, NoStream = range(3) + + + @controlServerEntrypoint + def selectStreamContent(self, content): + """ switch the livestream-content between selected mixer output, pause-image or nostream-image""" + assert(isinstance(content, StreamContents)) pass |