Last active
January 12, 2025 00:01
-
-
Save SanchayanMaity/32f40e5ad179c96e664a3506e7954e9e to your computer and use it in GitHub Desktop.
Test code for hlssink4
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python3 | |
| import os # noqa: I001 | |
| import signal | |
| import sys | |
| import subprocess | |
| import gi | |
| gi.require_version("GLib", "2.0") | |
| gi.require_version("Gst", "1.0") | |
| from gi.repository import GLib, Gst # noqa: E402 | |
| Gst.init(None) | |
| hlsTestFile = None | |
| glibMainLoop: GLib.MainLoop = None | |
| pipeline: Gst.Element = None | |
| def debugDumpPipeline(phase: str) -> None: | |
| GLib.timeout_add_seconds( | |
| 5, | |
| lambda: Gst.debug_bin_to_dot_file_with_ts( | |
| pipeline, Gst.DebugGraphDetails.VERBOSE, "hlssink-" + phase | |
| ), | |
| ) | |
| def log(*args): | |
| print(*args, file=sys.stderr) | |
| def hasVideoAudio(filename) -> bool: | |
| result = subprocess.run( | |
| [ | |
| "ffprobe", | |
| "-v", | |
| "error", | |
| "-show_entries", | |
| "format=nb_streams", | |
| "-of", | |
| "default=noprint_wrappers=1:nokey=1", | |
| filename, | |
| ], | |
| stdout=subprocess.PIPE, | |
| stderr=subprocess.STDOUT, | |
| ) | |
| print("Number of streams: ", int(result.stdout)) | |
| return int(result.stdout) == 2 | |
| def busMessage(_bus: Gst.Bus, message: Gst.Message, loop: GLib.MainLoop) -> bool: | |
| t = message.type | |
| if t == Gst.MessageType.EOS: | |
| log("End of stream. Shutting down pipeline.") | |
| loop.quit() | |
| elif t == Gst.MessageType.ERROR: | |
| err, debug = message.parse_error() | |
| debug = f"{err}: {debug}" | |
| log("Pipeline error: ", err, debug) | |
| loop.quit() | |
| return True | |
| def sigintHandler(_signum, _frame): | |
| log("Sending EOS to pipeline") | |
| pipeline.send_event(Gst.Event.new_eos()) | |
| glibMainLoop.quit() | |
| def decodebinPadAdded(_dbin: Gst.Element, pad: Gst.Pad) -> None: | |
| global pipeline | |
| caps: Gst.Caps = pad.get_current_caps() | |
| s = caps.get_structure(0) | |
| name = s.get_name() | |
| if name.startswith("video"): | |
| videotee = pipeline.get_by_name("video-tee") | |
| sinkpad = videotee.get_static_pad("sink") | |
| pad.link(sinkpad) | |
| debugDumpPipeline("decodebin-video") | |
| elif name.startswith("audio"): | |
| audiotee = pipeline.get_by_name("audio-tee") | |
| sinkpad = audiotee.get_static_pad("sink") | |
| pad.link(sinkpad) | |
| debugDumpPipeline("decodebin-audio") | |
| else: | |
| return | |
| def fileSourceBin(pipeline: Gst.Element) -> (Gst.Element, Gst.Element): | |
| filesrc = Gst.ElementFactory.make("filesrc") | |
| decodebin = Gst.ElementFactory.make("decodebin") | |
| audiotee = Gst.ElementFactory.make("tee", "audio-tee") | |
| videotee = Gst.ElementFactory.make("tee", "video-tee") | |
| filesrc.set_property("location", hlsTestFile) | |
| pipeline.add(filesrc) | |
| pipeline.add(decodebin) | |
| pipeline.add(audiotee) | |
| pipeline.add(videotee) | |
| decodebin.connect("pad-added", decodebinPadAdded) | |
| filesrc.link(decodebin) | |
| return (audiotee, videotee) | |
| def videoBin( | |
| width: int, | |
| height: int, | |
| fps: int, | |
| bitrate: int, | |
| iframe_only: bool, | |
| ) -> Gst.Bin: | |
| clocksync: Gst.Element = Gst.ElementFactory.make("clocksync") | |
| videoconvert: Gst.Element = Gst.ElementFactory.make("videoconvert") | |
| videoscale: Gst.Element = Gst.ElementFactory.make("videoscale") | |
| videorate: Gst.Element = Gst.ElementFactory.make("videorate") | |
| capsfilter: Gst.Element = Gst.ElementFactory.make("capsfilter") | |
| x264enc: Gst.Element = Gst.ElementFactory.make("x264enc") | |
| h264_capsfilter: Gst.Element = Gst.ElementFactory.make("capsfilter") | |
| h264parse: Gst.Element = Gst.ElementFactory.make("h264parse") | |
| queue: Gst.Element = Gst.ElementFactory.make("queue") | |
| caps = Gst.Caps.from_string( | |
| f"""video/x-raw,width={width},height={height},framerate={fps}/1,pixel-aspect-ratio=1/1,format=I420""" | |
| ) | |
| capsfilter.set_property("caps", caps) | |
| caps = Gst.Caps.from_string("video/x-h264") | |
| h264_capsfilter.set_property("caps", caps) | |
| x264enc.set_property("bitrate", bitrate) | |
| x264enc.set_property("speed-preset", "ultrafast") | |
| x264enc.set_property("tune", "zerolatency") | |
| if iframe_only: | |
| x264enc.set_property("key-int-max", 1) | |
| else: | |
| x264enc.set_property("key-int-max", fps * 2) | |
| bin = Gst.Bin.new("videobin-" + str(bitrate)) | |
| bin.add(clocksync) | |
| bin.add(videoconvert) | |
| bin.add(videoscale) | |
| bin.add(videorate) | |
| bin.add(capsfilter) | |
| bin.add(x264enc) | |
| bin.add(h264_capsfilter) | |
| bin.add(h264parse) | |
| bin.add(queue) | |
| clocksync.link(videoconvert) | |
| videoconvert.link(videorate) | |
| videorate.link(videoscale) | |
| videoscale.link(capsfilter) | |
| capsfilter.link(x264enc) | |
| x264enc.link(h264_capsfilter) | |
| h264_capsfilter.link(h264parse) | |
| h264parse.link(queue) | |
| queue_srcpad: Gst.Pad = queue.get_static_pad("src") | |
| srcpad: Gst.Pad = Gst.GhostPad.new("src", queue_srcpad) | |
| clocksync_sinkpad: Gst.Pad = clocksync.get_static_pad("sink") | |
| sinkpad: Gst.Pad = Gst.GhostPad.new("sink", clocksync_sinkpad) | |
| bin.add_pad(sinkpad) | |
| bin.add_pad(srcpad) | |
| Gst.debug_bin_to_dot_file_with_ts( | |
| bin, Gst.DebugGraphDetails.VERBOSE, "videobin-" + str(bitrate) | |
| ) | |
| return bin | |
| def audioBin(bitrate: int) -> Gst.Bin: | |
| clocksync: Gst.Element = Gst.ElementFactory.make("clocksync") | |
| audioconvert: Gst.Element = Gst.ElementFactory.make("audioconvert") | |
| audiorate: Gst.Element = Gst.ElementFactory.make("audiorate") | |
| capsfilter: Gst.Element = Gst.ElementFactory.make("capsfilter") | |
| audioenc: Gst.Element = Gst.ElementFactory.make("avenc_aac") | |
| aacparse: Gst.Element = Gst.ElementFactory.make("aacparse") | |
| caps: Gst.Caps = Gst.Caps.from_string( | |
| "audio/x-raw,channels=2,rate=48000,format=F32LE" | |
| ) | |
| capsfilter.set_property("caps", caps) | |
| audioenc.set_property("bitrate", bitrate) | |
| bin = Gst.Bin.new("audiobin-" + str(bitrate)) | |
| bin.add(clocksync) | |
| bin.add(audioconvert) | |
| bin.add(audiorate) | |
| bin.add(capsfilter) | |
| bin.add(audioenc) | |
| bin.add(aacparse) | |
| clocksync.link(audioconvert) | |
| audioconvert.link(audiorate) | |
| audiorate.link(capsfilter) | |
| capsfilter.link(audioenc) | |
| audioenc.link(aacparse) | |
| aacparse_srcpad: Gst.Pad = aacparse.get_static_pad("src") | |
| srcpad: Gst.Pad = Gst.GhostPad.new("src", aacparse_srcpad) | |
| clocksync_sinkpad: Gst.Pad = clocksync.get_static_pad("sink") | |
| sinkpad: Gst.Pad = Gst.GhostPad.new("sink", clocksync_sinkpad) | |
| bin.add_pad(sinkpad) | |
| bin.add_pad(srcpad) | |
| return bin | |
| def multipleAudioRenditionMultipleVideoVariant(iframe: bool = False): | |
| global pipeline | |
| hlssink: Gst.Element = Gst.ElementFactory.make("hlssink4") | |
| hlssink.set_property("master-playlist-location", "hlssink/master.m3u8") | |
| hlssink.set_property("playlist-type", "event") | |
| hlssink.set_property("target-duration", 10) | |
| if iframe: | |
| hlssink.set_property("muxer-type", "mpegts") | |
| pipeline.add(hlssink) | |
| (audiotee, videotee) = fileSourceBin(pipeline) | |
| audioBin1: Gst.Bin = audioBin(256000) | |
| pipeline.add(audioBin1) | |
| audioBin1_sinkpad = audioBin1.get_static_pad("sink") | |
| audioteeSrcPad = audiotee.request_pad_simple("src_%u") | |
| audioteeSrcPad.link(audioBin1_sinkpad) | |
| audioBin1Pad: Gst.Pad = audioBin1.get_static_pad("src") | |
| audio1Pad = hlssink.request_pad_simple("audio_%u") | |
| r = Gst.Structure.new_empty("audio1") | |
| r.set_value("media_type", "AUDIO") | |
| r.set_value("uri", "hi-audio/audio.m3u8") | |
| r.set_value("group_id", "aac") | |
| r.set_value("language", "en") | |
| r.set_value("name", "English") | |
| r.set_value("default", True) | |
| r.set_value("autoselect", False) | |
| audio1Pad.set_property("alternate-rendition", r) | |
| audioBin1Pad.link(audio1Pad) | |
| audioBin2: Gst.Bin = audioBin(128000) | |
| pipeline.add(audioBin2) | |
| audioBin2_sinkpad = audioBin2.get_static_pad("sink") | |
| audioteeSrcPad = audiotee.request_pad_simple("src_%u") | |
| audioteeSrcPad.link(audioBin2_sinkpad) | |
| audioBin2Pad: Gst.Pad = audioBin2.get_static_pad("src") | |
| audio2Pad = hlssink.request_pad_simple("audio_%u") | |
| r = Gst.Structure.new_empty("audio2") | |
| r.set_value("media_type", "AUDIO") | |
| r.set_value("uri", "mid-audio/audio.m3u8") | |
| r.set_value("group_id", "aac") | |
| r.set_value("name", "French") | |
| r.set_value("language", "fr") | |
| r.set_value("default", False) | |
| r.set_value("autoselect", True) | |
| audio2Pad.set_property("alternate-rendition", r) | |
| audioBin2Pad.link(audio2Pad) | |
| videoBin1: Gst.Bin = videoBin(1920, 1080, 30, 2500, False) | |
| pipeline.add(videoBin1) | |
| videoBin1_sinkpad = videoBin1.get_static_pad("sink") | |
| videoteeSrcPad = videotee.request_pad_simple("src_%u") | |
| videoteeSrcPad.link(videoBin1_sinkpad) | |
| videoBin1Pad: Gst.Pad = videoBin1.get_static_pad("src") | |
| video1Pad = hlssink.request_pad_simple("video_%u") | |
| v = Gst.Structure.new_empty("video1") | |
| v.set_value("uri", "hi/video.m3u8") | |
| v.set_value("bandwidth", 2500) | |
| v.set_value("audio", "aac") | |
| video1Pad.set_property("variant", v) | |
| videoBin1Pad.link(video1Pad) | |
| videoBin2: Gst.Bin = videoBin(1280, 720, 30, 1500, False) | |
| pipeline.add(videoBin2) | |
| videoBin2_sinkpad = videoBin2.get_static_pad("sink") | |
| videoteeSrcPad = videotee.request_pad_simple("src_%u") | |
| videoteeSrcPad.link(videoBin2_sinkpad) | |
| videoBin2Pad: Gst.Pad = videoBin2.get_static_pad("src") | |
| video2Pad = hlssink.request_pad_simple("video_%u") | |
| v = Gst.Structure.new_empty("video2") | |
| v.set_value("uri", "mid/video.m3u8") | |
| v.set_value("bandwidth", 1500) | |
| v.set_value("audio", "aac") | |
| video2Pad.set_property("variant", v) | |
| videoBin2Pad.link(video2Pad) | |
| videoBin3: Gst.Bin = videoBin(640, 360, 24, 700, False) | |
| pipeline.add(videoBin3) | |
| videoBin3_sinkpad = videoBin3.get_static_pad("sink") | |
| videoteeSrcPad = videotee.request_pad_simple("src_%u") | |
| videoteeSrcPad.link(videoBin3_sinkpad) | |
| videoBin3Pad: Gst.Pad = videoBin3.get_static_pad("src") | |
| video3Pad = hlssink.request_pad_simple("video_%u") | |
| v = Gst.Structure.new_empty("video3") | |
| v.set_value("uri", "low/video.m3u8") | |
| v.set_value("bandwidth", 700) | |
| if not iframe: | |
| v.set_value("audio", "aac") | |
| else: | |
| v.set_value("is-i-frame", True) | |
| video3Pad.set_property("variant", v) | |
| videoBin3Pad.link(video3Pad) | |
| debugDumpPipeline("setup-done") | |
| def singleAudioRenditionMultipleVideoVariant(): | |
| global pipeline | |
| hlssink: Gst.Element = Gst.ElementFactory.make("hlssink4") | |
| hlssink.set_property("master-playlist-location", "hlssink/master.m3u8") | |
| hlssink.set_property("playlist-type", "event") | |
| hlssink.set_property("target-duration", 10) | |
| pipeline.add(hlssink) | |
| (audiotee, videotee) = fileSourceBin(pipeline) | |
| audioBin1: Gst.Bin = audioBin(256000) | |
| pipeline.add(audioBin1) | |
| audioBin1_sinkpad = audioBin1.get_static_pad("sink") | |
| audioteeSrcPad = audiotee.request_pad_simple("src_%u") | |
| audioteeSrcPad.link(audioBin1_sinkpad) | |
| audioBin1Pad: Gst.Pad = audioBin1.get_static_pad("src") | |
| audio1Pad = hlssink.request_pad_simple("audio_%u") | |
| r = Gst.Structure.new_empty("audio1") | |
| r.set_value("media_type", "AUDIO") | |
| r.set_value("uri", "hi-audio/audio.m3u8") | |
| r.set_value("group_id", "aac") | |
| r.set_value("language", "en") | |
| r.set_value("name", "English") | |
| r.set_value("default", True) | |
| r.set_value("autoselect", False) | |
| audio1Pad.set_property("alternate-rendition", r) | |
| audioBin1Pad.link(audio1Pad) | |
| videoBin1: Gst.Bin = videoBin(1920, 1080, 30, 2500, False) | |
| pipeline.add(videoBin1) | |
| videoBin1_sinkpad = videoBin1.get_static_pad("sink") | |
| videoteeSrcPad = videotee.request_pad_simple("src_%u") | |
| videoteeSrcPad.link(videoBin1_sinkpad) | |
| videoBin1Pad: Gst.Pad = videoBin1.get_static_pad("src") | |
| video1Pad = hlssink.request_pad_simple("video_%u") | |
| v = Gst.Structure.new_empty("video1") | |
| v.set_value("uri", "hi/video.m3u8") | |
| v.set_value("bandwidth", 2500) | |
| v.set_value("audio", "aac") | |
| video1Pad.set_property("variant", v) | |
| videoBin1Pad.link(video1Pad) | |
| videoBin2: Gst.Bin = videoBin(1280, 720, 30, 1500, False) | |
| pipeline.add(videoBin2) | |
| videoBin2_sinkpad = videoBin2.get_static_pad("sink") | |
| videoteeSrcPad = videotee.request_pad_simple("src_%u") | |
| videoteeSrcPad.link(videoBin2_sinkpad) | |
| videoBin2Pad: Gst.Pad = videoBin2.get_static_pad("src") | |
| video2Pad = hlssink.request_pad_simple("video_%u") | |
| v = Gst.Structure.new_empty("video2") | |
| v.set_value("uri", "mid/video.m3u8") | |
| v.set_value("bandwidth", 1500) | |
| v.set_value("audio", "aac") | |
| video2Pad.set_property("variant", v) | |
| videoBin2Pad.link(video2Pad) | |
| videoBin3: Gst.Bin = videoBin(640, 360, 24, 700, False) | |
| pipeline.add(videoBin3) | |
| videoBin3_sinkpad = videoBin3.get_static_pad("sink") | |
| videoteeSrcPad = videotee.request_pad_simple("src_%u") | |
| videoteeSrcPad.link(videoBin3_sinkpad) | |
| videoBin3Pad: Gst.Pad = videoBin3.get_static_pad("src") | |
| video3Pad = hlssink.request_pad_simple("video_%u") | |
| v = Gst.Structure.new_empty("video3") | |
| v.set_value("uri", "low/video.m3u8") | |
| v.set_value("bandwidth", 700) | |
| v.set_value("audio", "aac") | |
| video3Pad.set_property("variant", v) | |
| videoBin3Pad.link(video3Pad) | |
| debugDumpPipeline("setup-done") | |
| def multipleAudioRenditionSingleVideoVariant(): | |
| global pipeline | |
| hlssink: Gst.Element = Gst.ElementFactory.make("hlssink4") | |
| hlssink.set_property("master-playlist-location", "hlssink/master.m3u8") | |
| hlssink.set_property("playlist-type", "event") | |
| hlssink.set_property("target-duration", 10) | |
| pipeline.add(hlssink) | |
| (audiotee, videotee) = fileSourceBin(pipeline) | |
| audioBin1: Gst.Bin = audioBin(256000) | |
| pipeline.add(audioBin1) | |
| audioBin1_sinkpad = audioBin1.get_static_pad("sink") | |
| audioteeSrcPad = audiotee.request_pad_simple("src_%u") | |
| audioteeSrcPad.link(audioBin1_sinkpad) | |
| audioBin1Pad: Gst.Pad = audioBin1.get_static_pad("src") | |
| audio1Pad = hlssink.request_pad_simple("audio_%u") | |
| r = Gst.Structure.new_empty("audio1") | |
| r.set_value("media_type", "AUDIO") | |
| r.set_value("uri", "hi-audio/audio.m3u8") | |
| r.set_value("group_id", "aac") | |
| r.set_value("language", "en") | |
| r.set_value("name", "English") | |
| r.set_value("default", True) | |
| r.set_value("autoselect", False) | |
| audio1Pad.set_property("alternate-rendition", r) | |
| audioBin1Pad.link(audio1Pad) | |
| audioBin2: Gst.Bin = audioBin(128000) | |
| pipeline.add(audioBin2) | |
| audioBin2_sinkpad = audioBin2.get_static_pad("sink") | |
| audioteeSrcPad = audiotee.request_pad_simple("src_%u") | |
| audioteeSrcPad.link(audioBin2_sinkpad) | |
| audioBin2Pad: Gst.Pad = audioBin2.get_static_pad("src") | |
| audio2Pad = hlssink.request_pad_simple("audio_%u") | |
| r = Gst.Structure.new_empty("audio2") | |
| r.set_value("media_type", "AUDIO") | |
| r.set_value("uri", "mid-audio/audio.m3u8") | |
| r.set_value("group_id", "aac") | |
| r.set_value("name", "Hindu") | |
| r.set_value("language", "hi") | |
| r.set_value("default", False) | |
| r.set_value("autoselect", True) | |
| audio2Pad.set_property("alternate-rendition", r) | |
| audioBin2Pad.link(audio2Pad) | |
| audioBin3: Gst.Bin = audioBin(64000) | |
| pipeline.add(audioBin3) | |
| audioBin3_sinkpad = audioBin3.get_static_pad("sink") | |
| audioteeSrcPad = audiotee.request_pad_simple("src_%u") | |
| audioteeSrcPad.link(audioBin3_sinkpad) | |
| audioBin3Pad: Gst.Pad = audioBin3.get_static_pad("src") | |
| audio3Pad = hlssink.request_pad_simple("audio_%u") | |
| r = Gst.Structure.new_empty("audio3") | |
| r.set_value("media_type", "AUDIO") | |
| r.set_value("uri", "low-audio/audio.m3u8") | |
| r.set_value("group_id", "aac") | |
| r.set_value("name", "Danish") | |
| r.set_value("language", "da") | |
| r.set_value("default", False) | |
| r.set_value("autoselect", True) | |
| audio3Pad.set_property("alternate-rendition", r) | |
| audioBin3Pad.link(audio3Pad) | |
| videoBin1: Gst.Bin = videoBin(1920, 1080, 30, 2500, False) | |
| pipeline.add(videoBin1) | |
| videoBin1_sinkpad = videoBin1.get_static_pad("sink") | |
| videoteeSrcPad = videotee.request_pad_simple("src_%u") | |
| videoteeSrcPad.link(videoBin1_sinkpad) | |
| videoBin1Pad: Gst.Pad = videoBin1.get_static_pad("src") | |
| video1Pad = hlssink.request_pad_simple("video_%u") | |
| v = Gst.Structure.new_empty("video1") | |
| v.set_value("uri", "hi/video.m3u8") | |
| v.set_value("bandwidth", 2500) | |
| v.set_value("audio", "aac") | |
| video1Pad.set_property("variant", v) | |
| videoBin1Pad.link(video1Pad) | |
| debugDumpPipeline("setup-done") | |
| def singleAudioOnlyVariantMultipleVideoVariantWithAudioVideoMuxed(): | |
| global pipeline | |
| hlssink: Gst.Element = Gst.ElementFactory.make("hlssink4") | |
| hlssink.set_property("master-playlist-location", "hlssink/master.m3u8") | |
| hlssink.set_property("playlist-type", "event") | |
| hlssink.set_property("target-duration", 10) | |
| hlssink.set_property("muxer-type", "mpegts") | |
| pipeline.add(hlssink) | |
| (audiotee, videotee) = fileSourceBin(pipeline) | |
| videoBin1: Gst.Bin = videoBin(1920, 1080, 30, 2500, False) | |
| pipeline.add(videoBin1) | |
| videoBin1_sinkpad = videoBin1.get_static_pad("sink") | |
| videoteeSrcPad = videotee.request_pad_simple("src_%u") | |
| videoteeSrcPad.link(videoBin1_sinkpad) | |
| videoBin1Pad: Gst.Pad = videoBin1.get_static_pad("src") | |
| video1Pad = hlssink.request_pad_simple("video_%u") | |
| v = Gst.Structure.new_empty("video1") | |
| v.set_value("uri", "hi/video.m3u8") | |
| v.set_value("bandwidth", 2500) | |
| video1Pad.set_property("variant", v) | |
| videoBin1Pad.link(video1Pad) | |
| videoBin2: Gst.Bin = videoBin(1280, 720, 30, 1500, False) | |
| pipeline.add(videoBin2) | |
| videoBin2_sinkpad = videoBin2.get_static_pad("sink") | |
| videoteeSrcPad = videotee.request_pad_simple("src_%u") | |
| videoteeSrcPad.link(videoBin2_sinkpad) | |
| videoBin2Pad: Gst.Pad = videoBin2.get_static_pad("src") | |
| video2Pad = hlssink.request_pad_simple("video_%u") | |
| v = Gst.Structure.new_empty("video2") | |
| v.set_value("uri", "mid/video.m3u8") | |
| v.set_value("bandwidth", 1500) | |
| video2Pad.set_property("variant", v) | |
| videoBin2Pad.link(video2Pad) | |
| audioBin1: Gst.Bin = audioBin(256000) | |
| pipeline.add(audioBin1) | |
| audioBin1_sinkpad = audioBin1.get_static_pad("sink") | |
| audioteeSrcPad = audiotee.request_pad_simple("src_%u") | |
| audioteeSrcPad.link(audioBin1_sinkpad) | |
| audioBin1Pad: Gst.Pad = audioBin1.get_static_pad("src") | |
| audio1Pad = hlssink.request_pad_simple("audio_%u") | |
| v = Gst.Structure.new_empty("audio1") | |
| v.set_value("uri", "hi/video.m3u8") | |
| v.set_value("bandwidth", 256000) | |
| audio1Pad.set_property("variant", v) | |
| audioBin1Pad.link(audio1Pad) | |
| audioBin2: Gst.Bin = audioBin(128000) | |
| pipeline.add(audioBin2) | |
| audioBin2_sinkpad = audioBin2.get_static_pad("sink") | |
| audioteeSrcPad = audiotee.request_pad_simple("src_%u") | |
| audioteeSrcPad.link(audioBin2_sinkpad) | |
| audioBin2Pad: Gst.Pad = audioBin2.get_static_pad("src") | |
| audio2Pad = hlssink.request_pad_simple("audio_%u") | |
| v = Gst.Structure.new_empty("audio2") | |
| v.set_value("uri", "mid/video.m3u8") | |
| v.set_value("bandwidth", 128000) | |
| audio2Pad.set_property("variant", v) | |
| audioBin2Pad.link(audio2Pad) | |
| audioBin3: Gst.Bin = audioBin(64000) | |
| pipeline.add(audioBin3) | |
| audioBin3_sinkpad = audioBin3.get_static_pad("sink") | |
| audioteeSrcPad = audiotee.request_pad_simple("src_%u") | |
| audioteeSrcPad.link(audioBin3_sinkpad) | |
| audioBin3Pad: Gst.Pad = audioBin3.get_static_pad("src") | |
| audio3Pad = hlssink.request_pad_simple("audio_%u") | |
| v = Gst.Structure.new_empty("audio3") | |
| v.set_value("uri", "low-audio/audio-only.m3u8") | |
| v.set_value("bandwidth", 64000) | |
| audio3Pad.set_property("variant", v) | |
| audioBin3Pad.link(audio3Pad) | |
| debugDumpPipeline("setup-done") | |
| def main(_args) -> int: | |
| global glibMainLoop | |
| global pipeline | |
| global hlsTestFile | |
| file = sys.argv[1] | |
| if not os.path.exists(file): | |
| print("File not found") | |
| return 0 | |
| if not hasVideoAudio(file): | |
| print("File must have audio video") | |
| return 0 | |
| hlsTestFile = file | |
| print("Using file for hlssink4 testing: ", hlsTestFile) | |
| glibMainLoop = GLib.MainLoop() | |
| signal.signal(signal.SIGINT, sigintHandler) | |
| pipeline = Gst.Pipeline.new() | |
| multipleAudioRenditionMultipleVideoVariant() | |
| # multipleAudioRenditionSingleVideoVariant() | |
| # multipleAudioRenditionMultipleVideoVariant(True) | |
| # singleAudioRenditionMultipleVideoVariant() | |
| # singleAudioOnlyVariantMultipleVideoVariantWithAudioVideoMuxed() | |
| bus = pipeline.get_bus() | |
| bus.add_watch(GLib.PRIORITY_DEFAULT, busMessage, glibMainLoop) | |
| pipeline.set_state(Gst.State.PLAYING) | |
| debugDumpPipeline("playing") | |
| glibMainLoop.run() | |
| pipeline.set_state(Gst.State.NULL) | |
| log("Exited GLib main loop") | |
| return 0 | |
| if __name__ == "__main__": | |
| sys.exit(main(sys.argv)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment