def mixer_check_cb(*user_data): global new_client if len(new_client) > 0 and len(clients) >= 2: print("\nnew client(s), checking mixer links... ", end="") # only try to link things when all clients have all stream decoders in place for c in clients: if not clients[c].ready(): print("not all decoders in place yet, waiting.") return True #GLib.SOURCE_CONTINUE print("all client decoders ready.") create_frontmixer_queue() ssrc = new_client.pop(0) print(" setting up mixers for new client " + ssrc) # create surface/audio mixers for _all_ clients that don't have one yet # needs to loop through all clients for the case where 2 or more clients # appear simultaneously, otherwise there are no mixers to link to for c in clients: clients[c].create_mixers() # add missing frontmixer links clients[ssrc].link_to_front() # add missing surface/audio mixer links clients[ssrc].link_all_streams() # write out debug dot file (needs envvar GST_DEBUG_DUMP_DOT_DIR set) Gst.debug_bin_to_dot_file(pipeline, Gst.DebugGraphDetails(15), "debug") # re-schedule the callback if there are more new clients to process if len(new_client) > 0: GLib.timeout_add(1000, mixer_check_cb, None) return False # GLib.SOURCE_REMOVE
def on_pad_added(src, pad, *user_data): name = pad.get_name() print("tsdemux pad added: " + name) # TODO: instead of the fpsdisplaysink, connect a mixer if name.startswith("video"): print("adding video subqueue") # FIXME: using the last/most recent src_id is a hack and will only work if clients do not connect at the same time teename = sources[-1] + "_" + stream[name] if stream[name] == "surface": surfaces.append(teename) add_and_link([ src, new_element("h264parse"), new_element("queue", { "max-size-time": 200000000, "leaky": "upstream" }), new_element("avdec_h264"), new_element("textoverlay", { "text": teename, "valignment": "top" }), new_element("alpha", {"method": "green"}), new_element("tee", myname=teename), new_element("queue"), new_element("videoconvert"), new_element("fpsdisplaysink") ]) if name.startswith("audio"): print("adding audio subqueue") add_and_link([ src, new_element("opusparse"), new_element("queue", { "max-size-time": 200000000, "leaky": "upstream" }), new_element("opusdec", {"plc": True}), new_element("autoaudiosink") ]) # do we have at least two surface streams? if len(surfaces) > 1: print("linking tees to mixer") #teepad1 = tee1.request_pad(tee1.get_pad_template("src_%u"), None, None) #teepad2 = tee2.request_pad(tee2.get_pad_template("src_%u"), None, None) mixer = new_element("videomixer") add_and_link([ mixer, new_element("videoconvert"), new_element("fpsdisplaysink") ]) add_and_link([ pipeline.get_by_name(surfaces[0]), new_element("queue"), mixer ]) add_and_link([ pipeline.get_by_name(surfaces[1]), new_element("queue"), mixer ]) #mixtemp = mixer.get_pad_template("sink_%u") #mixpad1 = mixer.request_pad(mixtemp, None, None) #mixpad2 = mixer.request_pad(mixtemp, None, None) #pipeline.set_state(Gst.State.PLAYING) Gst.debug_bin_to_dot_file(pipeline, Gst.DebugGraphDetails(15), "debug.dot")
err, debug = message.parse_error() print(err, debug) loop.quit() elif mtype == Gst.MessageType.WARNING: err, debug = message.parse_warning() print(err, debug) return True command = args["pipeline"] pipeline = Gst.parse_launch(command) Gst.debug_bin_to_dot_file(pipeline,Gst.DebugGraphDetails(-1),'/tmp/teste.dot') bus = pipeline.get_bus() bus.add_signal_watch() pipeline.set_state(Gst.State.PLAYING) loop = GObject.MainLoop() bus.connect("message", on_message, loop) try: loop.run() except Exception: traceback.print_exc() loop.quit() # Stop Pipeline