summaryrefslogtreecommitdiff
path: root/voctocore/lib/commands.py
blob: c972c699ae2044e71d9cd5efa5d9ecc78af3a3fc (plain)
  1. #!/usr/bin/python3
  2. import logging
  3. import json
  4. from lib.config import Config
  5. from lib.videomix import CompositeModes
  6. class ControlServerCommands():
  7. def __init__(self, pipeline):
  8. self.log = logging.getLogger('ControlServerCommands')
  9. self.pipeline = pipeline
  10. self.sources = Config.getlist('mix', 'sources')
  11. self.blankersources = Config.getlist('stream-blanker', 'sources')
  12. def decodeSourceName(self, src_name_or_id):
  13. if isinstance(src_name_or_id, str):
  14. try:
  15. return self.sources.index(src_name_or_id)
  16. except Exception as e:
  17. raise IndexError("source %s unknown" % src_name_or_id)
  18. if src_name_or_id < 0 or src_name_or_id >= len(self.sources):
  19. raise IndexError("source %s unknown" % src_name_or_id)
  20. def encodeSourceName(self, src_id):
  21. try:
  22. return self.sources[src_id]
  23. except Exception as e:
  24. raise IndexError("source %s unknown" % src_id)
  25. def decodeBlankerSourceName(self, src_name_or_id):
  26. if isinstance(src_name_or_id, str):
  27. try:
  28. return self.blankersources.index(src_name_or_id)
  29. except Exception as e:
  30. raise IndexError("source %s unknown" % src_name_or_id)
  31. if src_name_or_id < 0 or src_name_or_id >= len(self.blankersources):
  32. raise IndexError("source %s unknown" % src_name_or_id)
  33. def encodeBlankerSourceName(self, src_id):
  34. try:
  35. return self.blankersources[src_id]
  36. except Exception as e:
  37. raise IndexError("source %s unknown" % src_id)
  38. # Commands are defined below. Errors are sent to the clients by throwing
  39. # exceptions, they will be turned into messages outside.
  40. def fetch(self, command):
  41. if command not in ['set', 'get', 'message', 'signal']:
  42. raise Exception("unknown command")
  43. return getattr(self, command)
  44. def message(self, *args):
  45. return " ".join(args), True
  46. def signal(self, *args):
  47. return "", True
  48. def get(self, subcommand, *args, signal=False):
  49. return getattr(self, "_get_"+subcommand)(*args), signal
  50. def set(self, subcommand, *args):
  51. getattr(self, "_set_"+subcommand)(*args)
  52. return self.get(subcommand, *args, signal=True)
  53. def _get_video(self, target, _=None):
  54. if target not in ['a', 'b']:
  55. raise Exception("invalid video source name: 'a' or 'b' expected.")
  56. cmd = "getVideoSource" + target.upper()
  57. src_id = getattr(self.pipeline.vmix, cmd)()
  58. return self.encodeSourceName(src_id)
  59. def _set_video(self, target, src_name_or_id):
  60. if target not in ['a', 'b']:
  61. raise Exception("invalid video source name: 'a' or 'b' expected.")
  62. src_id = self.decodeSourceName(src_name_or_id)
  63. getattr(self.pipeline.vmix, 'setVideoSource' + target.upper())(src_id)
  64. def _set_audio(self, src_name_or_id):
  65. src_id = self.decodeSourceName(src_name_or_id)
  66. self.pipeline.amix.setAudioSource(src_id)
  67. def _get_audio(self, _=None):
  68. src_id = self.pipeline.amix.getAudioSource()
  69. return self.encodeSourceName(src_id)
  70. def _set_composite(self, composite_mode):
  71. try:
  72. mode = CompositeModes[composite_mode]
  73. except KeyError as e:
  74. raise KeyError("composite-mode %s unknown" % composite_mode)
  75. self.pipeline.vmix.setCompositeMode(mode)
  76. def _get_composite(self, _=None):
  77. try:
  78. mode = self.pipeline.vmix.getCompositeMode()
  79. return mode.name
  80. except Exception as e:
  81. raise KeyError("composite-mode %s unknown" % mode)
  82. def _set_status(self, *args):
  83. try:
  84. if args[0] == "live":
  85. self.pipeline.streamblanker.setBlankSource(None)
  86. elif args [0] == "blank":
  87. src_id = self.decodeBlankerSourceName(args[1])
  88. self.pipeline.streamblanker.setBlankSource(src_id)
  89. else:
  90. raise IndexError()
  91. except IndexError as e:
  92. raise Exception("invocation: set_status (live | blank <mode>)")
  93. def _get_status(self, *args):
  94. if self.pipeline.streamblanker.blankSource is None:
  95. return "live"
  96. name = self.encodeBlankerSourceName(self.pipeline.streamblanker.blankSource)
  97. return "blank " + name
  98. def _get_config(self):
  99. confdict = {k: dict(v) for k, v in dict(Config).items()}
  100. return json.dumps(confdict)