网页播放rtmp流转http流比rtsp流转rtmp流再转http流的效率高很多哦,资源占用也很低,我边缘机可以做到九路直播。操作也不麻烦,直接修改sink_bin就行。
1,在/opt/nvidia/deepstream/deepstream/sources/apps/apps-common/includes/deepstream_sinks.h中添加SINK_RTMP
2,在/opt/nvidia/deepstream/deepstream/sources/apps/apps-common/src/deepstream_sink_bin.c中添加create_rtmpsink_bin
static gboolean
create_rtmpsink_bin (NvDsSinkEncoderConfig * config, NvDsSinkBinSubBin * bin)
{
GstCaps *caps = NULL;
gboolean ret = FALSE;
gchar elem_name[50];
gchar encode_name[50];
uid++;
g_snprintf (elem_name, sizeof (elem_name), "sink_sub_bin%d", uid);
bin->bin = gst_bin_new (elem_name);
if (!bin->bin) {
NVGSTDS_ERR_MSG_V ("Failed to create '%s'", elem_name);
goto done;
}
g_snprintf (elem_name, sizeof (elem_name), "sink_sub_bin_queue%d", uid);
bin->queue = gst_element_factory_make (NVDS_ELEM_QUEUE, elem_name);
if (!bin->queue) {
NVGSTDS_ERR_MSG_V ("Failed to create '%s'", elem_name);
goto done;
}
g_snprintf (elem_name, sizeof (elem_name), "sink_sub_bin_transform%d", uid);
bin->transform = gst_element_factory_make (NVDS_ELEM_VIDEO_CONV, elem_name);
if (!bin->transform) {
NVGSTDS_ERR_MSG_V ("Failed to create '%s'", elem_name);
goto done;
}
g_snprintf (elem_name, sizeof (elem_name), "sink_sub_bin_cap_filter_%d", uid);
bin->cap_filter = gst_element_factory_make (NVDS_ELEM_CAPS_FILTER, elem_name);
if (!bin->cap_filter) {
NVGSTDS_ERR_MSG_V ("Failed to create '%s'", elem_name);
goto done;
}
if (config->enc_type == NV_DS_ENCODER_TYPE_SW)
caps = gst_caps_from_string ("video/x-raw, format=I420");
else
caps = gst_caps_from_string ("video/x-raw(memory:NVMM), format=I420");
g_object_set (G_OBJECT (bin->cap_filter), "caps", caps, NULL);
g_snprintf (encode_name, sizeof (encode_name), "sink_sub_bin_encoder%d", uid);
switch (config->codec) {
case NV_DS_ENCODER_H264:
bin->codecparse = gst_element_factory_make ("h264parse", "h264-parser");
bin->encoder = gst_element_factory_make (NVDS_ELEM_ENC_H264_HW, encode_name);
if (config->enc_type == NV_DS_ENCODER_TYPE_SW)
bin->encoder = gst_element_factory_make (NVDS_ELEM_ENC_H264_SW, encode_name);
else
bin->encoder = gst_element_factory_make (NVDS_ELEM_ENC_H264_HW, encode_name);
break;
case NV_DS_ENCODER_H265:
bin->codecparse = gst_element_factory_make ("h265parse", "h265-parser");
if (config->enc_type == NV_DS_ENCODER_TYPE_SW)
bin->encoder = gst_element_factory_make (NVDS_ELEM_ENC_H265_SW, encode_name);
else
bin->encoder = gst_element_factory_make (NVDS_ELEM_ENC_H265_HW, encode_name);
break;
default:
goto done;
}
if (!bin->encoder) {
NVGSTDS_ERR_MSG_V ("Failed to create '%s'", encode_name);
goto done;
}
if (config->enc_type == NV_DS_ENCODER_TYPE_SW) {
//bitrate is in kbits/sec for software encoder x264enc and x265enc
g_object_set (G_OBJECT (bin->encoder), "bitrate", config->bitrate/1000, NULL);
} else {
g_object_set (G_OBJECT (bin->encoder), "bitrate", config->bitrate, NULL);
g_object_set (G_OBJECT (bin->encoder), "profile", config->profile, NULL);
g_object_set (G_OBJECT (bin->encoder), "iframeinterval", config->iframeinterval, NULL);
}
#ifdef IS_TEGRA
g_object_set (G_OBJECT (bin->encoder), "preset-level", 1, NULL);
g_object_set (G_OBJECT (bin->encoder), "insert-sps-pps", 1, NULL);
//g_object_set (G_OBJECT (bin->encoder), "bufapi-version", 1, NULL);
#else
g_object_set (G_OBJECT (bin->transform), "gpu-id", config->gpu_id, NULL);
#endif
bin->mux = gst_element_factory_make ("flvmux", "sink_sub_bin_mux");
if (!bin->mux) {
NVGSTDS_ERR_MSG_V ("Failed to create '%s'", "sink_sub_bin_mux");
goto done;
}
g_object_set (G_OBJECT (bin->mux), "name", "mux", "streamable", TRUE, NULL);
bin->sink = gst_element_factory_make ("rtmpsink", elem_name);
if (!bin->sink) {
NVGSTDS_ERR_MSG_V ("Failed to create '%s'", elem_name);
goto done;
}
char url[128] = {0};
sprintf(url, "rtmp://127.0.0.1:%d/road/%d", config->udp_port, config->rtsp_port);//自己修改ip和路径
g_object_set (G_OBJECT (bin->sink), "location", url, NULL);//"rtmp://10.1.1.101/live/livestream"
g_print ("%s: DEBUGGER create_rtmp_sink \n", url);//"rtmp://10.1.1.101/live/livestream"
gst_bin_add_many (GST_BIN (bin->bin), bin->queue, bin->transform,
bin->encoder, bin->codecparse, bin->mux, bin->sink, NULL);
NVGSTDS_LINK_ELEMENT (bin->queue, bin->transform);
NVGSTDS_LINK_ELEMENT (bin->transform, bin->encoder);
NVGSTDS_LINK_ELEMENT (bin->encoder, bin->codecparse);
NVGSTDS_LINK_ELEMENT (bin->codecparse, bin->mux);
NVGSTDS_LINK_ELEMENT (bin->mux, bin->sink);
NVGSTDS_BIN_ADD_GHOST_PAD (bin->bin, bin->queue, "sink");
ret = TRUE;
if (ret != TRUE) {
g_print ("%s: start_rtmp_straming function failed\n", __func__);
}
g_print ("%s: Started streaming RTMP\n", __func__);
done:
if (caps) {
gst_caps_unref (caps);
}
if (!ret) {
NVGSTDS_ERR_MSG_V ("%s failed", __func__);
}
return ret;
}
3,在/opt/nvidia/deepstream/deepstream/sources/apps/apps-common/src/deepstream_sink_bin.c中查找“case NV_DS_SINK_MSG_CONV_BROKER:”在后面加上“case SINK_RTMP:”(一共有两处)
case NV_DS_SINK_MSG_CONV_BROKER:
config_array[i].msg_conv_broker_config.sync = config_array[i].sync;
if (!create_msg_conv_broker_bin (&config_array[i].
msg_conv_broker_config, &bin->sub_bins[i]))
goto done;
break;
case SINK_RTMP:
if (!create_rtmpsink_bin (&config_array[i].encoder_config,
&bin->sub_bins[i]))
goto done;
break;
4,去目标app源码目录下执行“sudo make install”
5,在config文件中修改“type=7”,“rtsp-port”和“udp-port”参数在uri上有用到,最后推流的地址是“rtmp://127.0.0.1:{udp-port}/road/{rtsp-port}”,有其他改动需求自己修代码。
[sink]
enable=0
source-id=11
type=7
codec=1
enc-type=0
sync=1
bitrate=4000000
profile=0
rtsp-port=8565
udp-port=1935
6,Enjoy it!