现在的位置: 首页 > 综合 > 正文

GStreamer播放教程06——可视化音频

2018年02月23日 ⁄ 综合 ⁄ 共 4329字 ⁄ 字号 评论关闭

目标

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

      如何允许音频的可视化

      如何选择可视化element


介绍

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

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

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


一个有趣的音乐播放器

#include <gst/gst.h>
  
/* playbin2 flags */
typedef enum {
  GST_PLAY_FLAG_VIS           = (1 << 3) /* Enable rendering of visualizations when there is no video stream. */
} GstPlayFlags;
  
/* Return TRUE if this is a Visualization element */
static gboolean filter_vis_features (GstPluginFeature *feature, gpointer data) {
  GstElementFactory *factory;
  
  if (!GST_IS_ELEMENT_FACTORY (feature))
    return FALSE;
  factory = GST_ELEMENT_FACTORY (feature);
  if (!g_strrstr (gst_element_factory_get_klass (factory), "Visualization"))
    return FALSE;
  
  return TRUE;
}
  
int main(int argc, char *argv[]) {
  GstElement *pipeline, *vis_plugin;
  GstBus *bus;
  GstMessage *msg;
  GList *list, *walk;
  GstElementFactory *selected_factory = NULL;
  guint flags;
  
  /* Initialize GStreamer */
  gst_init (&argc, &argv);
  
  /* Get a list of all visualization plugins */
  list = gst_registry_feature_filter (gst_registry_get_default (), filter_vis_features, FALSE, NULL);
  
  /* Print their names */
  g_print("Available visualization plugins:\n");
  for (walk = list; walk != NULL; walk = g_list_next (walk)) {
    const gchar *name;
    GstElementFactory *factory;
    
    factory = GST_ELEMENT_FACTORY (walk->data);
    name = gst_element_factory_get_longname (factory);
    g_print("  %s\n", name);
    
    if (selected_factory == NULL || g_str_has_prefix (name, "GOOM")) {
      selected_factory = factory;
    }
  }
  
  /* Don't use the factory if it's still empty */
  /* e.g. no visualization plugins found */
  if (!selected_factory) {
    g_print ("No visualization plugins found!\n");
    return -1;
  }
  
  /* We have now selected a factory for the visualization element */
  g_print ("Selected '%s'\n", gst_element_factory_get_longname (selected_factory));
  vis_plugin = gst_element_factory_create (selected_factory, NULL);
  if (!vis_plugin)
    return -1;
  
  /* Build the pipeline */
  pipeline = gst_parse_launch ("playbin2 uri=http://radio.hbr1.com:19800/ambient.ogg", NULL);
  
  /* Set the visualization flag */
  g_object_get (pipeline, "flags", &flags, NULL);
  flags |= GST_PLAY_FLAG_VIS;
  g_object_set (pipeline, "flags", flags, NULL);
  
  /* set vis plugin for playbin2 */
  g_object_set (pipeline, "vis-plugin", vis_plugin, NULL);
  
  /* Start playing */
  gst_element_set_state (pipeline, GST_STATE_PLAYING);
  
  /* Wait until error or EOS */
  bus = gst_element_get_bus (pipeline);
  msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_ERROR | GST_MESSAGE_EOS);
  
  /* Free resources */
  if (msg != NULL)
    gst_message_unref (msg);
  gst_plugin_feature_list_free (list);
  gst_object_unref (bus);
  gst_element_set_state (pipeline, GST_STATE_NULL);
  gst_object_unref (pipeline);
  return 0;
}


工作流程

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

  /* Set the visualization flag */
  g_object_get (pipeline, "flags", &flags, NULL);
  flags |= GST_PLAY_FLAG_VIS;
  g_object_set (pipeline, "flags", flags, NULL);

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

  /* Get a list of all visualization plugins */
  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。

/* Return TRUE if this is a Visualization element */
static gboolean filter_vis_features (GstPluginFeature *feature, gpointer data) {
  GstElementFactory *factory;
  
  if (!GST_IS_ELEMENT_FACTORY (feature))
    return FALSE;
  factory = GST_ELEMENT_FACTORY (feature);
  if (!g_strrstr (gst_element_factory_get_klass (factory), "Visualization"))
    return FALSE;
  
  return TRUE;
}

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

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

  /* Print their names */
  g_print("Available visualization plugins:\n");
  for (walk = list; walk != NULL; walk = g_list_next (walk)) {
    const gchar *name;
    GstElementFactory *factory;
    
    factory = GST_ELEMENT_FACTORY (walk->data);
    name = gst_element_factory_get_longname (factory);
    g_print("  %s\n", name);
    
    if (selected_factory == NULL || g_str_has_prefix (name, "GOOM")) {
      selected_factory = factory;
    }
  }

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

  /* We have now selected a factory for the visualization element */
  g_print ("Selected '%s'\n", gst_element_factory_get_longname (selected_factory));
  vis_plugin = gst_element_factory_create (selected_factory, NULL);
  if (!vis_plugin)
    return -1;

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

  /* set vis plugin for playbin2 */
  g_object_set (pipeline, "vis-plugin", vis_plugin, NULL);

      Bingo,就这么简单。


抱歉!评论已关闭.