GStreamer —— 2.9、Windows下Qt加载GStreamer库后运行 - “教程9:媒体信息收集“(附:完整源码)

server/2025/3/9 22:12:35/
简介

     上一个教程演示了多线程和 Pad 可用性。本教程介绍媒体信息收集。有时,您可能希望快速找出文件的媒体类型 (或 URI)包含媒体,或者您是否能够播放媒体。你 可以构建一个管道,将其设置为 Run,并监视总线消息,但 GStreamer 有一个实用程序可以为您执行此作。本教程 显示:

          • 如何恢复有关 URI 的信息

          • 如何确定 URI 是否可播放


     GstDiscoverer是在库中找到的实用程序对象 (插件基础实用程序),它接受 URI 或 URI 列表,并返回 关于他们的信息。它可以在同步或异步模式下工作 模式。在同步模式下,只有一个函数可以调用,该函数会阻塞,直到信息为 准备。由于这种阻塞,它通常不太有趣 使用基于 GUI 的应用程序和异步模式,如前所述 在本教程中。gst_discoverer_discover_uri()恢复的信息包括编解码器描述、流拓扑 (流和子流的数量)和可用的元数据(如 audio language) 的 Interface。例如,这是结果发现 https://gstreamer.freedesktop.org/data/media/sintel_trailer-480p.webm

在这里插入图片描述

GStreamer_18">GStreamer相关运行库
INCLUDEPATH += D:/Software/GStreamer/1.0/mingw_x86_64/include/gstreamer-1.0/gst
INCLUDEPATH += D:/Software/GStreamer/1.0/mingw_x86_64/include
INCLUDEPATH += D:/Software/GStreamer/1.0/mingw_x86_64/include/gstreamer-1.0
INCLUDEPATH += D:/Software/GStreamer/1.0/mingw_x86_64/include/glib-2.0
INCLUDEPATH += D:/Software/GStreamer/1.0/mingw_x86_64/lib/glib-2.0/includeLIBS += D:/Software/GStreamer/1.0/mingw_x86_64/lib/gstreamer-1.0.lib
LIBS += D:/Software/GStreamer/1.0/mingw_x86_64/lib/glib-2.0.lib
LIBS += D:/Software/GStreamer/1.0/mingw_x86_64/lib/gobject-2.0.lib
LIBS += D:/Software/GStreamer/1.0/mingw_x86_64/lib/gstaudio-1.0.lib
LIBS += D:/Software/GStreamer/1.0/mingw_x86_64/lib/gstpbutils-1.0.lib

完整源码
#include <string.h>
#include <gst/gst.h>
#include <gst/pbutils/pbutils.h>typedef struct _CustomData
{GstDiscoverer *discoverer;GMainLoop *loop;
} CustomData;/* 以人类可读的格式打印标签(名称:值) */
static void print_tag_foreach (const GstTagList *tags, const gchar *tag, gpointer user_data)
{GValue val = { 0, };gst_tag_list_copy_value (&val, tags, tag);  /* 将给定标签的内容复制到值 如果多个值关联,则将多个值合并为一个值 替换为标签。 使用后必须g_value_unset该值。 */gchar *str;if (G_VALUE_HOLDS_STRING (&val))str = g_value_dup_string (&val);elsestr = gst_value_serialize (&val);gint depth = GPOINTER_TO_INT (user_data);g_print ("%*s%s: %s\n", 2 * depth, " ", gst_tag_get_nick (tag), str);g_free (str);g_value_unset (&val);
}/* 打印有关流的信息 */
static void print_stream_info (GstDiscovererStreamInfo *info, gint depth)
{gchar *desc = NULL;GstCaps *caps = gst_discoverer_stream_info_get_caps (info);if (caps){/** 修复 GstCap 只描述一种格式,也就是说,它们恰好具有 一个结构,结构中的每个字段都描述一个固定类型。 非固定类型的示例包括 GST_TYPE_INT_RANGE 和 GST_TYPE_LIST。如果上限固定,则为 TRUE*/if (gst_caps_is_fixed (caps)){/* 返回一个本地化的(尽可能可能的)字符串,描述 以大写字母指定的媒体格式,用于错误对话框或其他消息 以便用户看到。除非 caps 无效,否则不应返回 NULL。 */desc = gst_pb_utils_get_codec_description (caps);}else{/* 将 Cap 转换为 String 表示形式。此字符串表示 可以通过 gst_caps_from_string 转换回 GstCap。 */desc = gst_caps_to_string (caps);}gst_caps_unref (caps);}g_print ("%*s%s: %s\n", 2 * depth, " ", gst_discoverer_stream_info_get_stream_type_nick (info), (desc ? desc : ""));if (desc){g_free (desc);desc = NULL;}const GstTagList *tags = gst_discoverer_stream_info_get_tags (info);if (tags){g_print ("%*sTags:\n", 2 * (depth + 1), " ");gst_tag_list_foreach (tags, print_tag_foreach, GINT_TO_POINTER (depth + 2));}
}/* 打印有关流及其子流的信息(如果有的话) */
static void print_topology (GstDiscovererStreamInfo *info, gint depth)
{if (!info){ return; }print_stream_info (info, depth);GstDiscovererStreamInfo *next = gst_discoverer_stream_info_get_next (info);if (next){print_topology (next, depth + 1);gst_discoverer_stream_info_unref (next);}else if (GST_IS_DISCOVERER_CONTAINER_INFO (info)){GList *streams = gst_discoverer_container_info_get_streams (GST_DISCOVERER_CONTAINER_INFO (info));for (GList *tmp = streams; tmp; tmp = tmp->next){GstDiscovererStreamInfo *tmpinf = (GstDiscovererStreamInfo *) tmp->data;print_topology (tmpinf, depth + 1);}gst_discoverer_stream_info_list_free (streams);}
}/* 每当发现者有关于我们提供的URI之一的信息时,就会调用此函数。 */
static void on_discovered_cb (GstDiscoverer *discoverer, GstDiscovererInfo *info, GError *err, CustomData *data)
{GstDiscovererResult result;const gchar *uri;const GstTagList *tags;GstDiscovererStreamInfo *sinfo;uri = gst_discoverer_info_get_uri (info);result = gst_discoverer_info_get_result (info);switch (result){case GST_DISCOVERER_URI_INVALID:g_print ("Invalid URI '%s'\n", uri);break;case GST_DISCOVERER_ERROR:g_print ("Discoverer error: %s\n", err->message);break;case GST_DISCOVERER_TIMEOUT:g_print ("Timeout\n");break;case GST_DISCOVERER_BUSY:g_print ("Busy\n");break;case GST_DISCOVERER_MISSING_PLUGINS:{const GstStructure *s;gchar *str;s = gst_discoverer_info_get_misc (info);str = gst_structure_to_string (s);g_print ("Missing plugins: %s\n", str);g_free (str);break;}case GST_DISCOVERER_OK:g_print ("Discovered '%s'\n", uri);break;}if (result != GST_DISCOVERER_OK) { g_printerr ("This URI cannot be played\n"); return; }/* 如果没有错误,显示检索到的信息 */g_print ("\nDuration: %" GST_TIME_FORMAT "\n", GST_TIME_ARGS (gst_discoverer_info_get_duration (info)));tags = gst_discoverer_info_get_tags (info);if (tags){g_print ("Tags:\n");/* 为标签列表中的每个标签调用给定的函数。请注意,如果存在 没有标签,则根本不会调用该函数。 */gst_tag_list_foreach (tags, print_tag_foreach, GINT_TO_POINTER (1));}g_print ("Seekable: %s\n", (gst_discoverer_info_get_seekable (info) ? "yes" : "no"));g_print ("\n");sinfo = gst_discoverer_info_get_stream_info (info);if (!sinfo){ return; }g_print ("Stream information:\n");print_topology (sinfo, 1);gst_discoverer_stream_info_unref (sinfo);g_print ("\n");
}/* 当发现者检查完我们提供的所有URI后,将调用此函数。.*/
static void on_finished_cb (GstDiscoverer *discoverer, CustomData *data)
{g_print ("Finished discovering\n");g_main_loop_quit (data->loop);
}int main (int argc, char **argv)
{gchar *uri = (gchar *)("https://gstreamer.freedesktop.org/data/media/sintel_trailer-480p.webm");if (argc > 1) { uri = argv[1]; }CustomData data;memset (&data, 0, sizeof (data));/* 初始化GStreamer */gst_init (&argc, &argv);g_print ("Discovering '%s'\n", uri);/* 实例化发现者 */GError *err = NULL;data.discoverer = gst_discoverer_new (5 * GST_SECOND, &err);if (!data.discoverer){g_print ("Error creating discoverer instance: %s\n", err->message);g_clear_error (&err); return -1;}/* 连接到有趣的信号 */g_signal_connect (data.discoverer, "discovered", G_CALLBACK (on_discovered_cb), &data);g_signal_connect (data.discoverer, "finished", G_CALLBACK (on_finished_cb), &data);/* 启动发现者进程(目前还没什么可做的) */gst_discoverer_start (data.discoverer);/* 添加请求以异步处理通过命令行传递的URI */if (!gst_discoverer_discover_uri_async (data.discoverer, uri)){g_print ("Failed to start discovering URI '%s'\n", uri);g_object_unref (data.discoverer); return -1;}/* 创建一个GLib主循环并将其设置为运行,这样我们就可以等待信号了 */data.loop = g_main_loop_new (NULL, FALSE);g_main_loop_run (data.loop);/* 停止发现者进程 */gst_discoverer_stop (data.discoverer);/* 释放资源 */g_object_unref (data.discoverer);g_main_loop_unref (data.loop);return 0;
}

关注

笔者 - jxd


http://www.ppmy.cn/server/173771.html

相关文章

Qt:day5

一、作业1 将一个 QSlider&#xff0c;使用QSS语句&#xff0c;画成一个进度条&#xff1a; 要画2个部分&#xff1a;QSlider的槽、QSlider滑块&#xff1b; 进度条通过线程自己动起来。 【运行结果】&#xff1a;点Play按钮后&#xff0c;线程运行滑块从最左端向右移动到最右端…

12.【线性代数】——图和网络

十二 图和网络&#xff08;线性代数的应用&#xff09; 图 g r a p h { n o d e s , e d g e s } graph\{nodes, edges\} graph{nodes,edges}1.关联矩阵2. A A A矩阵的零空间&#xff0c;求解 A x 0 Ax0 Ax0 电势3. A T A^T AT矩阵的零空间&#xff0c;电流总结电流图结论 …

Mybatis Generator 使用手册

第一章 什么是Mybatis Generator&#xff1f; MyBatis Generator Core – Introduction to MyBatis Generator MyBatis生成器&#xff08;MBG&#xff09;是MyBatis框架的代码生成工具。它支持为所有版本的MyBatis生成代码&#xff0c;通过解析数据库表&#xff08;或多个表&…

在 Linux 下,服务器如何知道某个 TCP 连接来了消息? 这就涉及 IO 事件通知机制!

1. 阻塞 read() 阻塞 read() 就像你打电话问饭好了吗&#xff0c;但如果对方不接电话&#xff08;没数据&#xff09;&#xff0c;你就一直守在电话边等&#xff0c;什么别的事情都做不了。 你打电话问外卖员“饭好了吗&#xff1f;”&#xff0c;如果外卖还没送到&#xff0c…

DeepSeek-R1本地化部署(Mac)

一、下载 Ollama 本地化部署需要用到 Ollama&#xff0c;它能支持很多大模型。官方网站&#xff1a;https://ollama.com/ 点击 Download 即可&#xff0c;支持macOS,Linux 和 Windows&#xff1b;我下载的是 mac 版本&#xff0c;要求macOS 11 Big Sur or later&#xff0c;Ol…

OCPP扩展机制与自定义功能开发:协议灵活性设计与实践 - 慧知开源充电桩平台

OCPP扩展机制与自定义功能开发&#xff1a;协议灵活性设计与实践 引言 OCPP作为开放协议&#xff0c;其核心价值在于平衡标准化与可扩展性。面对不同充电桩厂商的硬件差异、区域能源政策及定制化业务需求&#xff0c;OCPP通过**扩展点&#xff08;Extension Points&#xff09…

3D数字化:家居行业转型升级的关键驱动力

在科技日新月异的今天&#xff0c;家居行业正经历着一场前所未有的变革。从传统的线下实体店铺到线上电商平台的兴起&#xff0c;再到如今3D数字化营销的广泛应用&#xff0c;消费者的购物体验正在发生翻天覆地的变化。3D数字化营销不仅让购物变得更加智能和便捷&#xff0c;还…

如何用Kimi生成PPT?秒出PPT更高效!

做PPT是不是总是让你头疼&#xff1f;&#x1f629; 快速制作出专业的PPT&#xff0c;今天我们要推荐两款超级好用的AI工具——Kimi 和 秒出PPT&#xff01;我们来看看哪一款更适合你吧&#xff01;&#x1f680; &#x1f947; Kimi&#xff1a;让PPT制作更轻松 Kimi的生成效…