summaryrefslogtreecommitdiff
path: root/voctocore/lib/avsource.py
blob: 920d9060bc62a1dcc3c2333d9414f39503bcc08f (plain)
  1. #!/usr/bin/python3
  2. import logging
  3. from gi.repository import Gst
  4. from lib.config import Config
  5. from lib.tcpsingleconnection import TCPSingleConnection
  6. class AVSource(TCPSingleConnection):
  7. log = logging.getLogger('AVSource')
  8. name = None
  9. caps = None
  10. receiverPipeline = None
  11. def __init__(self, name, port):
  12. self.log = logging.getLogger('AVSource['+name+']')
  13. super().__init__(port)
  14. self.name = name
  15. def on_accepted(self, conn, addr):
  16. pipeline = """
  17. fdsrc fd={fd} !
  18. matroskademux name=demux
  19. demux. !
  20. {acaps} !
  21. queue !
  22. tee name=atee
  23. atee. ! queue ! interaudiosink channel=audio_{name}_mixer
  24. atee. ! queue ! interaudiosink channel=audio_{name}_mirror
  25. """.format(
  26. fd=conn.fileno(),
  27. name=self.name,
  28. acaps=Config.get('mix', 'audiocaps')
  29. )
  30. if Config.getboolean('previews', 'enabled'):
  31. pipeline += """
  32. atee. ! queue ! interaudiosink channel=audio_{name}_preview
  33. """.format(
  34. name=self.name
  35. )
  36. pipeline += """
  37. demux. !
  38. {vcaps} !
  39. textoverlay halignment=left valignment=top ypad=25 text=AVSource !
  40. timeoverlay halignment=left valignment=top ypad=25 xpad=400 !
  41. queue !
  42. tee name=vtee
  43. vtee. ! queue ! intervideosink channel=video_{name}_mixer
  44. vtee. ! queue ! intervideosink channel=video_{name}_mirror
  45. """.format(
  46. fd=conn.fileno(),
  47. name=self.name,
  48. vcaps=Config.get('mix', 'videocaps')
  49. )
  50. if Config.getboolean('previews', 'enabled'):
  51. pipeline += """
  52. vtee. ! queue ! intervideosink channel=video_{name}_preview
  53. """.format(
  54. name=self.name
  55. )
  56. self.log.debug('Launching Source-Pipeline:\n%s', pipeline)
  57. self.receiverPipeline = Gst.parse_launch(pipeline)
  58. self.log.debug('Binding End-of-Stream-Signal on Source-Pipeline')
  59. self.receiverPipeline.bus.add_signal_watch()
  60. self.receiverPipeline.bus.connect("message::eos", self.on_eos)
  61. self.receiverPipeline.bus.connect("message::error", self.on_error)
  62. self.receiverPipeline.set_state(Gst.State.PLAYING)
  63. def on_eos(self, bus, message):
  64. self.log.debug('Received End-of-Stream-Signal on Source-Pipeline')
  65. if self.currentConnection is not None:
  66. self.disconnect()
  67. def on_error(self, bus, message):
  68. self.log.debug('Received Error-Signal on Source-Pipeline')
  69. (error, debug) = message.parse_error()
  70. self.log.debug('Error-Details: #%u: %s', error.code, debug)
  71. if self.currentConnection is not None:
  72. self.disconnect()
  73. def disconnect(self):
  74. self.receiverPipeline.set_state(Gst.State.NULL)
  75. self.receiverPipeline = None
  76. self.close_connection()