Skip to content

Instantly share code, notes, and snippets.

@damonlynch
Created July 6, 2017 23:46
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 damonlynch/630224ac1c472cb73bc17b260e3cc5fb to your computer and use it in GitHub Desktop.
Save damonlynch/630224ac1c472cb73bc17b260e3cc5fb to your computer and use it in GitHub Desktop.
problematic gstreamer frame extraction
def get_video_frame(full_file_name: str,
offset: Optional[float]=5.0,
caps=Gst.Caps.from_string('image/png')) -> Optional[bytes]:
"""
Source: https://gist.github.com/dplanella/5563018
:param full_file_name: file and path of the video
:param offset:
:param caps:
:return: gstreamer buffer
"""
logging.debug("Using gstreamer to generate thumbnail from %s", full_file_name)
pipeline = Gst.parse_launch('playbin')
pipeline.props.uri = 'file://{}'.format(pathname2url(os.path.abspath(full_file_name)))
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)
# Seek offset seconds into the video, if the video is long enough
# If video is shorter than offset, seek 0.25 seconds less than the duration,
# but always at least zero.
offset = max(
min(
pipeline.query_duration(Gst.Format.TIME)[1] - Gst.SECOND / 4, offset * Gst.SECOND
), 0
)
try:
assert pipeline.seek_simple(Gst.Format.TIME, Gst.SeekFlags.FLUSH, offset)
except AssertionError:
return None
# Wait for seek to finish.
pipeline.get_state(Gst.CLOCK_TIME_NONE)
sample = pipeline.emit('convert-sample', caps)
if sample is not None:
buffer = sample.get_buffer()
pipeline.set_state(Gst.State.NULL)
return buffer.extract_dup(0, buffer.get_size())
else:
return None
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment