Skip to content

Instantly share code, notes, and snippets.

@sampsyo
Created July 7, 2015 03:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sampsyo/c26333a1546071d14352 to your computer and use it in GitHub Desktop.
Save sampsyo/c26333a1546071d14352 to your computer and use it in GitHub Desktop.
from __future__ import print_function
import sys
import os
import gi
gi.require_version('Gst', '1.0')
from gi.repository import GObject, Gst
def on_message(bus, message, udata):
pipeline, loop = udata
if message.type == Gst.MessageType.EOS:
pipeline.set_state(Gst.State.NULL)
loop.quit()
elif message.type == Gst.MessageType.ERROR:
print(message.parse_error())
pipeline.set_state(Gst.State.NULL)
loop.quit()
return True
def on_pad_added(element, pad, udata):
pipeline, sink = udata
pad.link(sink.get_static_pad('sink'))
# Get the duration of the source file.
duration, success = pad.query_duration(Gst.Format.TIME)
print(duration, success)
def decode(input_file):
loop = GObject.MainLoop()
pipeline = Gst.Pipeline()
uridecodebin = Gst.ElementFactory.make('uridecodebin')
sink = Gst.ElementFactory.make('fakesink')
pipeline.add(uridecodebin)
pipeline.add(sink)
uridecodebin.link(sink)
uridecodebin.set_property('uri', input_file)
uridecodebin.connect('pad-added', on_pad_added, (pipeline, sink))
bus = pipeline.get_bus()
bus.add_watch(0, on_message, (pipeline, loop))
pipeline.set_state(Gst.State.PLAYING)
loop.run()
if __name__ == '__main__':
Gst.init()
input_file = 'file://' + os.path.abspath(sys.argv[1])
decode(input_file)
@sampsyo
Copy link
Author

sampsyo commented Jul 7, 2015

This short program just opens a media file and queries its duration. It works for some files, but not for others.

Specifically, here's a file for which it works, image.mp3, and a file for which it fails, named full.mp3. Here's what happens when the script is run on the two files:

$ python getduration.py ../beets/test/rsrc/image.mp3 
True 1044897959
$ python getduration.py ../beets/test/rsrc/full.mp3
False 0

... indicating that the query_duration() call fails for the second file.

The two files are very similar: short MP3s containing one second of silence. The questions are: Why does the query fail on one file but not the other? Is there anything we can do to make it work for all files?

I got these results using GStreamer 1.4.5 on Arch Linux. The result is the same on both Python 2 and Python 3.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment