繁体   English   中英

如何使用Python和Gstreamer创建视频缩略图

[英]How to create video thumbnails with Python and Gstreamer

我想使用Gstreamer和Python为MPEG-4 AVC视频创建缩略图。 实质上:

  1. 打开视频文件
  2. 寻找某个时间点(例如5秒)
  3. 那时抓住框架
  4. 将帧保存为.jpg文件

我一直在看这个类似的问题 ,但我无法弄清楚如何在没有用户输入的情况下自动进行搜索和帧捕获。

总而言之,我如何按照上述步骤使用Gstreamer和Python捕获视频缩略图?

要详细说明ensonic的答案,这是一个例子:

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(str(buf))

if __name__ == '__main__':
    main()

这会生成PNG图像。 您可以使用gst.Caps("video/x-raw-rgb,bpp=24,depth=24")或类似的东西获取原始图像数据。

请注意,在GStreamer 1.0中(与0.10相反), playbin2已重命名为playbinconvert-frame信号名为convert-sample

GStreamer应用程序开发手册的这一章解释了搜索的机制。 0.10 playbin2文档似乎不再在线,但1.0的文档就在这里

Vala中的一个例子,GStreamer 1.0:

var playbin = Gst.ElementFactory.make ("playbin", null);
playbin.set ("uri", "file:///path/to/file");
// some code here.
var caps = Gst.Caps.from_string("image/png");
Gst.Sample sample;
Signal.emit_by_name(playbin, "convert-sample", caps, out sample);
if(sample == null)
    return;
var sample_caps = sample.get_caps ();
if(sample_caps == null)
    return;
unowned Gst.Structure structure = sample_caps.get_structure(0);
int width = (int)structure.get_value ("width");
int height = (int)structure.get_value ("height");
var memory = sample.get_buffer().get_memory (0);
Gst.MapInfo info;
memory.map (out info, Gst.MapFlags.READ);
uint8[] data = info.data;

这是一个古老的问题,但我仍然没有在任何地方找到它。
我发现以下内容与Gstreamer 1.0播放视频有关

import gi
import time
gi.require_version('Gst', '1.0')
from gi.repository import Gst

def get_frame():
    caps = Gst.Caps('image/png')
    pipeline = Gst.ElementFactory.make("playbin", "playbin")
    pipeline.set_property('uri','file:///home/rolf/GWPE.mp4')
    pipeline.set_state(Gst.State.PLAYING)
    #Allow time for it to start
    time.sleep(0.5)
    # jump 30 seconds
    seek_time = 30 * Gst.SECOND
    pipeline.seek(1.0, Gst.Format.TIME,(Gst.SeekFlags.FLUSH | Gst.SeekFlags.ACCURATE),Gst.SeekType.SET, seek_time , Gst.SeekType.NONE, -1)

    #Allow video to run to prove it's working, then take snapshot
    time.sleep(1)
    buffer = pipeline.emit('convert-sample', caps)
    buff = buffer.get_buffer()
    result, map = buff.map(Gst.MapFlags.READ)
    if result:
        data = map.data
        pipeline.set_state(Gst.State.NULL)
        return data
    else:
        return

if __name__ == '__main__':
    Gst.init(None)
    image = get_frame()
    with open('frame.png', 'wb') as snapshot:
        snapshot.write(image)

代码应该与Python2和Python3一起运行,我希望它可以帮助某人。

使用playbin2。 将uri设置为媒体文件,使用gst_element_seek_simple搜索所需的时间位置,然后使用g_signal_emit调用“convert-frame”动作信号。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM