GStreamer 转rtsp流(广电 / 酒店行业标准)

GStreamer + gst-rtsp-server(广电 / 酒店行业标准),本来以为在AI这么发达的情况下,小白搭建一个将udp/rtp转为rtsp的服务,应该不难,但实际上,都快被整疯的节奏。记录一下。

需求:由于iptv酒店项目需要多个机顶盒播出同步,而只有rtsp才可以的。故广电设备(比如编码器,卫星接收机输出的udp/rtp流)需要经过服务器转为rtsp流,基本就能同步播出的了。

由于自身能力有限,最终只能播出udp转的rtsp流。

推流软件:UdpTsAnalyser_1.61.exe,发送地址udp://239.94.0.31:5140,推送的广电常用的mpeg2格式的音视频流(ts流)。

环境搭建:

1.ubuntu20.04(太新太旧也是一堆错误);能正常运行后;地址为:192.168.11.212

2.进入/root/gst-build/gst-rtsp-server/examples目录:

vlc播放地址:rtsp://192.168.11.212:8554/test

(1)推本地流

./test-mp4 --port 8554 4.mp4

或者

./test-launch --port 8554 "filesrc location=4.mp4 ! qtdemux ! h264parse ! rtph264pay name=pay0 pt=96"

(2)udp不转码!直接封装:

**********udp不卡顿*****最终工业级无卡顿、超低延迟命令(推荐直接用这个) UDP-TS 转 RTSP
./test-launch --port 8554 \
"udpsrc port=5140 multicast-group=239.94.0.31 do-timestamp=false buffer-size=1048576 \
! tsparse set-timestamps=false \
! queue leaky=2 max-size-buffers=0 max-size-bytes=0 max-size-time=100000000 \
! rtpmp2tpay name=pay0 pt=96"

这个vlc播放是流畅的。

由于我们要播放多个节目,那我们重写test-launch.c的代码,root目录下建立my_rtsp_server目录:

1.频道地址配置文件:ch.conf

239.94.0.31:5140
239.94.0.32:5140
239.94.0.33:5140
239.94.0.34:5140
239.94.0.35:5140
239.94.0.36:5140
239.94.0.37:5140
239.94.0.38:5140
239.94.0.39:5140
239.94.0.40:5140

2.main.c文件,可以读取频道配置文件:

#include <gst/gst.h>
#include <gst/rtsp-server/rtsp-server.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define DEFAULT_RTSP_PORT "8554"
#define CHANNEL_FILE "ch.conf"

static char *port = (char *)DEFAULT_RTSP_PORT;

static GOptionEntry entries\[\] = {
{"port", 'p', 0, G_OPTION_ARG_STRING, &port,
"RTSP server port (default: 8554)", "PORT"},
{NULL}
};

typedef struct {
char ip50;
int udp_port;
} Channel;

int read_channels(Channel channels\[\], int max) {
FILE *f = fopen(CHANNEL_FILE, "r");
if (!f) {
g_printerr("Cannot open %s\n", CHANNEL_FILE);
return -1;
}

int count = 0;
char line128;

while (fgets(line, sizeof(line), f) && count < max) {
memset(&channelscount, 0, sizeof(Channel));
char clean_line128 = {0};
int j = 0;
for (int i = 0; linei != '\0'; i++) {
char c = linei;
if ((c >= '0' && c <= '9') || c == '.' || c == ':') {
clean_linej++ = c;
}
}

if (strlen(clean_line) < 5) continue;
char *colon = strchr(clean_line, ':');
if (!colon) continue;

*colon = 0;
strcpy(channelscount.ip, clean_line);
channelscount.udp_port = atoi(colon + 1);
count++;
}

fclose(f);
return count;
}

int main(int argc, char *argv\[\]) {
GMainLoop *loop;
GstRTSPServer *server;
GstRTSPMountPoints *mounts;
GOptionContext *optctx;
GError *error = NULL;

Channel channels20 = {0};
int channel_count, i;

optctx = g_option_context_new("- UDP to RTSP Server");
g_option_context_add_main_entries(optctx, entries, NULL);
g_option_context_add_group(optctx, gst_init_get_option_group());
if (!g_option_context_parse(optctx, &argc, &argv, &error)) {
g_printerr("Option error: %s\n", error->message);
g_error_free(error);
return -1;
}
g_option_context_free(optctx);

gst_init(&argc, &argv);
loop = g_main_loop_new(NULL, FALSE);

server = gst_rtsp_server_new();
g_object_set(server, "service", port, NULL);
mounts = gst_rtsp_server_get_mount_points(server);

channel_count = read_channels(channels, 20);
if (channel_count <= 0) {
g_printerr("No channels\n");
return -1;
}

for (i = 0; i < channel_count; i++) {
char mount_path128 = {0};
char pipeline512 = {0};
GstRTSPMediaFactory *factory = gst_rtsp_media_factory_new();

snprintf(mount_path, 127, "/iptv/%s:%d", channelsi.ip, channelsi.udp_port);

snprintf(pipeline, 511,
"udpsrc port=%d multicast-group=%s do-timestamp=false buffer-size=1048576 "
"! tsparse set-timestamps=false "
"! queue leaky=2 max-size-buffers=0 max-size-bytes=0 max-size-time=100000000 "
"! rtpmp2tpay name=pay0 pt=96",
channelsi.udp_port, channelsi.ip);

gst_rtsp_media_factory_set_launch(factory, pipeline);
gst_rtsp_media_factory_set_shared(factory, TRUE);
gst_rtsp_media_factory_set_latency(factory, 0);
gst_rtsp_mount_points_add_factory(mounts, mount_path, factory);

g_print("✅ OK: rtsp://0.0.0.0:%s%s\n", port, mount_path);
}

g_object_unref(mounts);
gst_rtsp_server_attach(server, NULL);

g_print("\n🚀 RTSP server running on port %s\n", port);
g_main_loop_run(loop);
return 0;
}

3.编译:

gcc main.c -o main `pkg-config --cflags --libs gstreamer-1.0 gstreamer-rtsp-server-1.0`

不报错,生成main执行文件即可

4.运行

./main

大概会显示:

root@linux:~/my_rtsp_server# ./main

? OK: rtsp://0.0.0.0:8554/iptv/239.94.0.31:5140

? OK: rtsp://0.0.0.0:8554/iptv/239.94.0.32:5140

? OK: rtsp://0.0.0.0:8554/iptv/239.94.0.33:5140

? OK: rtsp://0.0.0.0:8554/iptv/239.94.0.34:5140

? OK: rtsp://0.0.0.0:8554/iptv/239.94.0.35:5140

? OK: rtsp://0.0.0.0:8554/iptv/239.94.0.36:5140

? OK: rtsp://0.0.0.0:8554/iptv/239.94.0.37:5140

? OK: rtsp://0.0.0.0:8554/iptv/239.94.0.38:5140

? OK: rtsp://0.0.0.0:8554/iptv/239.94.0.39:5140

? OK: rtsp://0.0.0.0:8554/iptv/239.94.0.40:5140

? RTSP server running on port 8554

这就算正常的了,用vlc打开这些地址:

rtsp://192.168.11.212:8554/iptv/239.94.0.31:5140

rtsp://192.168.11.212:8554/iptv/239.94.0.32:5140

rtsp://192.168.11.212:8554/iptv/239.94.0.33:5140等,可以正常播放就可以了。

相关推荐
有续技术17 分钟前
哈斯 (Haas) 机床 IP、端口号配置内容总结
运维·服务器
心念枕惊29 分钟前
新写了个直播录制工具,可录制抖音快手斗鱼直播
运维·服务器·数据库
躺不平的理查德39 分钟前
CMAKE备忘录
linux·运维·服务器
9624561 小时前
跨域与私有网络访问限制排查实录
运维·服务器·网络
不在逃避q2 小时前
一步一步学习使用LiveBindings()TListView进阶使用(),打造天气预报程序
服务器·数据库·学习
诸葛老刘2 小时前
Ubuntu 服务器常用运维命令
运维·服务器·ubuntu
红叶舞2 小时前
成数据绑定对象,在应用程序中处理完数据后,将更新的数据序列化为JSON传回远端服务器,很多移动应用使用了这种模式处理服务器端的数据。 ...
运维·服务器·json
深圳恒讯2 小时前
H100服务器是什么?H100服务器适合哪些企业?
运维·服务器
ZJH__GO2 小时前
网络编程v4--群聊和私聊的实现
运维·服务器·网络
Ivan CloudBay3 小时前
SDK 游戏盾如何隐藏游戏服务器的真实 IP?
服务器·tcp/ip·游戏