【GStreamer】基于gstreamer的简单h264-rtmp推流器

1.命令行实现h264文件推流到RTMP服务器

# 将yuv文件先编码再传输
GST_DEBUG=3 gst-launch-1.0 filesrc location=test.yuv ! queue ! "video/x-raw,format=I420,width=832,height=480,framerate=25/1" ! rawvideoparse use-sink-caps=true ! x264enc bitrate=5000 qp-min=18 qp-max=35 ! flxmux ! rtmpsink location='rtmp://127.0.0.1:1935/live/test'
# 直接传输h264文件
GST_DEBUG=3 gst-launch-1.0 filesrc location=test.h264 ! h264parse ! flvmux ! rtmpsink location='rtmp://127.0.0.1:1935/live/test'
# 直接传输h264文件(循环推流)
GST_DEBUG=3 gst-launch-1.0 multifilesrc location=test.h264 loop=true ! h264parse ! flvmux ! rtmpsink location='rtmp://127.0.0.1:1935/live/test'

2.基于gstreamer的h264推流器

下面代码中直接传输本地已经编码的h264码流文件

#include <gst/gst.h>

typedef struct _Data
{
	GstElement* pipeline;
	GstElement* filesrc;
	GstElement* h264parse;
	GstElement* flvmux;
	GstElement* rtmpsink;
} Data;

int main(int argc, char* argv[])
{
	Data data;
	GstBus* bus;
	GstMessage* msg;
	GstStateChangeReturn ret;
	gboolean terminate= FALSE;
	// 设置日志级别
	gst_debug_set_default_threshold(3);
	// 初始化gst
	gst_init(&argc, &argv);
	// 创建模块
	data.filesrc = gst_element_factory_make("filesrc", "filesrc");
	data.h264parse = gst_element_factory_make("h264parse", "h264parse");
	data.flvmux = gst_element_factory_make("flvmux", "flvmux");
	data.rtmpsink = gst_element_factory_make("rtmpsink", "rtmpsink");
	data.pipeline = gst_pipeline_new("pipeline");

	if(!data.filesrc || !data.h264parse || !data.flvmux || !data.rtmpsink || !data.pipeline)
	{
		g_printerr("some elements created failed\n");
		return -1;
	}
	// 设置输入输出
	// 这里输出的地址是rtmp://127.0.0.1:1935/live/test,输入是本地的h264文件
	g_object_set(G_OBJECT(data.filesrc), "location", "test.h264", NULL);
	g_object_set(G_OBJECT(data.rtmpsink), "location", "rtmp://127.0.0.1:1935/live/test", NULL);
	// 将不同元素添加到同一个pipeline中
	gst_bin_add_many(GST_BIN(data.pipeline), data.filesrc, data.h264parse, data.flvmux, data.rtmpsink, NULL);
	// 链接不同的元素
	if(!gst_element_link_many(data.filesrc, data.h264parse, data.flvmux, data.rtmpsink, NULL))
	{
		g_printerr("link elements failed\n");
		return -1;
	}
	// 设置pipeline为playing状态
	ret = gst_element_set_state(data.pipeline, GST_STATE_PLAYING);
	if(ret == GST_STATE_CHANGE_FAILURE)
	{
		g_printerr("failed to start playing\n");
		return -1;
	}
	// 获取pipeline总线
	bus = gst_element_get_bus(data.pipeline);
	do {
		// 监测总线上面的消息
		msg = gst_bus_timed_pop_filtered(bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_STATE_CHANGED | GST_MESSAGE_ERROR | GST_MESSAGE_EOS);
		if(msg != NULL)
		{
			GError* err;
			gchar* debug_info;
			switch(GST_MESSAGE_TYPE(msg))
			{
				case GST_MESSAGE_ERROR:
				  	gst_message_parse_error(msg, &err, &debug_info);
				  	g_printerr("error received from element %s : %s\n", GST_OBJECT_NAME(msg->src), err->message);
				  	g_clear_error(&err);
				  	g_free(debug_info);
				  	gst_message_unref(msg);
				  	terminate = TRUE;
				  	break;
				case GST_MESSAGE_EOS:
				  	g_print("end of stream\n");
					terminate = TRUE;
				  	break;
				case GST_MESSAGE_STATE_CHANGED:
				  	if(GST_MESSAGE_SRC(msg) == GST_OBJECT(data.pipeline))
				  	{
						GstState old_state, new_state, pending_state;
						gst_message_parse_state_changed(msg, &old_state, &new_state, &pending_state);
						g_print("pipeline")
				  	}
					break;
				default:
					g_printerr("unexpected message received, type:%d\n", GST_MESSAGE_TYPE(msg));
					break;
			}
			gst_message_unref(msg);
		} 
	} while(!terminate);
	gst_object_unref(bus);
	gst_element_set_state(data.pipeline, GST_STATE_NULL);
	gst_object_unref(data.pipeline);
	return 0;
}

如果要播放测试,可以使用vlc或者ffplay

ffplay rtmp://127.0.0.1:1935/live/test
GStreamer是一款强大的开源多媒体框架,用于处理各种媒体数据,包括实时传输协议(RTMPRTMP是一种广泛应用于网络视频直播的应用层协议,比如Adobe Flash Player曾经支持使用RTMP进行视频上传。 要在GStreamer中实现RTMP文件,你需要使用`gstreamer-appsrc`(应用程序源)来生成视频数据,然后通过`rtmpsink`插件连接到RTMP服务器。以下是一个简单GStreamer pipeline(管道)示例: ```cpp #include <gst/gst.h> int main(int argc, char *argv[]) { GstElement *pipeline; GstElement *appsrc; GstElement *rtmpsink; // 初始化GStreamer gst_init(&argc, &argv); // 创建pipeline元素 pipeline = gst_pipeline_new("rtmp-push"); // 创建appsrc元素(模拟文件或摄像头) appsrc = gst_element_factory_make("appsrc", "app-source"); g_object_set(G_OBJECT(appsrc), "format", GST_FORMAT_TIME, "is-live", TRUE, NULL); // 设置为实时 // 创建rtmpsink元素 rtmpsink = gst_element_factory_make("rtmpsink", "rtmp-sink"); g_object_set(G_OBJECT(rtmpsink), "location", "rtmp://your_rtmp_server/live/stream_name", NULL); // 替换为你的RTMP服务器地址和名 // 连接元素 gst_bin_add_many(pipeline, appsrc, rtmpsink, NULL); gst_element_link(appsrc, rtmpsink); // 播放或打开文件(如果appsrc代表文件) if (argc > 1) { const gchar *filename = argv[1]; GstPadProbeReturn probe_ret; GstBuffer *buffer; g_signal_connect(appsrc, "pad-added", G_CALLBACK(probe_file_src_pad_added), filename); } else { // 如果没有提供文件,可能需要设置其他参数以触发appsrc开始读取视频数据 } // 启动pipeline if (!gst_element_set_state(pipeline, GST_STATE_PLAYING)) { GST_ERROR("Failed to set pipeline to playing state!"); return -1; } // 结束后清理 g_main_loop_run(g_main_loop_new(NULL, FALSE)); gst_element_dispose(pipeline); gst_object_unref(pipeline); return 0; } static gboolean probe_file_src_pad_added(GstElement *element, GstPad *pad, gpointer user_data) { const gchar *filename = user_data; GstPadProbeReturn ret; GstSample *sample; GstBuffer *buffer; // 加载文件并创建样本 buffer = gst_buffer_new_and_alloc(4096); // 假设我们只是简单地填充一个缓冲区 sample = gst_sample_new_with_buffer(buffer, NULL, GST_CLOCK_TIME_NONE, NULL); // 发送样本给appsrc ret = gst_pad_push_sample(pad, sample); if (ret == GST_PAD_PROBE_OK) { return TRUE; } else { GST_WARNING("Failed to push sample to appsrc pad."); return FALSE; } } ``` 要运行这段代码,确保已经安装了GStreamer库和必要的rtmpsink插件(如gst-rtmp-server)。同时,根据实际情况修改RTMP服务器URL和名。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值