summaryrefslogtreecommitdiff
path: root/voctogui/lib/videodisplay.py
blob: 691566618872e97d199fa377500ba6b137c80ad1 (plain)
  1. import logging
  2. from gi.repository import Gst, Gtk
  3. class VideoDisplay:
  4. """ Displays a Voctomix-Video-Stream into a GtkWidget """
  5. def __init__(self, port, videowidget, audiolevelwidget=None, playaudio=False):
  6. self.log = logging.getLogger('VideoDisplay[%u]' % port)
  7. pipeline = """
  8. videotestsrc !
  9. timeoverlay !
  10. video/x-raw,width=1920,height=1080 !
  11. xvimagesink name=v
  12. """.format(
  13. port=port
  14. )
  15. if audiolevelwidget or playaudio:
  16. pipeline += """
  17. audiotestsrc wave=blue-noise !
  18. audio/x-raw !
  19. level name=lvl interval=50000000 !
  20. """
  21. if playaudio:
  22. pipeline += """
  23. alsasink
  24. """
  25. else:
  26. pipeline += """
  27. fakesink
  28. """
  29. self.log.info('launching gstreamer-pipeline for widget %s "%s":\n%s', videowidget.get_name(), Gtk.Buildable.get_name(videowidget), pipeline)
  30. self.pipeline = Gst.parse_launch(pipeline)
  31. videowidget.realize()
  32. self.xid = videowidget.get_property('window').get_xid()
  33. bus = self.pipeline.get_bus()
  34. bus.add_signal_watch()
  35. bus.enable_sync_message_emission()
  36. bus.connect('message::error', self.on_error)
  37. bus.connect("sync-message::element", self.on_syncmsg)
  38. if audiolevelwidget:
  39. self.levelrms = [0, 0]
  40. self.audiolevelwidget = audiolevelwidget
  41. self.audiolevelwidget.connect('draw', self.on_level_draw)
  42. bus.connect("message::element", self.on_level)
  43. def run(self):
  44. self.pipeline.set_state(Gst.State.PLAYING)
  45. def set_overlay_callback(self, callback):
  46. if callback:
  47. if not self.draw_callback:
  48. self.draw_callback = self.pipeline.get_by_name('overlay').connect('draw', callback)
  49. else:
  50. print('disconnect')
  51. self.pipeline.get_by_name('overlay').disconnect(self.draw_callback)
  52. self.draw_callback = None
  53. def on_syncmsg(self, bus, msg):
  54. if msg.get_structure().get_name() == "prepare-window-handle":
  55. self.log.info('setting xvimagesink window-handle to %s', self.xid)
  56. msg.src.set_window_handle(self.xid)
  57. def on_error(self, bus, msg):
  58. self.log.error('on_error(): %s', msg.parse_error())
  59. def on_level_draw(self, widget, cr):
  60. cr.set_source_rgb(1, 1, 1)
  61. cr.set_line_width(10)
  62. cr.move_to(15, 0)
  63. cr.line_to(15, self.levelrms[0]*-20)
  64. cr.stroke()
  65. def on_level(self, bus, msg):
  66. if msg.src.name != 'lvl':
  67. return
  68. if msg.type != Gst.MessageType.ELEMENT:
  69. return
  70. self.levelpeaks = msg.get_structure().get_value('peak')
  71. self.levelrms = msg.get_structure().get_value('rms')
  72. self.audiolevelwidget.queue_draw()