目标

通过手动选择音频和视频的sink,playbin2可以进一步定制。这允许使用playbin2的应用在解码后可以自行做最终的渲染和显示。本教程展示了:

如何替换playbin2选择的sink

如何使用一个复杂的pipeline来作为sink

介绍

playbin2有两个属性:audio-sink和video-sink。应用只需要实例化合适的element然后通过这两个属性传给playbin2就行了。

这个方法只能使用一个简单地element来做sink。如果遇到的情况不是简单地element而是一个复杂的pipeline呢(比如均衡器加一个音频sink),就需要用Bin来包装一下,让playbin2感觉还是一个element。

一个Bin就是一个容器,可以容纳一部分的pipeline,但操作的时候作为一个element。例如,我们在所有教程里面用得GstPipeline就是一个不会和外面的element做交互的GstBin。在Bin里面的element通过虚拟Pad(Ghost Pads)来和外面的element交互。这也就是说,Bin上得一个pad仅仅实现把外面的element上的pad的数据传到内部的element的pad上。

GstBin也是element的一类,所以element可以用的地方,Bin也都能用,特别是,可以作为playbin2的sink。

一个均衡的播放器

[objc] view
plain
 copy

  1. #include <gst/gst.h>
  2. int main(int argc, charchar *argv[]) {
  3. GstElement *pipeline, *bin, *equalizer, *convert, *sink;
  4. GstPad *pad, *ghost_pad;
  5. GstBus *bus;
  6. GstMessage *msg;
  7. /* Initialize GStreamer */
  8. gst_init (&argc, &argv);
  9. /* Build the pipeline */
  10. pipeline = gst_parse_launch ("playbin2 uri=http://docs.gstreamer.com/media/sintel_trailer-480p.webm", NULL);
  11. /* Create the elements inside the sink bin */
  12. equalizer = gst_element_factory_make ("equalizer-3bands", "equalizer");
  13. convert = gst_element_factory_make ("audioconvert", "convert");
  14. sink = gst_element_factory_make ("autoaudiosink", "audio_sink");
  15. if (!equalizer || !convert || !sink) {
  16. g_printerr ("Not all elements could be created.\n");
  17. ;
  18. }
  19. /* Create the sink bin, add the elements and link them */
  20. bin = gst_bin_new ("audio_sink_bin");
  21. gst_bin_add_many (GST_BIN (bin), equalizer, convert, sink, NULL);
  22. gst_element_link_many (equalizer, convert, sink, NULL);
  23. pad = gst_element_get_static_pad (equalizer, "sink");
  24. ghost_pad = gst_ghost_pad_new ("sink", pad);
  25. gst_pad_set_active (ghost_pad, TRUE);
  26. gst_element_add_pad (bin, ghost_pad);
  27. gst_object_unref (pad);
  28. /* Configure the equalizer */
  29. 4.0, NULL);
  30. 4.0, NULL);
  31. /* Set playbin2's audio sink to be our sink bin */
  32. g_object_set (GST_OBJECT (pipeline), "audio-sink", bin, NULL);
  33. /* Start playing */
  34. gst_element_set_state (pipeline, GST_STATE_PLAYING);
  35. /* Wait until error or EOS */
  36. bus = gst_element_get_bus (pipeline);
  37. msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_ERROR | GST_MESSAGE_EOS);
  38. /* Free resources */
  39. if (msg != NULL)
  40. gst_message_unref (msg);
  41. gst_object_unref (bus);
  42. gst_element_set_state (pipeline, GST_STATE_NULL);
  43. gst_object_unref (pipeline);
  44. ;
  45. }

工作流程

[objc] view
plain
 copy

  1. /* Create the elements inside the sink bin */
  2. equalizer = gst_element_factory_make ("equalizer-3bands", "equalizer");
  3. convert = gst_element_factory_make ("audioconvert", "convert");
  4. sink = gst_element_factory_make ("autoaudiosink", "audio_sink");
  5. if (!equalizer || !convert || !sink) {
  6. g_printerr ("Not all elements could be created.\n");
  7. ;
  8. }

生成所有的sink bin所需要的element。我们使用了一个equalizer-3bands和一个autoaudiosink,中间还用audioconvert连接起来。

[objc] view
plain
 copy

  1. /* Create the sink bin, add the elements and link them */
  2. bin = gst_bin_new ("audio_sink_bin");
  3. gst_bin_add_many (GST_BIN (bin), equalizer, convert, sink, NULL);
  4. gst_element_link_many (equalizer, convert, sink, NULL);

这几句把新的element加到Bin里面然后连接起来,就和在pipeline中一样。

[objc] view
plain
 copy

  1. pad = gst_element_get_static_pad (equalizer, "sink");
  2. ghost_pad = gst_ghost_pad_new ("sink", pad);
  3. gst_pad_set_active (ghost_pad, TRUE);
  4. gst_element_add_pad (bin, ghost_pad);
  5. gst_object_unref (pad);

现在我们需要生成虚拟Pad,这也一部分在Bin里面的pipeline可以连接到外面。这个虚拟Pad会和内部的一个element的Pad连接起来,我们会用gst_element_get_static_pad()来获得这个Pad。如果是一个RequestPad而不是Always
Pad的话,那么我们就用get_element_request_pad()方法,具体请参考《GStreamer基础教程07——多线程和Pad的有效性

虚拟Pad用gst_ghost_pad_new()来创建,用gst_pad_set_active()来激活。然后用gst_element_add_pad()来加入Bin。

最后,我们用gst_object_unref()来释放获得的均衡器的sink pad。

在这点上,我们有一个有sink功能的Bin,可以在playbin2里面用作音频sink,我们只需要设置一下playbin2的相关属性就行了。

[objc] view
plain
 copy

  1. /* Set playbin2's audio sink to be our sink bin */
  2. g_object_set (GST_OBJECT (pipeline), "audio-sink", bin, NULL);

这和用一个sink element设置playbin2的audio-sink属性是完全一样的。

[objc] view
plain
 copy

  1. /* Configure the equalizer */
  2. 4.0, NULL);
  3. 4.0, NULL);

剩下的就是均衡器的配置了。在这个例子中,两个高频波段设置了最大的衰减,这样就增强了低音修改不同的值来实际看看效果。


【GStreamer开发】GStreamer播放教程07——自定义playbin2的sink的更多相关文章

  1. 新手编译开发OpenWrt入门教程(自定义固件、ubuntu学习)

    转自:   http://www.znck007.com/forum.php?mod=viewthread&tid=21571 由于openwrt编译教程资料很多,不同的cpu芯片只需要选择对 ...

  2. 【GStreamer开发】GStreamer基础教程13——播放速度

    目标 快进,倒放和慢放是trick模式的共同技巧,它们有一个共同点就是它们都修改了播放的速度.本教程会展示如何来获得这些效果和如何进行逐帧的跳跃.主要内容是: 如何来变换播放的速度,变快或者变慢,前进 ...

  3. 【GStreamer开发】GStreamer基础教程14——常用的element

    目标 本教程给出了一系列开发中常用的element.它们包括大杂烩般的eleemnt(比如playbin2)以及一些调试时很有用的element. 简单来说,下面用gst-launch这个工具给出一个 ...

  4. 【GStreamer开发】GStreamer基础教程10——GStreamer工具

    目标 GStreamer提供了一系列方便使用的工具.这篇教程里不牵涉任何代码,但还是会讲一些有用的内容: 如何在命令行下建立一个pipeline--完全不使用C 如何找出一个element的Capab ...

  5. 【GStreamer开发】GStreamer基础教程15——继承Clutter

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

  6. 【GStreamer开发】GStreamer基础教程12——流

    目标 直接播放Internet上的文件而不在本地保存就被称为流播放.我们在前面教程里已经这样做过了,使用了http://的URL.本教程展示的是在播放流的时候需要记住的几个点,特别是: 如何设置缓冲 ...

  7. 【GStreamer开发】GStreamer基础教程05——集成GUI工具

    目标 本教程展示了如何在GStreamer集成一个GUI(比如:GTK+).最基本的原则是GStreamer处理多媒体的播放而GUI处理和用户的交互. 在这个教程里面,我们可以学到: 如何告诉GStr ...

  8. 【GStreamer开发】GStreamer基础教程08——pipeline的快捷访问

    目标 GStreamer建立的pipeline不需要完全关闭.有多种方法可以让数据在任何时候送到pipeline中或者从pipeline中取出.本教程会展示: 如何把外部数据送到pipeline中 如 ...

  9. gstreamer应用开发(播放器)之旅

    GStreamer开发,主要分为两块:应用开发.插件开发. 插件开发人员,通常是编解码库的作者(做出了编解码库后,希望gstreamer能用起来这个库,因此增加这个适配层).芯片原厂人员(将自家的hw ...

随机推荐

  1. 在Ubuntu 或 Debian 系统环境安装MYSQL数据库

    一.第一步下载myslq安装程序 sudo apt-get install mysql-server mysql-client apt-get程序会自动下载安装最新的mysql版本.在安装的最后,它会 ...

  2. Cogs 876. 游戏(DP)

    游戏 ★ 输入文件:game1.in 输出文件:game1.out 简单对比 时间限制:1 s 内存限制:128 MB USACO/game1 A Game游戏 译 by 肖遥 描述 有如下一个双人游 ...

  3. 【一起来烧脑】一步学会Vue.js系统

    Vuejs是一个构建数据驱动的web界面的库,通过api实现响应的数据绑定和组合的视图组件,Vue.js的核心是一个响应的数据绑定系统,它让数据与DOM保持同步非常简单,一旦创建了绑定,DOM 将与数 ...

  4. Linux 文件系统引起的云盘文件系统异常导致 MySQL 数据页损坏事故恢复复盘

    事故的起因是因为当我访问某个数据库的某个表的时候,MySQL 立即出现崩溃并且去查看 MySQL 的错误日志出现类似信息 --09T05::.232564Z [ERROR] InnoDB: Space ...

  5. 如何解决金蝶IKernel.exe报错 Windows Installer 错误 重新安装、无法卸载

    如何解决金蝶IKernel.exe报错 Windows Installer 错误 金蝶这个小婊子,就是这么贱. 卸载了高版本的,再安装低版本就不能安装上,死活都不能安装. 请手动启动一下Install ...

  6. xftp实现本地与服务器的文件上传下载(windows)

    背景: Jemter环境搭建,需上传下载服务器文件到aws服务器上,由于secureCRT的局限性它只支持pub格式的密钥,不支持pem格式密钥,xshell是支持pem格式的,所以尝试安装xshel ...

  7. ICEM-管肋

    原视频下载地址:https://yunpan.cn/cMgkmd7u9ZPdC  访问密码 8a73

  8. linux 9.故障修复和网络配置

    一.linux系统故障修复       1.不知道root密码的前提下 破解root密码 服务器必须在身边           grub引导菜单              按任意键进入->e ( ...

  9. zabbix—自动发现端口并监控

    自动批量检查agent开放的端口 PS:如果服务器上的应用都是固定的,不会随机产生的都可以使用自动发现端口来监控:  如果服务器会随机出现端口且每次启动程序都会改变,可以采用第二种方法,来监控指定的端 ...

  10. Mybatis笔记(二)

    目录 MyBatis 逆向工程 MyBatis Generator 使用 分页插件 1.下载分页插件 2.配置分页插件 3.使用分页插件 SSM整合(spring与springMVC) 1.创建web ...