aboutsummaryrefslogtreecommitdiff
path: root/voctocore/lib/commands.py
diff options
context:
space:
mode:
Diffstat (limited to 'voctocore/lib/commands.py')
-rw-r--r--voctocore/lib/commands.py414
1 files changed, 209 insertions, 205 deletions
diff --git a/voctocore/lib/commands.py b/voctocore/lib/commands.py
index a5b6ab1..34590b7 100644
--- a/voctocore/lib/commands.py
+++ b/voctocore/lib/commands.py
@@ -6,236 +6,240 @@ from lib.config import Config
from lib.videomix import CompositeModes
from lib.response import NotifyResponse, OkResponse
-def decodeName(items, name_or_id):
- try:
- name_or_id = int(name_or_id)
- if name_or_id < 0 or name_or_id >= len(items):
- raise IndexError("unknown index %d" % name_or_id)
-
- return name_or_id
-
- except ValueError as e:
- try:
- return items.index(name_or_id)
-
- except ValueError as e:
- raise IndexError("unknown name %s" % name_or_id)
-
-def decodeEnumName(enum, name_or_id):
- try:
- name_or_id = int(name_or_id)
- if name_or_id < 0 or name_or_id >= len(enum):
- raise IndexError("unknown index %d" % name_or_id)
-
- return name_or_id
-
- except ValueError as e:
- try:
- return enum[name_or_id]
-
- except KeyError as e:
- raise IndexError("unknown name %s" % name_or_id)
-
-def encodeName(items, id):
- try:
- return items[id]
- except IndexError as e:
- raise IndexError("unknown index %d" % id)
-
-def encodeEnumName(enum, id):
- try:
- return enum(id).name
- except ValueError as e:
- raise IndexError("unknown index %d" % id)
-
-class ControlServerCommands(object):
- def __init__(self, pipeline):
- self.log = logging.getLogger('ControlServerCommands')
-
- self.pipeline = pipeline
- self.sources = Config.getlist('mix', 'sources')
- self.blankerSources = Config.getlist('stream-blanker', 'sources')
-
- # Commands are defined below. Errors are sent to the clients by throwing
- # exceptions, they will be turned into messages outside.
-
- def message(self, *args):
- """sends a message through the control-server, which can be received by
- user-defined scripts. does not change the state of the voctocore."""
- return NotifyResponse('message', *args)
-
- def help(self):
- helplines = []
-
- helplines.append("Commands:")
- for name, func in ControlServerCommands.__dict__.items():
- if name[0] == '_':
- continue
-
- if not func.__code__:
- continue
-
- params = inspect.signature(func).parameters
- params = [str(info) for name, info in params.items()]
- params = ', '.join(params[1:])
-
- command_sig = '\t' + name
-
- if params:
- command_sig += ': '+params
-
- if func.__doc__:
- command_sig += '\n'+'\n'.join(
- ['\t\t'+line.strip() for line in func.__doc__.splitlines()])+'\n'
-
- helplines.append(command_sig)
+def decodeName(items, name_or_id):
+ try:
+ name_or_id = int(name_or_id)
+ if name_or_id < 0 or name_or_id >= len(items):
+ raise IndexError("unknown index %d" % name_or_id)
- helplines.append('\t'+'quit / exit')
+ return name_or_id
- helplines.append("\n")
- helplines.append("Source-Names:")
- for source in self.sources:
- helplines.append("\t"+source)
+ except ValueError as e:
+ try:
+ return items.index(name_or_id)
- helplines.append("\n")
- helplines.append("Stream-Blanker Sources-Names:")
- for source in self.blankerSources:
- helplines.append("\t"+source)
+ except ValueError as e:
+ raise IndexError("unknown name %s" % name_or_id)
- helplines.append("\n")
- helplines.append("Composition-Modes:")
- for mode in CompositeModes:
- helplines.append("\t"+mode.name)
- return OkResponse("\n".join(helplines))
+def decodeEnumName(enum, name_or_id):
+ try:
+ name_or_id = int(name_or_id)
+ if name_or_id < 0 or name_or_id >= len(enum):
+ raise IndexError("unknown index %d" % name_or_id)
- def _get_video_status(self):
- a = encodeName( self.sources, self.pipeline.vmix.getVideoSourceA() )
- b = encodeName( self.sources, self.pipeline.vmix.getVideoSourceB() )
- return [a, b]
+ return name_or_id
- def get_video(self):
- """gets the current video-status, consisting of the name of
- video-source A and video-source B"""
- status = self._get_video_status()
- return OkResponse('video_status', *status)
+ except ValueError as e:
+ try:
+ return enum[name_or_id]
- def set_video_a(self, src_name_or_id):
- """sets the video-source A to the supplied source-name or source-id,
- swapping A and B if the supplied source is currently used as
- video-source B"""
- src_id = decodeName(self.sources, src_name_or_id)
- self.pipeline.vmix.setVideoSourceA(src_id)
+ except KeyError as e:
+ raise IndexError("unknown name %s" % name_or_id)
- status = self._get_video_status()
- return NotifyResponse('video_status', *status)
- def set_video_b(self, src_name_or_id):
- """sets the video-source B to the supplied source-name or source-id,
- swapping A and B if the supplied source is currently used as
- video-source A"""
- src_id = decodeName(self.sources, src_name_or_id)
- self.pipeline.vmix.setVideoSourceB(src_id)
+def encodeName(items, id):
+ try:
+ return items[id]
+ except IndexError as e:
+ raise IndexError("unknown index %d" % id)
- status = self._get_video_status()
- return NotifyResponse('video_status', *status)
+def encodeEnumName(enum, id):
+ try:
+ return enum(id).name
+ except ValueError as e:
+ raise IndexError("unknown index %d" % id)
- def _get_audio_status(self):
- src_id = self.pipeline.amix.getAudioSource()
- return encodeName(self.sources, src_id)
- def get_audio(self):
- """gets the name of the current audio-source"""
- status = self._get_audio_status()
- return OkResponse('audio_status', status)
+class ControlServerCommands(object):
- def set_audio(self, src_name_or_id):
- """sets the audio-source to the supplied source-name or source-id"""
- src_id = decodeName(self.sources, src_name_or_id)
- self.pipeline.amix.setAudioSource(src_id)
+ def __init__(self, pipeline):
+ self.log = logging.getLogger('ControlServerCommands')
- status = self._get_audio_status()
- return NotifyResponse('audio_status', status)
+ self.pipeline = pipeline
+ self.sources = Config.getlist('mix', 'sources')
+ self.blankerSources = Config.getlist('stream-blanker', 'sources')
- def _get_composite_status(self):
- mode = self.pipeline.vmix.getCompositeMode()
- return encodeEnumName(CompositeModes, mode)
+ # Commands are defined below. Errors are sent to the clients by throwing
+ # exceptions, they will be turned into messages outside.
- def get_composite_mode(self):
- """gets the name of the current composite-mode"""
- status = self._get_composite_status()
- return OkResponse('composite_mode', status)
+ def message(self, *args):
+ """sends a message through the control-server, which can be received by
+ user-defined scripts. does not change the state of the voctocore."""
+ return NotifyResponse('message', *args)
- def set_composite_mode(self, mode_name_or_id):
- """sets the name of the id of the composite-mode"""
- mode = decodeEnumName(CompositeModes, mode_name_or_id)
- self.pipeline.vmix.setCompositeMode(mode)
+ def help(self):
+ helplines = []
- composite_status = self._get_composite_status()
- video_status = self._get_video_status()
- return [
- NotifyResponse('composite_mode', composite_status),
- NotifyResponse('video_status', *video_status)
- ]
-
+ helplines.append("Commands:")
+ for name, func in ControlServerCommands.__dict__.items():
+ if name[0] == '_':
+ continue
- def set_videos_and_composite(self, src_a_name_or_id, src_b_name_or_id, mode_name_or_id):
- """sets the A- and the B-source synchronously with the composition-mode
- all parametets can be set to "*" which will leave them unchanged."""
- if src_a_name_or_id != '*':
- src_a_id = decodeName(self.sources, src_a_name_or_id)
- self.pipeline.vmix.setVideoSourceA(src_a_id)
+ if not func.__code__:
+ continue
- if src_b_name_or_id != '*':
- src_b_id = decodeName(self.sources, src_b_name_or_id)
- self.pipeline.vmix.setVideoSourceB(src_b_id)
-
- if mode_name_or_id != '*':
- mode = decodeEnumName(CompositeModes, mode_name_or_id)
- self.pipeline.vmix.setCompositeMode(mode)
-
- composite_status = self._get_composite_status()
- video_status = self._get_video_status()
-
- return [
- NotifyResponse('composite_mode', composite_status),
- NotifyResponse('video_status', *video_status)
- ]
-
-
- def _get_stream_status(self):
- blankSource = self.pipeline.streamblanker.blankSource
- if blankSource is None:
- return ('live',)
-
- return 'blank', encodeName(self.blankerSources, blankSource)
-
- def get_stream_status(self):
- """gets the current streamblanker-status"""
- status = self._get_stream_status()
- return OkResponse('stream_status', *status)
-
- def set_stream_blank(self, source_name_or_id):
- """sets the streamblanker-status to blank with the specified
- blanker-source-name or -id"""
- src_id = decodeName(self.blankerSources, source_name_or_id)
- self.pipeline.streamblanker.setBlankSource(src_id)
-
- status = self._get_stream_status()
- return NotifyResponse('stream_status', *status)
+ params = inspect.signature(func).parameters
+ params = [str(info) for name, info in params.items()]
+ params = ', '.join(params[1:])
- def set_stream_live(self):
- """sets the streamblanker-status to live"""
- self.pipeline.streamblanker.setBlankSource(None)
+ command_sig = '\t' + name
- status = self._get_stream_status()
- return NotifyResponse('stream_status', *status)
+ if params:
+ command_sig += ': ' + params
+
+ if func.__doc__:
+ command_sig += '\n\t\t{}\n'.format('\n\t\t'.join(
+ [line.strip() for line in func.__doc__.splitlines()]
+ ))
+
+ helplines.append(command_sig)
+
+ helplines.append('\t' + 'quit / exit')
+
+ helplines.append("\n")
+ helplines.append("Source-Names:")
+ for source in self.sources:
+ helplines.append("\t" + source)
+ helplines.append("\n")
+ helplines.append("Stream-Blanker Sources-Names:")
+ for source in self.blankerSources:
+ helplines.append("\t" + source)
+
+ helplines.append("\n")
+ helplines.append("Composition-Modes:")
+ for mode in CompositeModes:
+ helplines.append("\t" + mode.name)
+
+ return OkResponse("\n".join(helplines))
- def get_config(self):
- """returns the parsed server-config"""
- confdict = {header: dict(section) for header, section in dict(Config).items()}
- return OkResponse('server_config', json.dumps(confdict))
+ def _get_video_status(self):
+ a = encodeName(self.sources, self.pipeline.vmix.getVideoSourceA())
+ b = encodeName(self.sources, self.pipeline.vmix.getVideoSourceB())
+ return [a, b]
+
+ def get_video(self):
+ """gets the current video-status, consisting of the name of
+ video-source A and video-source B"""
+ status = self._get_video_status()
+ return OkResponse('video_status', *status)
+
+ def set_video_a(self, src_name_or_id):
+ """sets the video-source A to the supplied source-name or source-id,
+ swapping A and B if the supplied source is currently used as
+ video-source B"""
+ src_id = decodeName(self.sources, src_name_or_id)
+ self.pipeline.vmix.setVideoSourceA(src_id)
+
+ status = self._get_video_status()
+ return NotifyResponse('video_status', *status)
+
+ def set_video_b(self, src_name_or_id):
+ """sets the video-source B to the supplied source-name or source-id,
+ swapping A and B if the supplied source is currently used as
+ video-source A"""
+ src_id = decodeName(self.sources, src_name_or_id)
+ self.pipeline.vmix.setVideoSourceB(src_id)
+
+ status = self._get_video_status()
+ return NotifyResponse('video_status', *status)
+
+ def _get_audio_status(self):
+ src_id = self.pipeline.amix.getAudioSource()
+ return encodeName(self.sources, src_id)
+
+ def get_audio(self):
+ """gets the name of the current audio-source"""
+ status = self._get_audio_status()
+ return OkResponse('audio_status', status)
+
+ def set_audio(self, src_name_or_id):
+ """sets the audio-source to the supplied source-name or source-id"""
+ src_id = decodeName(self.sources, src_name_or_id)
+ self.pipeline.amix.setAudioSource(src_id)
+
+ status = self._get_audio_status()
+ return NotifyResponse('audio_status', status)
+
+ def _get_composite_status(self):
+ mode = self.pipeline.vmix.getCompositeMode()
+ return encodeEnumName(CompositeModes, mode)
+
+ def get_composite_mode(self):
+ """gets the name of the current composite-mode"""
+ status = self._get_composite_status()
+ return OkResponse('composite_mode', status)
+
+ def set_composite_mode(self, mode_name_or_id):
+ """sets the name of the id of the composite-mode"""
+ mode = decodeEnumName(CompositeModes, mode_name_or_id)
+ self.pipeline.vmix.setCompositeMode(mode)
+
+ composite_status = self._get_composite_status()
+ video_status = self._get_video_status()
+ return [
+ NotifyResponse('composite_mode', composite_status),
+ NotifyResponse('video_status', *video_status)
+ ]
+
+ def set_videos_and_composite(self, src_a_name_or_id, src_b_name_or_id,
+ mode_name_or_id):
+ """sets the A- and the B-source synchronously with the composition-mode
+ all parametets can be set to "*" which will leave them unchanged."""
+ if src_a_name_or_id != '*':
+ src_a_id = decodeName(self.sources, src_a_name_or_id)
+ self.pipeline.vmix.setVideoSourceA(src_a_id)
+
+ if src_b_name_or_id != '*':
+ src_b_id = decodeName(self.sources, src_b_name_or_id)
+ self.pipeline.vmix.setVideoSourceB(src_b_id)
+
+ if mode_name_or_id != '*':
+ mode = decodeEnumName(CompositeModes, mode_name_or_id)
+ self.pipeline.vmix.setCompositeMode(mode)
+
+ composite_status = self._get_composite_status()
+ video_status = self._get_video_status()
+
+ return [
+ NotifyResponse('composite_mode', composite_status),
+ NotifyResponse('video_status', *video_status)
+ ]
+
+ def _get_stream_status(self):
+ blankSource = self.pipeline.streamblanker.blankSource
+ if blankSource is None:
+ return ('live',)
+
+ return 'blank', encodeName(self.blankerSources, blankSource)
+
+ def get_stream_status(self):
+ """gets the current streamblanker-status"""
+ status = self._get_stream_status()
+ return OkResponse('stream_status', *status)
+
+ def set_stream_blank(self, source_name_or_id):
+ """sets the streamblanker-status to blank with the specified
+ blanker-source-name or -id"""
+ src_id = decodeName(self.blankerSources, source_name_or_id)
+ self.pipeline.streamblanker.setBlankSource(src_id)
+
+ status = self._get_stream_status()
+ return NotifyResponse('stream_status', *status)
+
+ def set_stream_live(self):
+ """sets the streamblanker-status to live"""
+ self.pipeline.streamblanker.setBlankSource(None)
+
+ status = self._get_stream_status()
+ return NotifyResponse('stream_status', *status)
+
+ def get_config(self):
+ """returns the parsed server-config"""
+ confdict = {header: dict(section)
+ for header, section in dict(Config).items()}
+ return OkResponse('server_config', json.dumps(confdict))