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

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

 技术背景

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

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

设计架构图

流程图.png

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

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

功能设计

  • [基础功能]支持常规的屏幕、摄像机、音频采集处理等;
  • [音频格式]AAC;
  • [视频格式]H.264、H.265;
  • [协议类型]RTSP;
  • [传输模式]支持单播和组播模式;
  • [端口设置]支持RTSP端口设置;
  • [鉴权设置]支持RTSP鉴权用户名、密码设置;
  • [获取session连接数]支持获取当前RTSP服务会话连接数;
  • [多服务支持]支持同时创建多个内置RTSP服务;
  • [H.265支持]Windows内置rtsp server支持发布H.265视频(64位库);
  • [RTSP url回调]支持设置后的rtsp url通过event回调到上层。

接口设计

RTSP Server操作接口设计:

/** 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_PHANDLEpRtspServerHandle, NT_INT32reserve);
/** 设置rtsp server 监听端口, 在StartRtspServer之前必须要设置端口* rtsp_server_handle: rtsp server 句柄* port: 端口号,可以设置为554,或者是1024到65535之间,其他值返回失败* 成功返回 NT_ERC_OK*/NT_UINT32(NT_API*SetRtspServerPort)(NT_HANDLErtsp_server_handle, NT_INT32port);
/** 设置rtsp server 鉴权用户名和密码, 这个可以不设置,只有需要鉴权的再设置* rtsp_server_handle: rtsp server 句柄* user_name: 用户名,必须是英文* password:密码,必须是英文* 成功返回 NT_ERC_OK*/NT_UINT32(NT_API*SetRtspServerUserNamePassword)(NT_HANDLErtsp_server_handle, NT_PCSTRuser_name, NT_PCSTRpassword);
/** 设置rtsp server 组播, 如果server设置成组播就不能单播,组播和单播只能选一个, 一般来说单播网络设备支持的好,wifi组播很多路由器不支持* rtsp_server_handle: rtsp server 句柄* is_multicast: 是否组播, 1为组播, 0为单播, 其他值接口返回错误, 默认是单播* 成功返回 NT_ERC_OK*/NT_UINT32(NT_API*SetRtspServerMulticast)(NT_HANDLErtsp_server_handle, NT_INT32is_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_HANDLErtsp_server_handle, NT_PCSTRmulticast_address);
/** 获取rtsp server当前的客户会话数, 这个接口必须在StartRtspServer之后再调用* rtsp_server_handle: rtsp server 句柄* session_numbers: 会话数* 成功返回 NT_ERC_OK*/NT_UINT32(NT_API*GetRtspServerClientSessionNumbers)(NT_HANDLErtsp_server_handle, NT_INT32*session_numbers);
/** 启动rtsp server* rtsp_server_handle: rtsp server 句柄* reserve: 保留参数传0* 成功返回 NT_ERC_OK*/NT_UINT32(NT_API*StartRtspServer)(NT_HANDLErtsp_server_handle, NT_INT32reserve);
/** 停止rtsp server* rtsp_server_handle: rtsp server 句柄* 成功返回 NT_ERC_OK*/NT_UINT32(NT_API*StopRtspServer)(NT_HANDLErtsp_server_handle);
/** 关闭rtsp server* 调用这个接口之后rtsp_server_handle失效,* 成功返回 NT_ERC_OK*/NT_UINT32 (NT_API*CloseRtspServer)(NT_HANDLErtsp_server_handle);
/*---rtsp server操作接口---*/

image.gif

发布RTSP流相关接口设计:

/** 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_HANDLEhandle, NT_PCSTRstream_name);
/** 给要发布的rtsp流设置rtsp server, 一个流可以发布到多个rtsp server上,rtsp server的创建启动请参考OpenRtspServer和StartRtspServer接口* handle: 推送实例句柄* rtsp_server_handle:rtsp server句柄 * reserve: 保留参数,传0*/NT_UINT32(NT_API*AddRtspStreamServer)(NT_HANDLEhandle, NT_HANDLErtsp_server_handle, NT_INT32reserve);
/** 清除设置的rtsp server*/NT_UINT32(NT_API*ClearRtspStreamServer)(NT_HANDLEhandle);
/*启动rtsp流reserve: 保留参数,传0*/NT_UINT32(NT_API*StartRtspStream)(NT_HANDLEhandle, NT_INT32reserve);
/*停止rtsp流*/NT_UINT32(NT_API*StopRtspStream)(NT_HANDLEhandle);
/*---发布rtsp流相关接口---*/

image.gif

调用实现

启动RTSP Server:

NT_HANDLEstart_rtsp_server(NT_SmartPublisherSDKAPI*push_api, intport, std::stringuser_name, std::stringpassword) {
NT_HANDLErtsp_server_handle=nullptr;
if (NT_ERC_OK!=push_api->OpenRtspServer(&rtsp_server_handle, 0)) {
fprintf(stderr, "OpenRtspServer failed\n");
returnnullptr;
        }
if (nullptr==rtsp_server_handle) {
fprintf(stderr, "rtsp_server_handle is null\n");
returnnullptr;
        }
if (NT_ERC_OK!=push_api->SetRtspServerPort(rtsp_server_handle, port)) {
push_api->CloseRtspServer(rtsp_server_handle);
returnnullptr;
        }
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))
returnrtsp_server_handle;
fprintf(stderr, "StartRtspServer failed\n");
push_api->CloseRtspServer(rtsp_server_handle);
returnnullptr;
    }

image.gif

停止RTSP Server:

voidstop_rtsp_server(NT_SmartPublisherSDKAPI*push_api, NT_HANDLE&rtsp_server_handle) {
if (nullptr==rtsp_server_handle)
return;
NT_HANDLEhandle=rtsp_server_handle;
rtsp_server_handle=nullptr;
push_api->StopRtspServer(handle);
push_api->CloseRtspServer(handle);
    }

image.gif

开始发布RTSP Stream:

boolstart_rtsp_stream(NT_SmartPublisherSDKAPI*push_api, NT_HANDLErtsp_server_handle, NT_HANDLEhandle, conststd::stringstream_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))
returnfalse;
returntrue;
    }

image.gif

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

stop_rtsp_server(&push_api, rtsp_server_handle);

image.gif

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

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

image.gif

总结

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

相关文章
|
4天前
|
Linux 编译器 调度
xenomai内核解析--双核系统调用(二)--应用如何区分xenomai/linux系统调用或服务
本文介绍了如何将POSIX应用程序编译为在Xenomai实时内核上运行的程序。
20 1
xenomai内核解析--双核系统调用(二)--应用如何区分xenomai/linux系统调用或服务
|
4天前
|
存储 缓存 Linux
xenomai内核解析--xenomai与普通linux进程之间通讯XDDP(三)--实时与非实时数据交互
本文介绍了Xenomai中的XDDP(Xenomai Distributed Data Protocol)通信机制,XDDP用于实时和非实时进程之间的数据交换。XDDP在Xenomai内核中涉及的数据结构和管理方式,以及创建XDDP通道后的实时端和非实时端连接过程。
8 0
xenomai内核解析--xenomai与普通linux进程之间通讯XDDP(三)--实时与非实时数据交互
|
4天前
|
消息中间件 测试技术 Linux
linux实时操作系统xenomai x86平台基准测试(benchmark)
本文是关于Xenomai实时操作系统的基准测试,旨在评估其在低端x86平台上的性能。测试模仿了VxWorks的方法,关注CPU结构、指令集等因素对系统服务耗时的影响。测试项目包括信号量、互斥量、消息队列、任务切换等,通过比较操作前后的时戳来测量耗时,并排除中断和上下文切换的干扰。测试结果显示了各项操作的最小、平均和最大耗时,为程序优化提供参考。注意,所有数据基于特定硬件环境,测试用例使用Alchemy API编写。
10 0
linux实时操作系统xenomai x86平台基准测试(benchmark)
|
6天前
|
数据采集 Linux Go
Linux系统是如何控制串口收发数据的?
Linux系统是如何控制串口收发数据的?
17 0
|
7天前
|
Web App开发 安全 Unix
Linux 配置FTP服务器 + vsftpd服务安装配置 (Good篇)
Linux 配置FTP服务器 + vsftpd服务安装配置 (Good篇)
|
7天前
|
分布式计算 大数据 Hadoop
【经验分享】用Linux脚本管理虚拟机下的大数据服务
【经验分享】用Linux脚本管理虚拟机下的大数据服务
15 1
|
13天前
|
负载均衡 网络协议 应用服务中间件
【亮剑】在Linux中构建高可用性和高性能网络服务的负载均衡工具HAProxy、Nginx和Keepalived。
【4月更文挑战第30天】本文介绍了在Linux中构建高可用性和高性能网络服务的负载均衡工具HAProxy、Nginx和Keepalived。HAProxy是一个高性能的开源TCP和HTTP负载均衡器,适合处理大量并发连接;Nginx是一个多功能Web服务器和反向代理,支持HTTP、HTTPS和TCP负载均衡,同时提供缓存和SSL功能;Keepalived用于监控和故障切换,通过VRRP实现IP热备份,保证服务连续性。文中详细阐述了如何配置这三个工具实现负载均衡,包括安装、配置文件修改和启动服务,为构建可靠的负载均衡系统提供了指导。
|
13天前
|
Linux 开发者
【亮剑】Linux系统中的四种文件锁定机制:flock、fcntl、lockfile和flockfile,用于多进程环境下协调共享资源访问,防止数据损坏和竞争条件
【4月更文挑战第30天】本文介绍了Linux系统中的四种文件锁定机制:flock、fcntl、lockfile和flockfile,用于多进程环境下协调共享资源访问,防止数据损坏和竞争条件。flock适合脚本,fcntl提供底层灵活性,lockfile用于管理锁定文件,flockfile则结合两者功能。选择锁定策略时需考虑应用场景,如脚本可选flock,复杂需求则用fcntl。理解并正确使用这些工具对保证系统稳定性和数据一致性至关重要。
|
15天前
|
安全 Linux 网络安全
【专栏】在 Linux 中,端口连接服务和应用,过多开放的端口可能带来安全隐患,教你一招找出所有开放的端口,然后直接干掉!
【4月更文挑战第28天】在 Linux 中,端口连接服务和应用,过多开放的端口可能带来安全隐患。要找出开放端口,可使用 `netstat -anp`、`lsof -i` 或 `nmap` 命令。关闭端口可通过停止相关服务、修改防火墙规则或禁用网络接口。注意不要随意关闭重要端口,操作前备份数据。保持端口安全对系统安全至关重要。
|
15天前
|
存储 Linux Shell
【进厂修炼 - Second week】Linux服务及用户设置
【进厂修炼 - Second week】Linux服务及用户设置