summaryrefslogtreecommitdiff
path: root/voctogui/voctogui.py
blob: 0e953b55377ad6fec7389c8d37e66e9b0a70d0ec (plain)
  1. #!/usr/bin/env python3
  2. import gi
  3. import signal
  4. import logging
  5. import sys
  6. import os
  7. # import GStreamer and GLib-Helper classes
  8. gi.require_version('Gtk', '3.0')
  9. gi.require_version('Gst', '1.0')
  10. gi.require_version('GdkX11', '3.0')
  11. gi.require_version('GstVideo', '1.0')
  12. gi.require_version('GstNet', '1.0')
  13. from gi.repository import Gtk, Gdk, Gst, GObject, GdkX11, GstVideo
  14. # check min-version
  15. minGst = (1, 5)
  16. minPy = (3, 0)
  17. Gst.init([])
  18. if Gst.version() < minGst:
  19. raise Exception('GStreamer version', Gst.version(),
  20. 'is too old, at least', minGst, 'is required')
  21. if sys.version_info < minPy:
  22. raise Exception('Python version', sys.version_info,
  23. 'is too old, at least', minPy, 'is required')
  24. # init GObject & Co. before importing local classes
  25. GObject.threads_init()
  26. Gdk.init([])
  27. Gtk.init([])
  28. # import local classes
  29. from lib.args import Args
  30. from lib.config import Config
  31. from lib.ui import Ui
  32. from lib.loghandler import LogHandler
  33. import lib.connection as Connection
  34. import lib.clock as ClockManager
  35. # main class
  36. class Voctogui(object):
  37. def __init__(self):
  38. self.log = logging.getLogger('Voctogui')
  39. # Uf a UI-File was specified on the Command-Line, load it
  40. if Args.ui_file:
  41. self.log.info(
  42. 'loading ui-file from file specified on command-line: %s',
  43. Args.ui_file
  44. )
  45. self.ui = Ui(Args.ui_file)
  46. else:
  47. # Paths to look for the gst-switch UI-File
  48. paths = [
  49. os.path.join(os.path.dirname(os.path.realpath(__file__)),
  50. 'ui/voctogui.ui'),
  51. '/usr/lib/voctogui/ui/voctogui.ui'
  52. ]
  53. # Look for a gst-switch UI-File and load it
  54. self.ui = None
  55. for path in paths:
  56. self.log.debug('trying to load ui-file from file %s', path)
  57. if os.path.isfile(path):
  58. self.log.info('loading ui-file from file %s', path)
  59. self.ui = Ui(path)
  60. break
  61. if self.ui is None:
  62. raise Exception("Can't find any .ui-Files to use "
  63. "(searched {})".format(', '.join(paths)))
  64. self.ui.setup()
  65. def run(self):
  66. self.log.info('setting UI visible')
  67. self.ui.show()
  68. try:
  69. self.log.info('running Gtk-MainLoop')
  70. Gtk.main()
  71. self.log.info('Gtk-MainLoop ended')
  72. except KeyboardInterrupt:
  73. self.log.info('Terminated via Ctrl-C')
  74. def quit(self):
  75. self.log.info('quitting Gtk-MainLoop')
  76. Gtk.main_quit()
  77. # run mainclass
  78. def main():
  79. # configure logging
  80. docolor = (Args.color == 'always') or (Args.color == 'auto' and
  81. sys.stderr.isatty())
  82. handler = LogHandler(docolor, Args.timestamp)
  83. logging.root.addHandler(handler)
  84. if Args.verbose >= 2:
  85. level = logging.DEBUG
  86. elif Args.verbose == 1:
  87. level = logging.INFO
  88. else:
  89. level = logging.WARNING
  90. logging.root.setLevel(level)
  91. # make killable by ctrl-c
  92. logging.debug('setting SIGINT handler')
  93. signal.signal(signal.SIGINT, signal.SIG_DFL)
  94. logging.info('Python Version: %s', sys.version_info)
  95. logging.info('GStreamer Version: %s', Gst.version())
  96. # establish a synchronus connection to server
  97. Connection.establish(
  98. Args.host if Args.host else Config.get('server', 'host')
  99. )
  100. # fetch config from server
  101. Config.fetchServerConfig()
  102. # Warn when connecting to a non-local core without preview-encoders enabled
  103. # The list-comparison is not complete
  104. # (one could use a local hostname or the local system ip),
  105. # but it's only here to warn that one might be making a mistake
  106. use_previews = (Config.getboolean('previews', 'enabled') and
  107. Config.getboolean('previews', 'use'))
  108. looks_like_localhost = Config.get('server', 'host') in ['::1',
  109. '127.0.0.1',
  110. 'localhost']
  111. if not use_previews and not looks_like_localhost:
  112. logging.warn(
  113. 'Connecting to `%s` (which looks like a remote host) '
  114. 'might not work without enabeling the preview encoders '
  115. '(set `[previews] enabled=true` on the core) or it might saturate '
  116. 'your ethernet link between the two machines.',
  117. Config.get('server', 'host')
  118. )
  119. # obtain network-clock
  120. ClockManager.obtainClock(Connection.ip)
  121. # switch connection to nonblocking, event-driven mode
  122. Connection.enterNonblockingMode()
  123. # init main-class and main-loop
  124. # (this binds all event-hander on the Connection)
  125. logging.debug('initializing Voctogui')
  126. voctogui = Voctogui()
  127. # start the Mainloop and show the Window
  128. logging.debug('running Voctogui')
  129. voctogui.run()
  130. if __name__ == '__main__':
  131. main()