用gstreamer抓取视频的缩略图

通过构建不同的gstreamer管道,可以有多种方法来抓取视频文件中的缩略图,以下作一简单介绍。

1、从gdkpixbufsink中获取图像 该方法通过gdkpixbufsink的"last-pixbuf"来获取图像的pixbuf。

        descr = g_strdup_printf ("uridecodebin uri=%s ! ffmpegcolorspace ! videoscale ! gdkpixbufsink name=sink", fileurl);
pipeline = gst_parse_launch (descr, &error);
if (error != NULL) {
printf ("could not construct pipeline: %s", error->message);
g_error_free (error);
return FALSE;
}

sink = gst_bin_get_by_name (GST_BIN (pipeline), "sink");

ret = gst_element_set_state (pipeline, GST_STATE_PAUSED);
switch (ret) {
case GST_STATE_CHANGE_FAILURE:
printf ("failed to play the file/n");
return FALSE;
case GST_STATE_CHANGE_NO_PREROLL:
printf ("live sources not supported yet/n");
return FALSE;
default:
break;
}

ret = gst_element_get_state (pipeline, NULL, NULL, 5 * GST_SECOND);
if (ret == GST_STATE_CHANGE_FAILURE) {
printf ("failed to play the file/n");
return FALSE;
}

format = GST_FORMAT_TIME;
gst_element_query_duration (pipeline, &format, &duration);

if (duration != -1)
position = duration * 1 / 100;
else
position = 1 * GST_SECOND;

gst_element_seek_simple (pipeline, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, position);
g_object_get (G_OBJECT (sink), "last-pixbuf", &pixbuf, NULL);
if(pixbuf) {
width = gdk_pixbuf_get_width(pixbuf);
height = gdk_pixbuf_get_height(pixbuf);
gdk_pixbuf_save (pixbuf, snapshot_name, "jpeg", &error, NULL);
}

gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref (pipeline);

2、通过appsink获取图像 与第一种方法不同的是采用了appsink插件,利用其"pull-preroll"事件来获取图像Buffer,随后把GST_BUFFER_DATA转换为需要的pixbuf。
下面贴出与方法1不同的部分代码:

       descr = g_strdup_printf ("uridecodebin uri=%s ! ffmpegcolorspace ! videoscale ! appsink name=sink", fileurl);
........
g_signal_emit_by_name (sink, "pull-preroll", &buffer, NULL);

if (buffer) {
GstCaps *caps;
GstStructure *s;

caps = GST_BUFFER_CAPS (buffer);
if (!caps) {
printf ("could not get snapshot format/n");
return FALSE;
}
s = gst_caps_get_structure (caps, 0);

res = gst_structure_get_int (s, "width", &width);
res |= gst_structure_get_int (s, "height", &height);

if (!res) {
printf ("could not get snapshot dimension/n");
return FALSE;
}

pixbuf = gdk_pixbuf_new_from_data (GST_BUFFER_DATA (buffer),
GDK_COLORSPACE_RGB, FALSE, 8, width, height,
GST_BUFFER_SIZE (buffer)/height, NULL, NULL);
............

3、利用playbin来获取图像 利用playbin的"frame"属性来获取图像buffer。然后将buffer通过colorspace以及videoscale等转换为所需要的图像pixbuf。
totem使用的是该方法,所以此处不再赘述,详细见totem源码的gstscreenshot.c。

你可能感兴趣的:(object,null,query,buffer,Signal,structure)