Enigma2 plugin to to play various online streams (mostly Latvian).

basic-tutorial-3.py 3.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. #!/usr/bin/env python3
  2. # -*- coding:utf-8 -*-
  3. # GStreamer SDK Tutorials in Python
  4. #
  5. # basic-tutorial-3
  6. #
  7. """
  8. basic-tutorial-3: Dynamic pipelines
  9. http://docs.gstreamer.com/display/GstSDK/Basic+tutorial+3%3A+Dynamic+pipelines
  10. """
  11. import sys
  12. # GObject.threads_init() needed to avoid seg fault
  13. from gi.repository import GObject
  14. GObject.threads_init()
  15. from gi.repository import Gst
  16. Gst.init(None)
  17. data = dict()
  18. # Handler for the pad-added signal
  19. def pad_added_handler(src, new_pad, data):
  20. print("Received new pad '%s' from '%s':" % (new_pad.get_name(),
  21. src.get_name()))
  22. # If our converter is already linked, we have nothing to do here
  23. if new_pad.is_linked():
  24. print("We are already linked. Ignoring.")
  25. return
  26. # Check the new pad's type
  27. new_pad_type = new_pad.query_caps(None).to_string()
  28. if not new_pad_type.startswith("audio/x-raw"):
  29. print(" It has type '%s' which is not raw audio. Ignoring." %
  30. new_pad_type)
  31. return
  32. # Attempt the link
  33. ret = new_pad.link(data["convert"].get_static_pad("sink"))
  34. return
  35. # Create the elements
  36. data["source"] = Gst.ElementFactory.make("uridecodebin", "source")
  37. data["convert"] = Gst.ElementFactory.make("audioconvert", "convert")
  38. data["sink"] = Gst.ElementFactory.make("autoaudiosink", "sink")
  39. # Create the empty pipeline
  40. pipeline = Gst.Pipeline.new("test-pipeline")
  41. if not data["source"] or not data["convert"] or not data["sink"] or not pipeline:
  42. print("Not all elements could be created.", file=sys.stderr)
  43. exit(-1)
  44. # Build the pipeline
  45. # Note that we are NOT linking the source at this point. We will do it later.
  46. pipeline.add(data["source"])
  47. pipeline.add(data["convert"])
  48. pipeline.add(data["sink"])
  49. if not Gst.Element.link(data["convert"], data["sink"]):
  50. print("Elements could not be linked.", file=sys.stderr)
  51. exit(-1)
  52. # Set the URI to play
  53. data["source"].set_property(
  54. "uri", "http://docs.gstreamer.com/media/sintel_trailer-480p.webm")
  55. # Connect to the pad-added signal
  56. data["source"].connect("pad-added", pad_added_handler, data)
  57. # Start playing
  58. ret = pipeline.set_state(Gst.State.PLAYING)
  59. if ret == Gst.StateChangeReturn.FAILURE:
  60. print("Unable to set the pipeline to the playing state.", file=sys.stderr)
  61. exit(-1)
  62. # Wait until error or EOS
  63. bus = pipeline.get_bus()
  64. # Parse message
  65. while True:
  66. message = bus.timed_pop_filtered(Gst.CLOCK_TIME_NONE, Gst.MessageType.STATE_CHANGED | Gst.MessageType.ERROR | Gst.MessageType.EOS)
  67. if message.type == Gst.MessageType.ERROR:
  68. err, debug = message.parse_error()
  69. print("Error received from element %s: %s" % (
  70. message.src.get_name(), err), file=sys.stderr)
  71. print("Debugging information: %s" % debug, file=sys.stderr)
  72. break
  73. elif message.type == Gst.MessageType.EOS:
  74. print("End-Of-Stream reached.")
  75. break
  76. elif message.type == Gst.MessageType.STATE_CHANGED:
  77. if isinstance(message.src, Gst.Pipeline):
  78. old_state, new_state, pending_state = message.parse_state_changed()
  79. print("Pipeline state changed from %s to %s." %
  80. (old_state.value_nick, new_state.value_nick))
  81. else:
  82. print("Unexpected message received.", file=sys.stderr)
  83. # Free resources
  84. pipeline.set_state(Gst.State.NULL)