通过构建不同的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。