目标

Clutter是一个开源的库,用来创建快速、可移植和动态的GUI。GStreamer可以通过cluttersink这个element把clutter集成进来,允许视频像纹理一样使用。本教程会展示:

如何把GStreamer pipeline的视频输出在clutter里面作为纹理来处理

介绍

连接GStreamer和clutter的流程实际上非常简单。我们必须使用cluttersink这个element(或者autocluttersink)并把它作为视频的sink。通过texture这个属性,这个element接受一个被GStreamer刷新的clutter的纹理。

一个3D的媒体播放器

[objc] view
plain
 copy

  1. <span style="font-size:14px;">#include <clutter-gst/clutter-gst.h>
  2. /* Setup the video texture once its size is known */
  3. void size_change (ClutterActor *texture, gint width, gint height, gpointer user_data) {
  4. ClutterActor *stage;
  5. gfloat new_x, new_y, new_width, new_height;
  6. gfloat stage_width, stage_height;
  7. ClutterAnimation *animation = NULL;
  8. stage = clutter_actor_get_stage (texture);
  9. if (stage == NULL)
  10. return;
  11. clutter_actor_get_size (stage, &stage_width, &stage_height);
  12. /* Center video on window and calculate new size preserving aspect ratio */
  13. new_height = (height * stage_width) / width;
  14. if (new_height <= stage_height) {
  15. new_width = stage_width;
  16. ;
  17. ;
  18. } else {
  19. new_width  = (width * stage_height) / height;
  20. new_height = stage_height;
  21. ;
  22. ;
  23. }
  24. clutter_actor_set_position (texture, new_x, new_y);
  25. clutter_actor_set_size (texture, new_width, new_height);
  26. .0, stage_width / 2, 0, 0);
  27. /* Animate it */
  28. 0000, "rotation-angle-y", 360.0, NULL);
  29. clutter_animation_set_loop (animation, TRUE);
  30. }
  31. int main(int argc, charchar *argv[]) {
  32. GstElement *pipeline, *sink;
  33. ClutterTimeline *timeline;
  34. ClutterActor *stage, *texture;
  35. /* clutter-gst takes care of initializing Clutter and GStreamer */
  36. if (clutter_gst_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) {
  37. g_error ("Failed to initialize clutter\n");
  38. ;
  39. }
  40. stage = clutter_stage_get_default ();
  41. /* Make a timeline */
  42. 000);
  43. g_object_set(timeline, "loop", TRUE, NULL);
  44. /* Create new texture and disable slicing so the video is properly mapped onto it */
  45. texture = CLUTTER_ACTOR (g_object_new (CLUTTER_TYPE_TEXTURE, "disable-slicing", TRUE, NULL));
  46. g_signal_connect (texture, "size-change", G_CALLBACK (size_change), NULL);
  47. /* Build the GStreamer pipeline */
  48. pipeline = gst_parse_launch ("playbin2 uri=http://docs.gstreamer.com/media/sintel_trailer-480p.webm", NULL);
  49. /* Instantiate the Clutter sink */
  50. sink = gst_element_factory_make ("autocluttersink", NULL);
  51. if (sink == NULL) {
  52. /* Revert to the older cluttersink, in case autocluttersink was not found */
  53. sink = gst_element_factory_make ("cluttersink", NULL);
  54. }
  55. if (sink == NULL) {
  56. g_printerr ("Unable to find a Clutter sink.\n");
  57. ;
  58. }
  59. /* Link GStreamer with Clutter by passing the Clutter texture to the Clutter sink*/
  60. g_object_set (sink, "texture", texture, NULL);
  61. /* Add the Clutter sink to the pipeline */
  62. g_object_set (pipeline, "video-sink", sink, NULL);
  63. /* Start playing */
  64. gst_element_set_state (pipeline, GST_STATE_PLAYING);
  65. /* start the timeline */
  66. clutter_timeline_start (timeline);
  67. /* Add texture to the stage, and show it */
  68. clutter_group_add (CLUTTER_GROUP (stage), texture);
  69. clutter_actor_show_all (stage);
  70. clutter_main();
  71. /* Free resources */
  72. gst_element_set_state (pipeline, GST_STATE_NULL);
  73. gst_object_unref (pipeline);
  74. ;
  75. }
  76. </span>

工作流程

这篇教程的目的不是教你如何使用clutter,而是如何把它集成到GStreamer里来。这个工作通过clutter-gst库来完成,所以它的头文件必须包含进来。

[objc] view
plain
 copy

  1. <span style="font-size:14px;">#include <clutter-gst/clutter-gst.h></span>

这个库的第一件事是初始化GStreamer和Clutter,所以你调用clutter-gst-init()方法而不是自己来初始化。

[objc] view
plain
 copy

  1. /* clutter-gst takes care of initializing Clutter and GStreamer */
  2. if (clutter_gst_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) {
  3. g_error ("Failed to initialize clutter\n");
  4. ;
  5. }

GStreamer视频是作为Clutter的纹理来播放,所以我们需要创建一个纹理。请记住关闭纹理的切片:

[objc] view
plain
 copy

  1. /* Create new texture and disable slicing so the video is properly mapped onto it */
  2. texture = CLUTTER_ACTOR (g_object_new (CLUTTER_TYPE_TEXTURE, "disable-slicing", TRUE, NULL));
  3. g_signal_connect (texture, "size-change", G_CALLBACK (size_change), NULL);

我们注册size-change信号,这样我们一旦知道视频的尺寸之后就可以做最后的设置。

[objc] view
plain
 copy

  1. /* Instantiate the Clutter sink */
  2. sink = gst_element_factory_make ("autocluttersink", NULL);
  3. if (sink == NULL) {
  4. /* Revert to the older cluttersink, in case autocluttersink was not found */
  5. sink = gst_element_factory_make ("cluttersink", NULL);
  6. }
  7. if (sink == NULL) {
  8. g_printerr ("Unable to find a Clutter sink.\n");
  9. ;
  10. }

正确创建的Clutter sink element是autocluttersink,这个element工作起来或多或少的像autovideosink。然而,autocluttersink在2012.7后发布的SDK里面才有,如果找不到这个element,那么创建cluttersink来代替。

[objc] view
plain
 copy

  1. /* Link GStreamer with Clutter by passing the Clutter texture to the Clutter sink*/
  2. g_object_set (sink, "texture", texture, NULL);

这个纹理是GStreamer唯一需要了解的关于Clutter的内容。

[objc] view
plain
 copy

  1. /* Add the Clutter sink to the pipeline */
  2. g_object_set (pipeline, "video-sink", sink, NULL);

最后,告诉playbin2使用我们创建的sink而不是默认的。

然后GStreamer的pipeline和Clutter的timeline就开始工作了。一旦pipeline获得了视频的尺寸,我们在收到一个通知后更新Clutter的纹理,调用size_change的回调。这个方法会把纹理设置正确地尺寸,把它输出到窗口的中心然后开始做动画旋转(仅供演示使用),当然,这个和GStreamer就没有任何关系了。

【GStreamer开发】GStreamer基础教程15——继承Clutter的更多相关文章

  1. Android程序开发0基础教程(一)

    程序猿学英语就上视觉英语网 Android程序开发0基础教程(一)   平台简单介绍   令人激动的Google手机操作系统平台-Android在2007年11月13日正式公布了,这是一个开放源码的操 ...

  2. [SQL基础教程] 1-5 表的删除和更新

    [SQL基础教程] 1-5 表的删除和更新 表的删除 语法 DROP TABLE <表名>; 法则 1-12 删除的表无法恢复 表定义的更新 语法 ALTER TABLE<表名> ...

  3. Java基础教程(18)--继承

    一.继承的概念   继承是面向对象中一个非常重要的概念,使用继承可以从逻辑和层次上更好地组织代码,大大提高代码的复用性.在Java中,继承可以使得子类具有父类的属性和方法或者重新定义.追加属性和方法. ...

  4. JPA 菜鸟教程 15 继承-一个表-SINGLE_TABLE

    原地址:http://blog.csdn.net/JE_GE/article/details/53678422 继承映射策略 一个类继承结构一个表的策略,最终只生成一个表,这是继承映射的默认策略. 举 ...

  5. python开发面向对象基础:组合&继承

    一,组合 组合指的是,在一个类中以另外一个类的对象作为数据属性,称为类的组合      人类装备了武器类就是组合 1.圆环,将圆类实例后传给圆环类 #!/usr/bin/env python #_*_ ...

  6. iOS开发零基础教程之生成git所需的SSH keys

    在我们github看到了一个不错的第三方库时,可能我们想把他git clone到本地,我们需要复制他的SSH URL,如下图: 复制完地址之后,我们需要打开终端,然后输入命令: git clone + ...

  7. Java基础教程(15)--枚举类型

      枚举类型定义了一个枚举值的列表,每个值是一个标识符.例如,下面的语句声明了一个枚举类型,用来表示星期的可能情况: public enum Day { SUNDAY, MONDAY, TUESDAY ...

  8. Ruby 基础教程1-5

    1.条件语句 if unless case        unless和if相反,条件不成立则执行   2.条件  除了 false和nil 其他都是true   3.unless 语法        ...

  9. Chrome扩展开发基础教程(附HelloWorld)

    1 概述 Chrome扩展开发的基础教程,代码基于原生JS+H5,教程内容基于谷歌扩展开发官方文档. 2 环境 Chrome 88.0.4324.96 Chromium 87.0.4280.141 B ...

随机推荐

  1. 本地存储API

    一.定义 随着互联网的快速发展,基于网页的应用越来越普遍,同时也变得越来越复杂,为了满足各种各样的需求,会经常在本地存储大量的数据,HTML5规范提出了相关解决方案 本地存储设置读取方便,容量较大,s ...

  2. 2019暑期金华集训 Day6 杂题选讲

    自闭集训 Day6 杂题选讲 CF round 469 E 发现一个数不可能取两次,因为1,1不如1,2. 发现不可能选一个数的正负,因为1,-1不如1,-2. hihoCoder挑战赛29 D 设\ ...

  3. BFC、IFC、FFC、GFC

    FC(Formatting Context) 它是W3C CSS2.1规范中的一个概念,定义的是页面中的一块渲染区域,并且有一套渲染规则,它决定了其子元素将如何定位,以及和其他元素的关系和相互作用. ...

  4. getchar与putchar缓冲区以及字符串数组、指针

    getchar与putchar缓冲区 有下面的语句段: while ((s = getchar()) != '\n'){ putchar(s); putchar("\n"); } ...

  5. GO标准库flag

    Go语言内置的flag包实现了命令行参数的解析. os.Args os.Args是一个[]string类型. 获取命令参数示例: func main() { if len(os.Args) > ...

  6. 五笔字典86版wubi拆字图编码查询

    五笔字典86版 软件能查询以下数据,五笔编码,汉字拆字图,拼音,部首,笔划,笔顺,解释,五笔口诀等等.这些数据只针对单个汉字查询(大概7000字左右).词组查询只支持五笔编码查询(有60000个词组+ ...

  7. python中whl的讲解

    whl 格式:这是一个压缩包,在其中包含了py文件,以及经过编译的pyd文件. 这个格式可以使文件在不具备编译环境的情况下,选择合适自己的python环境进行安装. 安装方法如下 进入命令行输入:pi ...

  8. 树莓派连接18b20测温度

    树莓派系统包含了18b20的驱动(1-wire interface),我们只需要将其开启即可.有两种开启方式: 方式一:输入raspi-config命令,然后在interfacing options ...

  9. docker在windows下上传文件到容器

    我的系统是windows10,docker是用DockerToolbox工具安装的,安装完之后会默认挂载Windows的C:/Users目录,在docker里面对应路径是/c/Users,docker ...

  10. Java基础 return 退出main方法的示例

        JDK :OpenJDK-11      OS :CentOS 7.6.1810      IDE :Eclipse 2019‑03 typesetting :Markdown   code ...