Linux平台如何实现采集音视频数据并注入轻量级RTSP服务?

​技术背景

好多开发者,问我们最多的问题是,为什么要设计轻量级RTSP服务?轻量级RTSP服务,和RTSP服务有什么区别?

针对这个问题,我们的回答是:轻量级RTSP服务解决的核心痛点是避免用户或者开发者单独部署RTSP服务或者RTMP服务,RTSP服务,并发或功能相对强大,数据注入模式一般是外部直接推流到RTSP服务(目前大多流媒体服务,以RTMP居多,RTSP的相对较少,或者说,可以商用的RTSP服务,相对较少,音视频数据推送这块,RTMP推送为主,很少有RTSP推流),轻量级RTSP服务,直接部署在数据源测,相当于采集到的屏幕、摄像头、麦克风数据,直接编码注入本地的轻量级RTSP服务,对外提供个可供拉流的RTSP URL,说到这里,轻量级RTSP服务,更像一个IPC摄像头,侧重的不是并发,而是便捷。

设计架构图

Windows、Android、iOS平台的轻量级RTSP服务,不再赘述,之前都有描述,今天介绍的是Linux平台下的轻量级RTSP服务。

和其他平台一样,我们Linux平台依然实现的是本地的音视频数据(如屏幕、摄像头、麦克风),编码打包后,汇聚到内置RTSP服务,对外提供可供拉流的RTSP URL,轻量级RTSP服务,适用于内网环境下,对并发要求不高的场景,支持H.264/H.265,支持RTSP鉴权、单播、组播模式,考虑到单个服务承载能力,我们支持同时创建多个RTSP服务,并支持获取当前RTSP服务会话连接数。

功能设计

  • 基础功能\]支持常规的屏幕、摄像机、音频采集处理等;

  • 视频格式\]H.264、H.265;

  • 传输模式\]支持单播和组播模式;

  • 鉴权设置\]支持RTSP鉴权用户名、密码设置;

  • 多服务支持\]支持同时创建多个内置RTSP服务;

  • RTSP url回调\]支持设置后的rtsp url通过event回调到上层。

RTSP Server操作接口设计:

scss 复制代码
        /*
         * nt_linux_smart_publisher_sdk.h
         * Created by daniusdk.com
         */

        /*+++rtsp server操作接口+++*/


		/*
		* 创建一个rtsp server 
		* pRtspServerHandle: rtsp server 句柄
		* reserve:保留参数传0
		* 成功返回 NT_ERC_OK
		*/
		NT_UINT32(NT_API *OpenRtspServer)(NT_PHANDLE pRtspServerHandle, NT_INT32 reserve);

		/*
		* 设置rtsp server 监听端口, 在StartRtspServer之前必须要设置端口
		* rtsp_server_handle: rtsp server 句柄
		* port: 端口号,可以设置为554,或者是1024到65535之间,其他值返回失败
		* 成功返回 NT_ERC_OK
		*/
		NT_UINT32(NT_API *SetRtspServerPort)(NT_HANDLE rtsp_server_handle, NT_INT32 port);

		/*
		* 设置rtsp server 鉴权用户名和密码, 这个可以不设置,只有需要鉴权的再设置
		* rtsp_server_handle: rtsp server 句柄
		* user_name: 用户名,必须是英文
		* password:密码,必须是英文
		* 成功返回 NT_ERC_OK
		*/
		NT_UINT32(NT_API *SetRtspServerUserNamePassword)(NT_HANDLE rtsp_server_handle, NT_PCSTR user_name, NT_PCSTR password);


		/*
		* 设置rtsp server 组播, 如果server设置成组播就不能单播,组播和单播只能选一个, 一般来说单播网络设备支持的好,wifi组播很多路由器不支持
		* rtsp_server_handle: rtsp server 句柄
		* is_multicast: 是否组播, 1为组播, 0为单播, 其他值接口返回错误, 默认是单播
		* 成功返回 NT_ERC_OK
		*/
		NT_UINT32(NT_API *SetRtspServerMulticast)(NT_HANDLE rtsp_server_handle, NT_INT32 is_multicast);


		/*
		* 设置rtsp server 组播组播地址 
		* rtsp_server_handle: rtsp server 句柄
		* multicast_address: 组播地址
		* 如果设置的不是组播地址, 将返回错误
		* 组播地址范围说明: [224.0.0.0, 224.0.0.255] 为组播预留地址, 不能设置. 可设置范围为[224.0.1.0, 239.255.255.255], 其中SSM地址范围为[232.0.0.0, 232.255.255.255]
		* 成功返回 NT_ERC_OK
		*/
		NT_UINT32(NT_API *SetRtspServerMulticastAddress)(NT_HANDLE rtsp_server_handle, NT_PCSTR multicast_address);


		/*
		* 获取rtsp server当前的客户会话数, 这个接口必须在StartRtspServer之后再调用
		* rtsp_server_handle: rtsp server 句柄
		* session_numbers: 会话数
		* 成功返回 NT_ERC_OK
		*/
		NT_UINT32(NT_API *GetRtspServerClientSessionNumbers)(NT_HANDLE rtsp_server_handle, NT_INT32* session_numbers);


		/*
		* 启动rtsp server
		* rtsp_server_handle: rtsp server 句柄
		* reserve: 保留参数传0
		* 成功返回 NT_ERC_OK
		*/
		NT_UINT32(NT_API *StartRtspServer)(NT_HANDLE rtsp_server_handle, NT_INT32 reserve);

		/*
		* 停止rtsp server
		* rtsp_server_handle: rtsp server 句柄
		* 成功返回 NT_ERC_OK
		*/
		NT_UINT32(NT_API *StopRtspServer)(NT_HANDLE rtsp_server_handle);

		/*
		* 关闭rtsp server
		* 调用这个接口之后rtsp_server_handle失效,
		* 成功返回 NT_ERC_OK
		*/
		NT_UINT32 (NT_API *CloseRtspServer)(NT_HANDLE rtsp_server_handle);


		/*---rtsp server操作接口---*/

发布RTSP流相关接口设计:

scss 复制代码
	/*
         * nt_linux_smart_publisher_sdk.h
         * Created by daniusdk.com
         */

               /*+++发布rtsp流相关接口+++*/


		/*
		* 设置rtsp的流名称
		* stream_name: 流程名称,不能为空字符串,必须是英文
		* 这个作用是: 比如rtsp的url是:rtsp://192.168.0.111/test, test就是设置下去的stream_name
		* 成功返回 NT_ERC_OK
		*/
		NT_UINT32(NT_API *SetRtspStreamName)(NT_HANDLE handle, NT_PCSTR stream_name);

		/*
		* 给要发布的rtsp流设置rtsp server, 一个流可以发布到多个rtsp server上,rtsp server的创建启动请参考OpenRtspServer和StartRtspServer接口
		* handle: 推送实例句柄
		* rtsp_server_handle:rtsp server句柄 
		* reserve: 保留参数,传0
		*/
		NT_UINT32(NT_API *AddRtspStreamServer)(NT_HANDLE handle, NT_HANDLE rtsp_server_handle, NT_INT32 reserve);

		
		/*
		* 清除设置的rtsp server
		*/
		NT_UINT32(NT_API *ClearRtspStreamServer)(NT_HANDLE handle);


		/*
		启动rtsp流
		reserve: 保留参数,传0
		*/
		NT_UINT32(NT_API *StartRtspStream)(NT_HANDLE handle, NT_INT32 reserve);

		
		/*
		停止rtsp流
		*/
		NT_UINT32(NT_API *StopRtspStream)(NT_HANDLE handle);


		/*---发布rtsp流相关接口---*/

调用实现

启动RTSP Server:

scss 复制代码
	NT_HANDLE start_rtsp_server(NT_SmartPublisherSDKAPI* push_api, int port, std::string user_name, std::string password) {

		NT_HANDLE rtsp_server_handle = nullptr;
		if (NT_ERC_OK != push_api->OpenRtspServer(&rtsp_server_handle, 0)) {
			fprintf(stderr, "OpenRtspServer failed\n");
			return nullptr;
		}

		if (nullptr == rtsp_server_handle) {
			fprintf(stderr, "rtsp_server_handle is null\n");
			return nullptr;
		}

		if (NT_ERC_OK != push_api->SetRtspServerPort(rtsp_server_handle, port)) {
			push_api->CloseRtspServer(rtsp_server_handle);
			return nullptr;
		}

		if (!user_name.empty() && !password.empty())
			push_api->SetRtspServerUserNamePassword(rtsp_server_handle, user_name.c_str(), password.c_str());

		if (NT_ERC_OK == push_api->StartRtspServer(rtsp_server_handle, 0))
			return rtsp_server_handle;

		fprintf(stderr, "StartRtspServer failed\n");
		push_api->CloseRtspServer(rtsp_server_handle);
		
		return nullptr;
	}

停止RTSP Server:

ini 复制代码
	void stop_rtsp_server(NT_SmartPublisherSDKAPI* push_api, NT_HANDLE& rtsp_server_handle) {
		if (nullptr == rtsp_server_handle)
			return;

		NT_HANDLE handle = rtsp_server_handle;
		rtsp_server_handle = nullptr;

		push_api->StopRtspServer(handle);
		push_api->CloseRtspServer(handle);
	}

开始发布RTSP Stream:

rust 复制代码
	bool start_rtsp_stream(NT_SmartPublisherSDKAPI* push_api, NT_HANDLE rtsp_server_handle, NT_HANDLE handle, const std::string stream_name) {

		push_api->SetRtspStreamName(handle, stream_name.c_str());

		push_api->ClearRtspStreamServer(handle);

		push_api->AddRtspStreamServer(handle, rtsp_server_handle, 0);
		
		if (NT_ERC_OK != push_api->StartRtspStream(handle, 0))
			return false;

		return true;
	}

如需停止RTSP流的发布,直接调用:

scss 复制代码
	stop_rtsp_server(&push_api, rtsp_server_handle);

如果需要采集到的音视频数据预览,调用预览接口即可:

arduino 复制代码
	// 开启预览,也可以不开启, 根据需求来
	push_api.SetPreviewXWindow(push_handle, "", sub_wid);
	push_api.StartPreview(push_handle, 0, nullptr);

总结

轻量级RTSP服务,并发这块不是强项,不过确实解决了单独部署RTSP或RTMP服务的痛点,减少了工程实施成本,在并发量要求不高的场景下,非常方便。

相关推荐
aqi001 天前
FFmpeg开发笔记(九十九)基于Kotlin的国产开源播放器DKVideoPlayer
android·ffmpeg·kotlin·音视频·直播·流媒体
字节架构前端3 天前
媒体采集标准草案 与 Chromium 音频采集实现简介
前端·chrome·音视频开发
Tiny_React7 天前
使用 Claude Code Skills 模拟的视频生成流程
人工智能·音视频开发·vibecoding
aqi008 天前
FFmpeg开发笔记(九十八)基于FFmpeg的跨平台图形用户界面LosslessCut
android·ffmpeg·kotlin·音视频·直播·流媒体
aqi008 天前
FFmpeg开发笔记(九十七)国产的开源视频剪辑工具AndroidVideoEditor
android·ffmpeg·音视频·直播·流媒体
aqi009 天前
FFmpeg开发笔记(一百)国产的Android开源视频压缩工具VideoSlimmer
android·ffmpeg·音视频·直播·流媒体
haibindev11 天前
【终极踩坑指南】Windows 10上MsQuic证书加载失败?坑不在证书,而在Schannel!
直播·http3·quic·流媒体
飞鸟真人15 天前
livekit搭建与使用浏览器测试
直播·视频会议·视频聊天·livekit
hk112415 天前
【音视频/边缘计算】2025年度H.265/HEVC高并发解码与画质修复(Super-Resolution)基准测试报告(含沙丘/失控玩家核心样本)
ffmpeg·边缘计算·音视频开发·h.265·测试数据集
aqi0022 天前
FFmpeg开发笔记(九十五)国产的开源视频美颜工具VideoEditorForAndroid
android·ffmpeg·音视频·直播·流媒体