01.Hello World
2026/1/15大约 3 分钟helloworld
GStreamer学习笔记:01.Hello World
这是学习 GStreamer 的第一个示例,尝试构建一个最简单的播放 pipeline。
核心概念
1. 初始化 GStreamer
GStreamer 程序必须执行 gst_init(),该函数实现:
- 初始化所有内部结构体
- 检查平台所有可用的插件
- 执行任何用于 GStreamer 的命令行选项
gst_init(&argc, &argv);2. 构建 Pipeline
关于 gst_parse_launch()
- 构建了一个只有 playbin 插件的 pipeline
- 通常通过手动组装各个独立的 element 来构建 pipeline
- 当 pipeline 足够简单时,可以使用
gst_parse_launch()自动解析并实例化文本形式表示的 pipeline - 注意:
gst_parse_launch()内部的事件处理机制和 Pad 动态创建机制可能导致管道无法重复使用
关于 playbin
- 特殊的 element,具备一个 pipeline 的所有特点,既有 source,又有 sink
- 在内部自动创建和连接所有播放媒体需要的 element:
- 自动为不同的源初始化合适的 source element(http 源、file 源、rtsp 源)
- 自动创建 filter element(解封装、解码)
pipeline = gst_parse_launch("playbin uri=https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm", NULL);3. 设置播放状态
将 pipeline 的状态设置为 PLAYING 以开始播放:
gst_element_set_state(pipeline, GST_STATE_PLAYING);4. 监听消息
监听整个 pipeline 总线:
gst_element_get_bus()获取 pipeline 的 busgst_bus_timed_pop_filtered()阻塞程序直到程序运行引发 ERROR 或到达 EOS
bus = gst_element_get_bus(pipeline);
msg = gst_bus_timed_pop_filtered(bus, GST_CLOCK_TIME_NONE,
GST_MESSAGE_ERROR | GST_MESSAGE_EOS);5. 释放资源
回收所有手动申请的资源:
释放 GstMessage
- 流程:
gst_bus_timed_pop_filtered()获取 →gst_message_unref()释放
释放 GstBus
- 流程:
gst_element_get_bus()获取 →gst_object_unref()释放
释放 pipeline
- 在释放 pipeline 及其下的所有 element 之前需要将 pipeline 的状态设置为 NULL
- 流程:
gst_parse_launch()获取 →gst_element_set_state()设置状态 →gst_object_unref()释放
if (msg != NULL)
gst_message_unref(msg);
gst_object_unref(bus);
gst_element_set_state(pipeline, GST_STATE_NULL);
gst_object_unref(pipeline);完整代码
#include <gst/gst.h>
int main(int argc, char *argv[])
{
GstElement *pipeline;
GstBus *bus;
GstMessage *msg;
/* Initialize GStreamer */
gst_init(&argc, &argv);
/* Build the pipeline */
pipeline = gst_parse_launch("playbin uri=https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm",
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_object_unref(bus);
gst_element_set_state(pipeline, GST_STATE_NULL);
gst_object_unref(pipeline);
return 0;
}编译和运行
直接编译
gcc main.c -o main.out $(pkg-config --cflags --libs gstreamer-1.0)
./main.out使用 Makefile
编写 Makefile 可以更方便地管理编译过程。这里有两个版本的 makefile。
版本一:简洁版
这个版本适用于简单的单文件项目,代码最简洁:
CFLAGS += $(shell pkg-config --cflags gstreamer-1.0)
LDLIBS += $(shell pkg-config --libs gstreamer-1.0)
# 隐式规则(可以不写)
*.o: *.c
$(CC) $(CFLAGS) -c -o main.o main.c
main.out: main.o
$(CC) -o $@ $^ $(LDLIBS)
all: main.out
clean:
rm -f *.o *.out说明:
- 使用
pkg-config获取 GStreamer 的编译选项和链接库 - 定义了简单的目标文件和可执行文件依赖关系
- 提供
clean目标清理生成的文件
版本二:标准版(后续示例使用)
后续示例使用的 makefile 更加规范和可扩展,适合多文件项目:
# 编译器设置
CC = gcc
CFLAGS = -Wall -g
# 使用 pkg-config 获取 glib-2.0 的路径
CFLAGS += $(shell pkg-config --cflags gstreamer-1.0)
LDLIBS += $(shell pkg-config --libs gstreamer-1.0)
# 目标
TARGET = main.out
SRCS = main.c
OBJS = $(SRCS:.c=.o)
# 默认目标
all: $(TARGET)
$(TARGET): $(OBJS)
$(CC) $(OBJS) -o $@ $(LDLIBS)
# 编译 .c 文件 (隐式规则)
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
# 清理
clean:
rm -f $(OBJS) $(TARGET)
.PHONY: all clean改进说明:
- 显式定义编译器
CC,默认为gcc - 添加了
-Wall -g编译选项,开启警告和调试信息 - 使用变量
TARGET、SRCS、OBJS统一管理目标文件 - 使用自动模式规则
%.o: %.c,适用于多个源文件 - 添加
.PHONY声明,明确指出all和clean是伪目标
使用方法:
make # 编译项目
make clean # 清理生成的文件版本选择建议:
- 简单的单文件学习示例可以使用版本一
- 需要扩展性的项目建议使用版本二
- 后续示例都采用版本二,保持一致性
总结
这个示例展示了 GStreamer 最基础的使用流程:
- 初始化 GStreamer
- 创建 pipeline(使用 playbin 简化构建)
- 设置播放状态
- 监听消息
- 释放资源
这是所有 GStreamer 应用程序的基本框架。