当前位置:   article > 正文

跨平台轻量级RTSP服务模块设计思路及实现探讨_rtspserver 并发数

rtspserver 并发数

技术背景

为满足内网无纸化/电子教室等内网超低延迟需求,避免让用户配置单独的服务器,我们发布了轻量级RTSP服务模块,轻量级RTSP服务解决的核心痛点是避免用户或者开发者单独部署RTSP或者RTMP服务,实现本地的音视频数据(如摄像头、麦克风),编码后,汇聚到内置RTSP服务,对外提供可供拉流的RTSP URL,轻量级RTSP服务,适用于内网环境下,对并发要求不高的场景,支持H.264/H.265,支持RTSP鉴权、单播、组播模式,考虑到单个服务承载能力,我们支持同时创建多个RTSP服务,并支持获取当前RTSP服务会话连接数。

以下是轻量级RTSP服务的一些特点:

1. 简单易用:SDK 提供了完整的 RTSP服务功能,包括音频格式、视频格式、传输模式、端口设置、鉴权设置等,开发者可以轻松地使用这些功能进行 RTSP服务开发。

2. 跨平台支持:SDK 支持 Windows、Android 和 iOS 平台,开发者可以在不同的平台上进行 RTSP服务开发,并且可以使用多种编程语言进行开发。

3. 音频和视频处理:SDK 提供了音频和视频的处理功能,包括采集麦克风、采集扬声器、音频格式转换、视频格式转换等,开发者可以使用这些功能实现音视频的采集和处理。

4. 摄像头和屏幕合成:SDK 支持摄像头和屏幕的实时切换,可以单画面显示摄像头或屏幕,并且支持摄像头和屏幕的合成处理,让开发者能够实现更多的监控和展示功能。

5. 音频处理:SDK 支持音频的噪音抑制、自动增益控制等功能,可以帮助开发者实现更好的音频处理效果。

6. 安全性:SDK 支持密码验证和鉴权设置,可以保护 RTSP服务的网络安全和数据安全。

7. 多服务支持:SDK 支持同时创建多个内置 RTSP 服务,并且支持 H.265 视频编码,可以帮助开发者实现更多的监控和服务需求。

功能支持:

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

接口设计

以Android平台为例,接口设计如下:

  1. /*
  2. * SmartPublisherJniV2.java
  3. * Author: daniusdk.com
  4. * Created on 2015/09/20.
  5. */
  6. /*
  7. * Init rtsp server(和UnInitRtspServer配对使用,即便是启动多个RTSP服务,也只需调用一次InitRtspServer,请确保在OpenRtspServer之前调用)
  8. *
  9. * @param ctx: get by this.getApplicationContext()
  10. *
  11. * @return {0} if successful
  12. */
  13. public native int InitRtspServer(Object ctx);
  14. /*
  15. * 创建一个rtsp server
  16. *
  17. * @param reserve:保留参数传0
  18. *
  19. * @return rtsp server 句柄
  20. */
  21. public native long OpenRtspServer(int reserve);
  22. /*
  23. * 设置rtsp server 监听端口, 在StartRtspServer之前必须要设置端口
  24. *
  25. * @param rtsp_server_handle: rtsp server 句柄
  26. *
  27. * @param port: 端口号,可以设置为554,或者是1024到65535之间,其他值返回失败
  28. *
  29. * @return {0} if successful
  30. */
  31. public native int SetRtspServerPort(long rtsp_server_handle, int port);
  32. /*
  33. * 设置rtsp server 鉴权用户名和密码, 这个可以不设置,只有需要鉴权的再设置
  34. *
  35. * @param rtsp_server_handle: rtsp server 句柄
  36. *
  37. * @param user_name: 用户名(必须是英文)
  38. *
  39. * @param password:密码(必须是英文)
  40. *
  41. * @return {0} if successful
  42. */
  43. public native int SetRtspServerUserNamePassword(long rtsp_server_handle, String user_name, String password);
  44. /*
  45. * 设置rtsp server 组播, 如果server设置成组播就不能单播,组播和单播只能选一个, 一般来说单播网络设备支持的好,wifi组播很多路由器不支持
  46. *
  47. * @param rtsp_server_handle: rtsp server 句柄
  48. *
  49. * @param is_multicast: 是否组播, 1为组播, 0为单播, 其他值接口返回错误, 默认是单播
  50. *
  51. * @return {0} if successful
  52. */
  53. public native int SetRtspServerMulticast(long rtsp_server_handle, int is_multicast);
  54. /*
  55. * 设置rtsp server 组播组播地址
  56. *
  57. * @param rtsp_server_handle: rtsp server 句柄
  58. *
  59. * @param multicast_address: 组播地址
  60. *
  61. * 如果设置的不是组播地址, 将返回错误
  62. * 组播地址范围说明: [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]
  63. *
  64. * @return {0} if successful
  65. */
  66. public native int SetRtspServerMulticastAddress(long rtsp_server_handle, String multicast_address);
  67. /*
  68. * 获取rtsp server当前的客户会话数, 这个接口必须在StartRtspServer之后再调用
  69. *
  70. * @param rtsp_server_handle: rtsp server 句柄
  71. *
  72. * @return {当前rtsp server会话数}
  73. */
  74. public native int GetRtspServerClientSessionNumbers(long rtsp_server_handle);
  75. /*
  76. * 启动rtsp server
  77. *
  78. * @param rtsp_server_handle: rtsp server 句柄
  79. *
  80. * @param reserve: 保留参数传0
  81. *
  82. * @return {0} if successful
  83. */
  84. public native int StartRtspServer(long rtsp_server_handle, int reserve);
  85. /*
  86. * 停止rtsp server
  87. *
  88. * @param rtsp_server_handle: rtsp server 句柄
  89. *
  90. * @return {0} if successful
  91. */
  92. public native int StopRtspServer(long rtsp_server_handle);
  93. /*
  94. * 关闭rtsp server
  95. *
  96. * @param rtsp_server_handle: rtsp server 句柄
  97. *
  98. * NOTE: 调用这个接口之后rtsp_server_handle失效,
  99. *
  100. * @return {0} if successful
  101. */
  102. public native int CloseRtspServer(long rtsp_server_handle);
  103. /*
  104. * UnInit rtsp server(和InitRtspServer配对使用,即便是启动多个RTSP服务,也只需调用一次UnInitRtspServer)
  105. *
  106. * @return {0} if successful
  107. */
  108. public native int UnInitRtspServer();
  109. /*
  110. * 设置rtsp的流名称
  111. *
  112. * @param handle: 推送实例句柄
  113. *
  114. * @param stream_name: 流程名称,不能为空字符串,必须是英文
  115. *
  116. * 这个作用是: 比如rtsp的url是:rtsp://192.168.0.111/test, test就是设置下去的stream_name
  117. *
  118. * @return {0} if successful
  119. */
  120. public native int SetRtspStreamName(long handle, String stream_name);
  121. /*
  122. * 给要发布的rtsp流设置rtsp server, 一个流可以发布到多个rtsp server上,rtsp server的创建启动请参考OpenRtspServer和StartRtspServer接口
  123. *
  124. * @param handle: 推送实例句柄
  125. *
  126. * @param rtsp_server_handle:rtsp server句柄
  127. *
  128. * @param reserve:保留参数,传0
  129. *
  130. * @return {0} if successful
  131. */
  132. public native int AddRtspStreamServer(long handle, long rtsp_server_handle, int reserve);
  133. /*
  134. * 清除设置的rtsp server
  135. *
  136. * @param handle: 推送实例句柄
  137. *
  138. * @return {0} if successful
  139. */
  140. public native int ClearRtspStreamServer(long handle);
  141. /*
  142. * 启动rtsp流
  143. *
  144. * @param handle: 推送实例句柄
  145. *
  146. * @param reserve: 保留参数,传0
  147. *
  148. * @return {0} if successful
  149. */
  150. public native int StartRtspStream(long handle, int reserve);
  151. /*
  152. * 停止rtsp流
  153. *
  154. * @param handle: 推送实例句柄
  155. *
  156. * @return {0} if successful
  157. */
  158. public native int StopRtspStream(long handle);

接口调用示例

启动、停止RTSP服务

  1. //启动/停止RTSP服务
  2. class ButtonRtspServiceListener implements View.OnClickListener {
  3. public void onClick(View v) {
  4. if (isRTSPServiceRunning) {
  5. stopRtspService();
  6. btnRtspService.setText("启动RTSP服务");
  7. btnRtspPublisher.setEnabled(false);
  8. isRTSPServiceRunning = false;
  9. return;
  10. }
  11. Log.i(TAG, "onClick start rtsp service..");
  12. rtsp_handle_ = libPublisher.OpenRtspServer(0);
  13. if (rtsp_handle_ == 0) {
  14. Log.e(TAG, "创建rtsp server实例失败! 请检查SDK有效性");
  15. } else {
  16. int port = 8554;
  17. if (libPublisher.SetRtspServerPort(rtsp_handle_, port) != 0) {
  18. libPublisher.CloseRtspServer(rtsp_handle_);
  19. rtsp_handle_ = 0;
  20. Log.e(TAG, "创建rtsp server端口失败! 请检查端口是否重复或者端口不在范围内!");
  21. }
  22. if (libPublisher.StartRtspServer(rtsp_handle_, 0) == 0) {
  23. Log.i(TAG, "启动rtsp server 成功!");
  24. } else {
  25. libPublisher.CloseRtspServer(rtsp_handle_);
  26. rtsp_handle_ = 0;
  27. Log.e(TAG, "启动rtsp server失败! 请检查设置的端口是否被占用!");
  28. }
  29. btnRtspService.setText("停止RTSP服务");
  30. btnRtspPublisher.setEnabled(true);
  31. isRTSPServiceRunning = true;
  32. }
  33. }
  34. }

发布RTSP流:

  1. //发布/停止RTSP流
  2. class ButtonRtspPublisherListener implements View.OnClickListener {
  3. public void onClick(View v) {
  4. if (isRTSPPublisherRunning) {
  5. stopRtspPublisher();
  6. btnRtspPublisher.setText("发布RTSP流");
  7. btnGetRtspSessionNumbers.setEnabled(false);
  8. btnRtspService.setEnabled(true);
  9. return;
  10. }
  11. Log.i(TAG, "onClick start rtsp publisher..");
  12. if (!isPushingRtmp && !isGB28181StreamRunning && !isRecording) {
  13. InitAndSetConfig();
  14. }
  15. if (publisherHandle == 0) {
  16. Log.e(TAG, "Start rtsp publisher, publisherHandle is null..");
  17. return;
  18. }
  19. String rtsp_stream_name = "stream1";
  20. libPublisher.SetRtspStreamName(publisherHandle, rtsp_stream_name);
  21. libPublisher.ClearRtspStreamServer(publisherHandle);
  22. libPublisher.AddRtspStreamServer(publisherHandle, rtsp_handle_, 0);
  23. if (libPublisher.StartRtspStream(publisherHandle, 0) != 0) {
  24. Log.e(TAG, "调用发布rtsp流接口失败!");
  25. return;
  26. }
  27. if (!isPushingRtmp && !isGB28181StreamRunning && !isRecording) {
  28. CheckInitAudioRecorder(); //enable pure video publisher..
  29. }
  30. startLayerPostThread();
  31. btnRtspPublisher.setText("停止RTSP流");
  32. btnGetRtspSessionNumbers.setEnabled(true);
  33. btnRtspService.setEnabled(false);
  34. isRTSPPublisherRunning = true;
  35. }
  36. }

获取RTSP会话数:

  1. //获取RTSP会话数
  2. class ButtonGetRtspSessionNumbersListener implements View.OnClickListener {
  3. public void onClick(View v) {
  4. if (libPublisher != null && rtsp_handle_ != 0) {
  5. int session_numbers = libPublisher.GetRtspServerClientSessionNumbers(rtsp_handle_);
  6. Log.i(TAG, "GetRtspSessionNumbers: " + session_numbers);
  7. PopRtspSessionNumberDialog(session_numbers);
  8. }
  9. }
  10. }
  11. //当前RTSP会话数弹出框
  12. private void PopRtspSessionNumberDialog(int session_numbers) {
  13. final EditText inputUrlTxt = new EditText(this);
  14. inputUrlTxt.setFocusable(true);
  15. inputUrlTxt.setEnabled(false);
  16. String session_numbers_tag = "RTSP服务当前客户会话数: " + session_numbers;
  17. inputUrlTxt.setText(session_numbers_tag);
  18. AlertDialog.Builder builderUrl = new AlertDialog.Builder(this);
  19. builderUrl
  20. .setTitle("内置RTSP服务")
  21. .setView(inputUrlTxt).setNegativeButton("确定", null);
  22. builderUrl.show();
  23. }

总结

轻量级RTSP服务模块是一个跨平台的、简单易用的 RTSP 服务开发工具包,可以帮助开发者快速实现 RTSP 服务,并且提供多种音视频处理和安全性保障功能,无需单独部署RTSP服务,在内网环境特别是移动端,非常方便。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/611147
推荐阅读
相关标签
  

闽ICP备14008679号