summaryrefslogtreecommitdiff
path: root/voctogui/lib/videodisplay.py
blob: b98daf152f9916be3d6bf06bbb907a9edced8283 (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 on_syncmsg(self, bus, msg):
  46. if msg.get_structure().get_name() == "prepare-window-handle":
  47. self.log.info('setting xvimagesink window-handle to %s', self.xid)
  48. msg.src.set_window_handle(self.xid)
  49. def on_error(self, bus, msg):
  50. self.log.error('on_error():', msg.parse_error())
  51. def on_level_draw(self, widget, cr):
  52. cr.set_source_rgb(1, 1, 1)
  53. cr.set_line_width(10)
  54. cr.move_to(15, 0)
  55. cr.line_to(15, self.levelrms[0]*-20)
  56. cr.stroke()
  57. def on_level(self, bus, msg):
  58. if msg.src.name != 'lvl':
  59. return
  60. if msg.type != Gst.MessageType.ELEMENT:
  61. return
  62. self.levelpeaks = msg.get_structure().get_value('peak')
  63. self.levelrms = msg.get_structure().get_value('rms')
  64. self.audiolevelwidget.queue_draw()