Last active
November 11, 2022 16:59
-
-
Save virtuald/0aa9f7e30ed82c0270de to your computer and use it in GitHub Desktop.
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
# | |
# Playbin bug: Play 2 flac files (presumably of any length), and play | |
# 2 mp3 files, using gapless playback, and weirdness happens | |
# | |
# On GST 1.4.5, track4.mp3 stalls for ~10s or so without playing, but | |
# there is no audio for track3 or track4. Other tests I've conducted | |
# track3 does have audio, but there is still a pause. | |
# | |
# On GST 1.5.2, there is no volume for track3 or track4.mp3, but no | |
# stall occurs. Seems like a bug. | |
# | |
# Tested on Linux, probably using pulsesink as output. | |
# | |
from gi.repository import Gst, GObject, GLib, Gio | |
Gst.init(None) | |
playbin = Gst.ElementFactory.make('playbin') | |
playbin.props.volume = .2 | |
uris = [ | |
'track1.flac', | |
'track2.flac', | |
'track3.mp3', | |
'track4.mp3' | |
] | |
# Convert to uri | |
for i in range(len(uris)): | |
uris[i] = Gio.File.new_for_commandline_arg(uris[i]).get_uri() | |
# Gapless playback mechanism | |
def on_about_to_finish(_): | |
try: | |
uri = uris.pop(0) | |
except: | |
ml.quit() | |
else: | |
print 'about to play', uri | |
playbin.set_property('uri', uri) | |
playbin.connect('about-to-finish', on_about_to_finish) | |
# Print the current stream position every second | |
def query_pos(): | |
res, pos = playbin.query_position(Gst.Format.TIME) | |
if res: | |
print 'pos: %.02f' % (float(pos)/Gst.SECOND) | |
return True | |
GLib.timeout_add(1000, query_pos) | |
# Originally, we noticed that the pipeline stall only happened | |
# when a seek occurred. | |
def do_skip(): | |
new_position = int(Gst.SECOND * 3) | |
seek_event = Gst.Event.new_seek(1.0, Gst.Format.TIME, | |
Gst.SeekFlags.FLUSH, Gst.SeekType.SET, | |
new_position, | |
Gst.SeekType.NONE, 0) | |
playbin.send_event(seek_event) | |
print 'seek!' | |
return False | |
GLib.timeout_add(13000, do_skip) | |
# Start it up | |
on_about_to_finish(None) | |
playbin.set_state(Gst.State.PLAYING) | |
ml = GObject.MainLoop() | |
ml.run() | |
print 'Done' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment