用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。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章