GStreamer中gst_parse_launch无法拼接std::string变量的问题求助
问题解决:GStreamer中RTSP地址变量拼接报错
错误原因
gst_parse_launch() 要求第一个参数是C风格字符串(const gchar*),但你拼接字符串后得到的是std::string对象,C++不会自动完成这种类型转换,因此触发了类型不匹配的错误。
解决方案一:字符串拼接后转C风格字符串
先把所有部分拼接成完整的std::string,再通过c_str()方法获取其底层的C风格字符串指针,传给gst_parse_launch():
/*Url Cams*/ std::string URL_RTSP = "rtsp://user:pass@protocol:port/cam/realmonitor?channel=1&subtype=0"; /* 拼接完整的管道描述字符串 */ std::string pipeline_str = "rtspsrc protocols=tcp location=" + URL_RTSP + " latency=300 ! decodebin3 ! autovideosink"; /* Build the pipeline */ pipeline = gst_parse_launch(pipeline_str.c_str(), NULL); /* Start playing */ gst_element_set_state(pipeline, GST_STATE_PLAYING);
解决方案二:分步创建元素并设置属性(更推荐)
相比字符串拼接,直接创建rtspsrc元素并设置location等属性,可读性和灵活性更强,也能避免字符串拼接可能出现的转义问题:
/*Url Cams*/ std::string URL_RTSP = "rtsp://user:pass@protocol:port/cam/realmonitor?channel=1&subtype=0"; // 创建管道和各个元素 GstElement *pipeline = gst_pipeline_new("rtsp-pipeline"); GstElement *rtspsrc = gst_element_factory_make("rtspsrc", "source"); GstElement *decodebin = gst_element_factory_make("decodebin3", "decoder"); GstElement *videosink = gst_element_factory_make("autovideosink", "sink"); if (!pipeline || !rtspsrc || !decodebin || !videosink) { g_printerr("无法创建所有GStreamer元素!\n"); return -1; } // 设置rtspsrc的属性 g_object_set(rtspsrc, "protocols", GST_RTSP_LOWER_TRANS_TCP, "location", URL_RTSP.c_str(), "latency", 300, NULL); // 将元素添加到管道 gst_bin_add_many(GST_BIN(pipeline), rtspsrc, decodebin, videosink, NULL); // 链接元素(decodebin需要动态链接,因为它的输出pad是动态创建的) if (!gst_element_link(rtspsrc, decodebin)) { g_printerr("无法链接rtspsrc和decodebin!\n"); gst_object_unref(pipeline); return -1; } // 处理decodebin的pad-added信号,动态链接到videosink g_signal_connect(decodebin, "pad-added", G_CALLBACK(on_pad_added), videosink); /* Start playing */ gst_element_set_state(pipeline, GST_STATE_PLAYING);
需要额外实现on_pad_added回调函数:
static void on_pad_added(GstElement *element, GstPad *pad, gpointer data) { GstElement *sink = (GstElement *)data; GstPad *sink_pad = gst_element_get_static_pad(sink, "sink"); if (gst_pad_is_linked(sink_pad)) { g_object_unref(sink_pad); return; } GstCaps *caps = gst_pad_get_current_caps(pad); GstStructure *str = gst_caps_get_structure(caps, 0); const gchar *media_type = gst_structure_get_name(str); // 只链接视频流 if (g_str_has_prefix(media_type, "video/")) { gst_pad_link(pad, sink_pad); } gst_caps_unref(caps); g_object_unref(sink_pad); }
说明
- 方案一适合简单场景,快速修改现有代码即可生效;
- 方案二更符合GStreamer的最佳实践,尤其是需要动态处理媒体流(比如同时包含音视频的RTSP流)时,能更灵活地处理不同类型的流。
内容的提问来源于stack exchange,提问作者l12
相关产品推荐
相关产品推荐

