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