• 【GStreamer开发】GStreamer播放教程06——可视化音频


    目标

          GStreamer有一系列把音频转换成视频的element。他们可以用于科学的目的或者增加音乐播放器的趣味性。本教程展示:

          如何允许音频的可视化

          如何选择可视化element


    介绍

          在playbin2里面运行音频可视化是非常容易的。当遇到一个只有音频的流时,只需要正确地设置playbin2的一些标志就行了。它会自己创建必要的element然后显示的。

          如果你想要增加实际的element的趣味性,你要自己实例化它然后通过vis-plug属性来告诉playbin2。

          本教程GStreamer注册的所有关于可视化的element,选择了goom并传给了playbin2


    一个有趣的音乐播放器

    [objc] view plain copy
    1. <span style="font-size:14px;">#include <gst/gst.h>  
    2.     
    3. /* playbin2 flags */  
    4. typedef enum {  
    5.   GST_PLAY_FLAG_VIS           = (1 << 3/* Enable rendering of visualizations when there is no video stream. */  
    6. } GstPlayFlags;  
    7.     
    8. /* Return TRUE if this is a Visualization element */  
    9. static gboolean filter_vis_features (GstPluginFeature *feature, gpointer data) {  
    10.   GstElementFactory *factory;  
    11.     
    12.   if (!GST_IS_ELEMENT_FACTORY (feature))  
    13.     return FALSE;  
    14.   factory = GST_ELEMENT_FACTORY (feature);  
    15.   if (!g_strrstr (gst_element_factory_get_klass (factory), "Visualization"))  
    16.     return FALSE;  
    17.     
    18.   return TRUE;  
    19. }  
    20.     
    21. int main(int argc, charchar *argv[]) {  
    22.   GstElement *pipeline, *vis_plugin;  
    23.   GstBus *bus;  
    24.   GstMessage *msg;  
    25.   GList *list, *walk;  
    26.   GstElementFactory *selected_factory = NULL;  
    27.   guint flags;  
    28.     
    29.   /* Initialize GStreamer */  
    30.   gst_init (&argc, &argv);  
    31.     
    32.   /* Get a list of all visualization plugins */  
    33.   list = gst_registry_feature_filter (gst_registry_get_default (), filter_vis_features, FALSE, NULL);  
    34.     
    35.   /* Print their names */  
    36.   g_print("Available visualization plugins: ");  
    37.   for (walk = list; walk != NULL; walk = g_list_next (walk)) {  
    38.     const gchar *name;  
    39.     GstElementFactory *factory;  
    40.       
    41.     factory = GST_ELEMENT_FACTORY (walk->data);  
    42.     name = gst_element_factory_get_longname (factory);  
    43.     g_print("  %s ", name);  
    44.       
    45.     if (selected_factory == NULL || g_str_has_prefix (name, "GOOM")) {  
    46.       selected_factory = factory;  
    47.     }  
    48.   }  
    49.     
    50.   /* Don't use the factory if it's still empty */  
    51.   /* e.g. no visualization plugins found */  
    52.   if (!selected_factory) {  
    53.     g_print ("No visualization plugins found! ");  
    54.     return -1;  
    55.   }  
    56.     
    57.   /* We have now selected a factory for the visualization element */  
    58.   g_print ("Selected '%s' ", gst_element_factory_get_longname (selected_factory));  
    59.   vis_plugin = gst_element_factory_create (selected_factory, NULL);  
    60.   if (!vis_plugin)  
    61.     return -1;  
    62.     
    63.   /* Build the pipeline */  
    64.   pipeline = gst_parse_launch ("playbin2 uri=http://radio.hbr1.com:19800/ambient.ogg"NULL);  
    65.     
    66.   /* Set the visualization flag */  
    67.   g_object_get (pipeline, "flags", &flags, NULL);  
    68.   flags |= GST_PLAY_FLAG_VIS;  
    69.   g_object_set (pipeline, "flags", flags, NULL);  
    70.     
    71.   /* set vis plugin for playbin2 */  
    72.   g_object_set (pipeline, "vis-plugin", vis_plugin, NULL);  
    73.     
    74.   /* Start playing */  
    75.   gst_element_set_state (pipeline, GST_STATE_PLAYING);  
    76.     
    77.   /* Wait until error or EOS */  
    78.   bus = gst_element_get_bus (pipeline);  
    79.   msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_ERROR | GST_MESSAGE_EOS);  
    80.     
    81.   /* Free resources */  
    82.   if (msg != NULL)  
    83.     gst_message_unref (msg);  
    84.   gst_plugin_feature_list_free (list);  
    85.   gst_object_unref (bus);  
    86.   gst_element_set_state (pipeline, GST_STATE_NULL);  
    87.   gst_object_unref (pipeline);  
    88.   return 0;  
    89. }  
    90. </span>  

    工作流程

          首先,我们都知道通过设置GST_PLAY_FLAG_VIS标志可以让playbin2的音频可视化。如果媒体文件里面已经包含了视频,那么这个标志就不起作用。

    [objc] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. /* Set the visualization flag */  
    2. g_object_get (pipeline, "flags", &flags, NULL);  
    3. flags |= GST_PLAY_FLAG_VIS;  
    4. g_object_set (pipeline, "flags", flags, NULL);  

          如果用户没有指定可视化插件,playbin2会使用goom来做(如果没有这个element就不能进行音频可视化)。本教程剩下的部分会显示如何来发现一个可用的可视化element并指定playbin2使用。

    [objc] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. /* Get a list of all visualization plugins */  
    2. list = gst_registry_feature_filter (gst_registry_get_default (), filter_vis_features, FALSE, NULL);  

          gst_registry_feature_filter()检查GStreamer当前所有注册的element并选择那些filter_vis_features函数返回TRUE的element。

    [objc] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. /* Return TRUE if this is a Visualization element */  
    2. static gboolean filter_vis_features (GstPluginFeature *feature, gpointer data) {  
    3.   GstElementFactory *factory;  
    4.     
    5.   if (!GST_IS_ELEMENT_FACTORY (feature))  
    6.     return FALSE;  
    7.   factory = GST_ELEMENT_FACTORY (feature);  
    8.   if (!g_strrstr (gst_element_factory_get_klass (factory), "Visualization"))  
    9.     return FALSE;  
    10.     
    11.   return TRUE;  
    12. }  

          这里牵涉到一点关于GStreamer element的理论:每一个GStreamer在运行时加载的文件都被认为是插件。一个插件可以有多个功能,不同种类的功能。

          这个函数简单的丢弃了所有不能批量复现的功能以及不包含“可视化”这个功能的插件。

    [objc] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. /* Print their names */  
    2. g_print("Available visualization plugins: ");  
    3. for (walk = list; walk != NULL; walk = g_list_next (walk)) {  
    4.   const gchar *name;  
    5.   GstElementFactory *factory;  
    6.     
    7.   factory = GST_ELEMENT_FACTORY (walk->data);  
    8.   name = gst_element_factory_get_longname (factory);  
    9.   g_print("  %s ", name);  
    10.     
    11.   if (selected_factory == NULL || g_str_has_prefix (name, "GOOM")) {  
    12.     selected_factory = factory;  
    13.   }  
    14. }  

          一旦我们有了可视化插件的列表,我们会打印出它们的名字(gst_element_factory_get_longname())并选择一个(比如:GOOM)。

    [objc] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. /* We have now selected a factory for the visualization element */  
    2. g_print ("Selected '%s' ", gst_element_factory_get_longname (selected_factory));  
    3. vis_plugin = gst_element_factory_create (selected_factory, NULL);  
    4. if (!vis_plugin)  
    5.   return -1;  

          选中的工厂用来生成一个GstElement,通过vis-plugin属性来传给playbin2。

    [objc] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. /* set vis plugin for playbin2 */  
    2. g_object_set (pipeline, "vis-plugin", vis_plugin, NULL);  

          Bingo,就这么简单。

  • 相关阅读:
    201521123061 《Java程序设计》第三周学习总结
    201521123061 《Java程序设计》第二周学习总结
    201621123033 《Java程序设计》第10周学习总结
    201621123033 《Java程序设计》第9周学习总结
    201621123033 《Java程序设计》第8周学习总结
    201621123033 《Java程序设计》第7周学习总结
    201621123033 《Java程序设计》第6周学习总结
    201621123033 《Java程序设计》第5周学习总结
    201621123033 《Java程序设计》第4周学习总结
    201621123033 《Java程序设计》第3周学习总结
  • 原文地址:https://www.cnblogs.com/huty/p/8517338.html
Copyright © 2020-2023  润新知