Last active
September 13, 2017 08:19
-
-
Save dplanella/5563018 to your computer and use it in GitHub Desktop.
A snippet to create thumbnails from video files, using GStreamer and Python. Original author: [daf](http://stackoverflow.com/users/32082/daf) via http://stackoverflow.com/a/16478342/1049318
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
# Video thumbnailer, non-PyGI version, working as expected | |
import os | |
import sys | |
import gst | |
def get_frame(path, offset=5, caps=gst.Caps('image/png')): | |
pipeline = gst.parse_launch('playbin2') | |
pipeline.props.uri = 'file://' + os.path.abspath(path) | |
pipeline.props.audio_sink = gst.element_factory_make('fakesink') | |
pipeline.props.video_sink = gst.element_factory_make('fakesink') | |
pipeline.set_state(gst.STATE_PAUSED) | |
# Wait for state change to finish. | |
pipeline.get_state() | |
assert pipeline.seek_simple( | |
gst.FORMAT_TIME, gst.SEEK_FLAG_FLUSH, offset * gst.SECOND) | |
# Wait for seek to finish. | |
pipeline.get_state() | |
buffer = pipeline.emit('convert-frame', caps) | |
pipeline.set_state(gst.STATE_NULL) | |
return buffer | |
def main(): | |
buf = get_frame(sys.argv[1]) | |
with file('frame.png', 'w') as fh: | |
fh.write(bytes(buf)) | |
if __name__ == '__main__': | |
main() |
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
# Video thumbnailer, PyGI version, not working (creates unreadable thumbnails) | |
import os | |
import sys | |
import gi | |
gi.require_version('Gst', '1.0') | |
from gi.repository import GObject, Gst | |
Gst.init(None) | |
def get_frame(path, offset=5, caps=Gst.Caps.from_string('image/png')): | |
pipeline = Gst.parse_launch('playbin') | |
pipeline.props.uri = 'file://' + os.path.abspath(path) | |
pipeline.props.audio_sink = Gst.ElementFactory.make('fakesink', 'fakeaudio') | |
pipeline.props.video_sink = Gst.ElementFactory.make('fakesink', 'fakevideo') | |
pipeline.set_state(Gst.State.PAUSED) | |
# Wait for state change to finish. | |
pipeline.get_state(Gst.CLOCK_TIME_NONE) | |
assert pipeline.seek_simple( | |
Gst.Format.TIME, Gst.SeekFlags.FLUSH, offset * Gst.SECOND) | |
# Wait for seek to finish. | |
pipeline.get_state(Gst.CLOCK_TIME_NONE) | |
buffer = pipeline.emit('convert-sample', caps).get_buffer() | |
pipeline.set_state(Gst.State.NULL) | |
return buffer | |
def main(): | |
buf = get_frame(sys.argv[1]) | |
with file('frame.png', 'w') as fh: | |
# This (i.e. getting the data from the buffer) does not work. See https://bugzilla.gnome.org/show_bug.cgi?id=678663 | |
fh.write(bytes(buf)) | |
if __name__ == '__main__': | |
main() |
This seems to have broken in a recent version of gstreamer?
I can't get it work with mp4 file which is h264 (High profile) / AAC. But this works with webm file.
convert-sample returns None in mp4's case.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
As stated bytes(buf) doesn't work, so you will have to do it another way:
Also as wongcc966422 said, you will need 'wb' file mode on Windows. It works with 'w' on Linux for me.