Last active
October 12, 2023 12:26
-
-
Save jb-alvarado/aa43dd005137e859e6418aac0de1e31b to your computer and use it in GitHub Desktop.
gstreamer python snips
This file contains 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 gi | |
from urllib.parse import quote | |
gi.require_version('Gst', '1.0') | |
gi.require_version('GLib', '2.0') | |
from gi.repository import GLib, Gst | |
# mode debugging infos | |
Gst.debug_set_active(True) | |
Gst.debug_set_default_threshold(3) | |
Gst.init(None) | |
playlist = [ | |
'/home/user/dev/python/adtv.mp4', | |
'/home/user/dev/python/voice.mp4', | |
'/home/user/dev/python/andacht.mp4', | |
] | |
playbin = Gst.ElementFactory.make('playbin', 'playbin') | |
def on_about_to_finish(*args): | |
url = quote(playlist.pop(0)) | |
playbin.set_property('uri', 'file://' + url) | |
playbin.connect('about-to-finish', on_about_to_finish) | |
url = quote(playlist.pop(0)) | |
playbin.set_property('uri', 'file://' + url) | |
playbin.seek_simple(Gst.Format.TIME, Gst.SeekFlags.FLUSH, 10 * Gst.SECOND) | |
playbin.set_state(Gst.State.PLAYING) | |
loop = GLib.MainLoop() | |
loop.run() |
This file contains 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 gi | |
import os | |
import sys | |
gi.require_version('Gst', '1.0') | |
gi.require_version('GLib', '2.0') | |
from gi.repository import GLib, Gst | |
""" | |
This example is not working!!! | |
""" | |
current_dir = os.path.dirname(os.path.realpath(__file__)) | |
os.environ["GST_DEBUG_DUMP_DOT_DIR"] = current_dir | |
os.putenv('GST_DEBUG_DUMP_DIR_DIR', current_dir) | |
os.putenv('GST_DEBUG_NO_COLOR', "1") | |
os.putenv('GST_DEBUG_FILE', current_dir + '/debug.log') | |
# mode debugging infos | |
Gst.debug_set_active(True) | |
Gst.debug_set_default_threshold(6) | |
Gst.init(None) | |
# callback link pads | |
def on_new_decoded_pad(dbin, pad): | |
type = pad.query_caps(None).to_string() | |
decode = pad.get_parent() | |
pipeline = decode.get_parent() | |
if type.startswith("video"): | |
video_queue = pipeline.get_by_name("video_queue") | |
decode.link(video_queue) | |
print("linked video") | |
if type.startswith("audio"): | |
audio_queue = pipeline.get_by_name("audio_queue") | |
decode.link(audio_queue) | |
print("linked audio") | |
playlist = [ | |
'file:///home/user/dev/python/adtv.mp4', | |
'file:///home/user/dev/python/voice.mp4', | |
'file:///home/user/dev/python/andacht.mp4', | |
] | |
pipe = Gst.Pipeline.new('pipleline') | |
uri = Gst.ElementFactory.make('uridecodebin3', "uri") | |
video_queue = Gst.ElementFactory.make('queue', 'video_queue') | |
audio_queue = Gst.ElementFactory.make('queue', 'audio_queue') | |
video_convert = Gst.ElementFactory.make('videoconvert', "video_convert") | |
audio_convert = Gst.ElementFactory.make('audioconvert', 'audio_convert') | |
video_sink = Gst.ElementFactory.make('autovideosink', 'video_sink') | |
audio_sink = Gst.ElementFactory.make('autoaudiosink', 'audio_sink') | |
pipe.add(uri) | |
pipe.add(video_queue) | |
pipe.add(audio_queue) | |
pipe.add(video_convert) | |
pipe.add(audio_convert) | |
pipe.add(video_sink) | |
pipe.add(audio_sink) | |
video_queue.link(video_convert) | |
audio_queue.link(audio_convert) | |
video_convert.link(video_sink) | |
audio_convert.link(audio_sink) | |
def on_about_to_finish(*args): | |
uri.set_property('uri', playlist.pop(0)) | |
uri.connect('pad-added', on_new_decoded_pad) | |
# link decoder to coresponding queue | |
uri.connect('pad-added', on_new_decoded_pad) | |
uri.connect('about-to-finish', on_about_to_finish) | |
uri.set_property('uri', playlist.pop(0)) | |
Gst.debug_bin_to_dot_file( | |
pipe, | |
Gst.DebugGraphDetails.ALL, | |
'debug-graph') | |
# playbin.seek_simple(Gst.Format.TIME, Gst.SeekFlags.FLUSH, 10 * Gst.SECOND) | |
pipe.set_state(Gst.State.PLAYING) | |
loop = GLib.MainLoop() | |
loop.run() |
Yes I did, but all end in the conclusion that it is more difficult to have A/V sync and it needed more resources then my ffmpeg solution.
A really interesting project is FFdynamic. I think a playout solution based on that could be more powerful. But I'm not a c++ developer, so is more difficult for me to dive in.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@jb-alvarado I'm curious if you did any further experiments using gstreamer and playlists/playlist handling in addition to this gist. Obviously you've done a lot of interesting work using ffmpeg and your ffmpeg playout engine repo :-)