如何实现点击按钮停止OBS Studio推流并断开与RTMP服务器的连接?
如何断开RTMP服务器与OBS Studio的推流连接
要实现“停止直播”按钮,核心是主动切断RTMP服务器与OBS之间的TCP连接或终止流会话,而不是删除存储文件夹(服务器会自动重建目录,完全不影响推流进程)。以下是针对主流RTMP服务器的具体解决方案:
一、通用原理
RTMP推流基于TCP长连接,只要服务器不主动断开这个连接,OBS会持续推送数据。删除文件夹只是清理了录制文件,并没有中断底层的连接会话,所以直播会继续。
二、针对不同RTMP服务器的实现方法
1. Nginx-rtmp(开源常用)
Nginx-rtmp本身没有内置的流终止API,但可以通过统计接口+脚本实现:
- 第一步:配置RTMP统计页面
在nginx.conf中添加统计配置,用于获取当前推流的客户端信息:rtmp { server { listen 1935; application live { live on; record all; record_path /tmp/rtmp_records; # 开启统计 rtmp_stat all; rtmp_stat_stylesheet stat.xsl; } } } http { server { listen 8080; location /stat { rtmp_stat all; rtmp_stat_stylesheet stat.xsl; } # 指向nginx-rtmp模块的stat.xsl文件路径 location /stat.xsl { root /usr/local/src/nginx-rtmp-module/; } } } - 第二步:编写停止流的脚本
解析统计页面的XML数据,找到目标流对应的客户端IP和端口,用ss命令强制关闭TCP连接:import requests import xml.etree.ElementTree as ET import subprocess def stop_target_stream(stream_name): # 获取RTMP统计数据 stat_response = requests.get("http://localhost:8080/stat") xml_root = ET.fromstring(stat_response.content) # 遍历找到目标流的客户端连接 for stream_node in xml_root.findall('.//stream'): if stream_node.find('name').text == stream_name: for client_node in stream_node.findall('.//client'): client_ip = client_node.find('ip').text client_port = client_node.find('port').text # 强制关闭连接 subprocess.run( ["ss", "-K", f"dst {client_ip}", f"sport {client_port}"], check=False ) print(f"已断开流 {stream_name} 的客户端连接 {client_ip}:{client_port}") # 调用示例:停止名为live/stream1的流 stop_target_stream("live/stream1") - 第三步:按钮触发脚本
把按钮的点击事件绑定到执行这个脚本的操作(比如后端接口调用脚本,或者前端直接触发脚本执行,根据你的架构调整)。
2. SRS(高性能RTMP服务器)
SRS提供了完善的HTTP控制API,可以直接通过API终止指定流:
- 发送POST请求到SRS的流控制接口(以SRS 4.x为例):
比如你的流是curl -X POST http://<SRS服务器IP>:1985/api/v1/streams/<流名称>/stoplive/stream1,请求就是http://localhost:1985/api/v1/streams/live/stream1/stop - 你的停止按钮只需要触发这个HTTP请求即可,SRS会主动断开与OBS的推流连接,并停止流的分发。
3. 自定义RTMP服务器
如果是你自己开发的RTMP服务器,只需在代码中维护流会话列表:
- 当点击停止按钮时,根据流名称找到对应的会话实例;
- 调用socket的关闭方法(比如Java的
socket.close(),Python的socket.close()),同时清理该流的相关资源(如录制文件句柄、缓存等)。
内容的提问来源于stack exchange,提问作者Jun Su
相关产品推荐
相关产品推荐

