first commit

This commit is contained in:
陈赣
2026-06-03 12:43:14 +08:00
commit ba76cfae28
608 changed files with 120791 additions and 0 deletions

24
third_party/rtsp_server/CMakeLists.txt vendored Normal file
View File

@@ -0,0 +1,24 @@
cmake_minimum_required(VERSION 3.10)
project(rtsp_server VERSION 1.0)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_BUILD_TYPE Debug)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fPIC -w -fdiagnostics-color=always -pthread")
# Gstreamer required
include(FindPkgConfig)
pkg_check_modules(GST REQUIRED gstreamer-1.0)
pkg_check_modules(GSTAPP REQUIRED gstreamer-app-1.0)
pkg_check_modules(GST_RTSP REQUIRED gstreamer-rtsp-server-1.0)
message(STATUS "GStreamer library status:")
message(STATUS " version: ${GST_VERSION}")
message(STATUS " libraries: ${GST_LIBRARIES} ${GSTAPP_LIBRARIES} ${GST_RTSP_LIBRARIES}")
message(STATUS " include path: ${GST_INCLUDE_DIRS}")
include_directories(${GST_INCLUDE_DIRS})
set(GST_DEPEND_LIBS ${GST_LIBRARIES} ${GSTAPP_LIBRARIES} ${GST_RTSP_LIBRARIES})
# build for rtsp_server
file(GLOB SRCS "run_rtsp_server.cpp")
add_executable(run_rtsp_server ${SRCS})
target_link_libraries(run_rtsp_server ${GST_DEPEND_LIBS})

56
third_party/rtsp_server/README.md vendored Normal file
View File

@@ -0,0 +1,56 @@
# rtsp_server #
> NOTE: building of VideoPipe is not dependent on this project.
a simple rtsp server based on `GStreamer` which can accept udp stream and distribute them using `rtsp` protocal something like `rtsp://127.0.0.1:8554/stream1`/`rtsp://127.0.0.1:8554/stream2`.
## how to build ##
first install `GStreamer` refer to `VideoPipe`, and build using CMake:
```
mkdir build && cd build
cmake ..
make -j8
```
## how to run ##
first build `rtsp_server` successfully and run:
`./build/run_rtsp_server [-p] [rtsp_port] [-s] [stream_name1:inner_port1/stream_name2:inner_port2/...]`
```
for example:
./build/run_rtsp_server -p 8555 -s rtsp0:8000/rtsp1:9000/rtsp2:9005
rtsp server will listen at ports(8000/9000/9005) to receive udp stream and distribute them at port 8555 using rtsp protocal:
########## rtsp server info ###########
(1) rtsp0==>8000==>rtsp://127.0.0.1:8555/rtsp0
(2) rtsp1==>9000==>rtsp://127.0.0.1:8555/rtsp1
(3) rtsp2==>9005==>rtsp://127.0.0.1:8555/rtsp2
```
then you need push your stream to port `8000`, `9000`, `9005` using some multi-media tools like `gst-launch-1.0` or your application.
```
# push udp stream to port 8000
gst-launch-1.0 filesrc location=face2.mp4 ! qtdemux ! h264parse ! avdec_h264 ! x264enc ! rtph264pay ! udpsink host=localhost port=8000
# push udp stream to port 9000
gst-launch-1.0 filesrc location=face2.mp4 ! qtdemux ! h264parse ! avdec_h264 ! x264enc ! rtph264pay ! udpsink host=localhost port=9000
# push udp stream to port 9005
gst-launch-1.0 filesrc location=face2.mp4 ! qtdemux ! h264parse ! avdec_h264 ! x264enc ! rtph264pay ! udpsink host=localhost port=9005
```
now you can pull/play rtsp stream using `vlc` or `gst-launch-1.0` by rtsp urls:
```
rtsp://127.0.0.1:8555/rtsp0
rtsp://127.0.0.1:8555/rtsp1
rtsp://127.0.0.1:8555/rtsp2
```
## how rtsp_server serve VideoPipe? ##
`vp_udp_des_node` in VideoPipe will push udp streams to rtsp_server, which distribute them by rtsp protocal.

View File

@@ -0,0 +1,119 @@
#include <iostream>
#include <thread>
#include <vector>
#include <sstream>
#include <utility>
#include <gst/gst.h>
#include <gst/rtsp-server/rtsp-server.h>
inline std::vector<std::string> string_split(const std::string& s, char delimiter) {
std::vector<std::string> tokens;
std::string token;
std::istringstream tokenStream(s);
while (std::getline(tokenStream, token, delimiter)) {
tokens.push_back(token);
}
return tokens;
}
/*
* usage:
* ./run_rtsp_server [-p] [rtsp_port] [-s] [stream_name1:inner_port1/stream_name2:inner_port2/...]
*
* for example:
* ./run_rtsp_server -p 8554 -s 1st_rtsp:8000/2nd_rtsp:8001/3rd_rtsp:8002
* rtsp server will listen at ports(8000/8001/8002) to receive udp stream and distribute them at port 8554 using rtsp protocal:
* (1) rtsp://127.0.0.1:8554/1st_rtsp
* (2) rtsp://127.0.0.1:8554/2nd_rtsp
* (3) rtsp://127.0.0.1:8554/3rd_rtsp
*/
bool parse_args(int argc, char** argv, std::string& rtsp_port, std::vector<std::pair<std::string, std::string>>& streams_info) {
auto print_error = []() {
std::cout << "invalid arguments!" << std::endl;
std::cout << "./run_rtsp_server [-p] [rtsp_port] [-s] [stream_name1:inner_port1/stream_name2:inner_port2/...]" << std::endl;
};
if (argc != 5) {
print_error();
return false;
}
auto _p = std::string(argv[1]);
rtsp_port = std::string(argv[2]);
auto _s = std::string(argv[3]);
auto streams = std::string(argv[4]);
if (_p != "-p" || _s != "-s") {
print_error();
return false;
}
auto streams_list = string_split(streams, '/');
for (auto& stream: streams_list) {
auto name_port = string_split(stream, ':');
if (name_port.size() != 2) {
print_error();
return false;
}
streams_info.push_back(std::pair<std::string, std::string>(name_port[0], name_port[1]));
}
return true;
}
int main(int argc, char** argv) {
std::string rtsp_port;
std::vector<std::pair<std::string, std::string>> streams_info;
if (!parse_args(argc, argv, rtsp_port, streams_info)) {
return -1;
}
auto rtsp_server_run = [&]() {
GMainLoop* loop;
GstRTSPServer* server;
gst_init(&argc, &argv);
server = gst_rtsp_server_new();
g_object_set(server, "service", rtsp_port.c_str(), NULL);
gst_rtsp_server_attach(server, NULL);
auto mounts = gst_rtsp_server_get_mount_points(server);
for(auto& stream: streams_info) {
auto stream_name = stream.first;
auto stream_port = stream.second;
char udpsrc_pipeline[512];
int udp_buffer_size = 512 * 1024;
// receive stream data from udpsrc internally and push it via rtsp
sprintf (udpsrc_pipeline,
"( udpsrc name=pay0 port=%s buffer-size=%lu caps=\"application/x-rtp, media=video, "
"clock-rate=90000, encoding-name=H264, payload=96 \" )",
stream_port.c_str(), udp_buffer_size);
auto factory = gst_rtsp_media_factory_new();
gst_rtsp_media_factory_set_launch(factory, udpsrc_pipeline);
gst_rtsp_media_factory_set_shared(factory, true);
gst_rtsp_mount_points_add_factory(mounts, ("/" + stream_name).c_str(), factory);
}
g_object_unref(mounts);
std::cout << "########## rtsp server info ###########" << std::endl;
for (int i = 0; i < streams_info.size(); i++) {
std::cout << "(" << i + 1 << ") "
<< streams_info[i].first << "==>" << streams_info[i].second
<< "==>rtsp://127.0.0.1:" << rtsp_port << "/" << streams_info[i].first << std::endl;
}
loop = g_main_loop_new(NULL, FALSE);
g_main_loop_run(loop);
g_main_loop_unref(loop);
gst_object_unref(server);
};
std::thread rtsp_server(rtsp_server_run);
// enter to exit
std::string wait;
std::getline(std::cin, wait);
return 0;
}