转载请注明出处:https://blog.csdn.net/impingo
项目地址:https://github.com/im-pingo/
项目官网:http://pingos.io
控制台接口
一个成熟的媒体服务器需要有跟业系统对接的能力,例如允许开发者开发自己的控制台系统,通过http接口控制当前直播流的暂停与播放,录像功能的暂停与继续等操作。
本项目支持多种控制台控制接口和流信息获取接口。
配置
配置项
配置项 | 参数类型 | 默认值 | 描述 |
---|---|---|---|
rtmp_control | 选项 | all | all: 开启所有控制接口。record: 只开启录像控制接口。drop:只开启关闭连接控制接口。redirect:只开启重定向控制接口。pause:只开启暂停接口。 resume:只开启恢复接口 |
配置模板
user root;
daemon on;
master_process on;
worker_processes 1;
#worker_rlimit 4g;
#working_directory /usr/local/openresty/nginx/logs;
#error_log logs/error.log;
#error_log logs/error.log notice;
error_log logs/error.log info;
worker_rlimit_nofile 102400;
worker_rlimit_core 2G;
working_directory /tmp;
#pid logs/nginx.pid;
events {
use epoll;
worker_connections 1024;
multi_listen unix:/tmp/http 80;
}
stream_zone buckets=1024 streams=4096;
rtmp {
log_format log_json '{$remote_addr, [$time_local]}';
access_log logs/rtmp.log trunc=2s;
server {
listen 1935;
serverid 000;
out_queue 2048;
application live {
rtmp_auto_pull on;
rtmp_auto_pull_port unix:/tmp/rtmp;
# live_record on;
# live_record_path /tmp/record;
# live_record_interval 1m;
record all;
record_path /tmp/record;
# exec_publish_done bash -c "ffmpeg -i /tmp/record/$name.flv -c copy /tmp/record/$basename.mp4";
# exec_publish bash -c "ffmpeg -i rtmp://127.0.0.1/live/$name -c copy -movflags faststart /tmp/record/$name-$starttime.mp4";
idle_streams on;
#
# oclp_pull http://127.0.0.1/p1;
# push rtmp://120.132.13.108/live;
live on;
hls on;
hls_type live;
hls_path /tmp/hls;
hls_fragment 5000ms;
hls_max_fragment 8000ms;
hls_playlist_length 15000ms;
# live_record on;
# live_record_path /tmp/record;
# live_record_interval 2m;
# live_record_min_fragment 10s;
# live_record_max_fragment 30s;
hls2memory on;
mpegts_cache_time 20s;
hls2_fragment 1000ms;
hls2_max_fragment 1300ms;
hls2_playlist_length 3000ms;
wait_key on;
wait_video on;
cache_time 3s;
low_latency off;
fix_timestamp 0s;
# h265 codecid, default 12
hevc_codecid 12;
}
}
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_X-Forwarded-For" "$http_X-Real-IP" "$host"';
access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#reset_server_name www.test1.com www.test2.com;
#gzip on;
server {
listen 80;
location /ts {
ts_live 1935 app=live;
}
location /control {
rtmp_control all;
}
location /rtmp_stat {
rtmp_stat all;
rtmp_stat_stylesheet /stat.xsl;
}
location /xstat {
rtmp_stat all;
}
location /sys_stat {
sys_stat;
}
location /live {
flv_live 1935;
}
location /files {
alias /tmp/record;
#Nginx日志目录
autoindex on;
#打开目录浏览功能
autoindex_exact_size off;
#默认为on,显示出文件的确切大小,单位是bytes
#显示出文件的大概大小,单位是kB或者MB或者GB
autoindex_localtime on;
#默认为off,显示的文件时间为GMT时间。
#改为on后,显示的文件时间为文件的服务器时间
add_header Cache-Control no-store;
}
location /hls {
# Serve HLS fragments
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
root /tmp;
expires -1;
add_header Cache-Control no-cache;
}
location /hls2 {
hls2_live 1935 app=live;
}
location / {
chunked_transfer_encoding on;
root html/;
}
location /hls0/ {
types{
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
expires -1;
}
}
}
控制接口说明
接口名 | 请求 | 回复 | 描述 |
---|---|---|---|
暂停推流 | /${location}/pause/publisher?srv=${serverid}&app=${app}&name=${name} | 参考 http ack | 服务器停止转发收到的直播流 |
恢复推流 | /${location}/resume/publisher?srv=${serverid}&app=${app}&name=${name} | 参考 http ack | 服务器恢复转发收到的直播流 |
暂停录像 | /${location}/record/stop?srv=${serverid}&app=${app}&name=${name}&rec=${recorder} | 参考 http ack | 暂停某条流的录像 |
恢复录像 | /${location}/record/start?srv=${serverid}&app=${app}&name=${name}&rec=${recorder} | 参考 http ack | 恢复某条流的录像 |
JS控制台示例
为了更好地帮助大家理解上述接口的使用方法,我专门写了一个简单的js控制台,仅仅实现了暂停、播放、录像和停止录像的基本控制。
源码如下:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
</head>
<body>
<script>
function pause() {
var name=document.getElementById('value').value;
var ip=document.getElementById('ip').value;
var url = 'http://'+ ip + '/control/pause/publisher?srv=000&app=live&name='+name;
var request = new XMLHttpRequest();
request.open("Get", url, true);
request.send()
}
function resume() {
var name=document.getElementById('value').value;
var ip=document.getElementById('ip').value;
var url = 'http://' + ip + '/control/resume/publisher?srv=000&app=live&name='+name;
var request = new XMLHttpRequest();
request.open("Get", url, true);
request.send()
}
function pauseRecord(){
var name=document.getElementById('value').value;
var ip=document.getElementById('ip').value;
var url = 'http://' + ip + '/control/record/stop?srv=000&app=live&name='+name+'&rec=r1';
var request = new XMLHttpRequest();
request.open("Get", url, true);
request.send()
}
function resumeRecord(){
var name=document.getElementById('value').value;
var ip=document.getElementById('ip').value;
var url = 'http://'+ip+'/control/record/start?srv=000&app=live&name='+name+'&rec=r1';
var request = new XMLHttpRequest();
request.open("Get", url, true);
request.send()
}
function finalize(){
var name=document.getElementById('value').value;
var ip=document.getElementById('ip').value;
var url = 'http://'+ip+'/control/drop/publisher?srv=000&app=live&name='+name;
var request = new XMLHttpRequest();
request.open("Get", url, true);
request.send()
}
</script>
<span id="car_control" class="car">
server ip:
<input type="text" id="ip" placeholder=""/><br/>
stream name:
<input type="text" id="value" placeholder=""/><br/>
<button class="top" onclick="pause()">暂停直播</button>
<button class="left" onclick="resume()">继续直播</button>
<button class="right" onclick="pauseRecord()">暂停录像</button>
<button class="bottom" onclick="resumeRecord()">继续录像</button>
<button class="bottom" onclick="finalize()">结束直播</button>
</span>
</body>
</html>
录像文件查看接口
生成的录像文件会存在固定目录下,通过http接口(http://ip/files/)可以在浏览器中看到其文件列表。
获取流信息
通过接口(http://ip/xstat)可请求到所有在线流的信息,内容如下
<?xml version="1.0" encoding="utf-8" ?>
<rtmp>
<nginx_version>1.17.1</nginx_version>
<nginx_rtmp_version>1.1.4</nginx_rtmp_version>
<compiler>gcc 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC) </compiler>
<built>Oct 24 2019 16:26:06</built>
<pid>20853</pid>
<uptime>176258</uptime>
<naccepted>3</naccepted>
<bw_in>0</bw_in>
<bytes_in>171403</bytes_in>
<bw_out>0</bw_out>
<bytes_out>172549</bytes_out>
<server>
<serverid>000</serverid>
<live>
<stream>
<name>0</name>
<time>3225</time>
<bw_in>0</bw_in>
<bytes_in>168524</bytes_in>
<bw_out>0</bw_out>
<bytes_out>165725</bytes_out>
<bw_audio>0</bw_audio>
<bw_video>0</bw_video>
<client>
<id>455</id>
<address>0.0.0.0:1935</address>
<remote_address>127.0.0.1</remote_address>
<time>3056</time>
<flashver>LNX 9,0,124,2</flashver>
<dropped>0</dropped>
<avsync>0</avsync>
<timestamp>0</timestamp>
<active/>
</client>
<client>
<id>454</id>
<address>0.0.0.0:1935</address>
<remote_address>127.0.0.1</remote_address>
<time>3413</time>
<flashver>FMLE/3.0 (compatible; Lavf58.26.101)</flashver>
<dropped>0</dropped>
<avsync>11</avsync>
<timestamp>3219</timestamp>
<publishing/>
<active/>
</client>
<meta>
<video>
<width>1920</width>
<height>1080</height>
<frame_rate>24</frame_rate>
<codec>H264</codec>
<profile>High</profile>
<compat>0</compat>
<level>4.0</level>
</video>
<audio>
<codec>AAC</codec>
<profile>LC</profile>
<channels>6</channels>
<sample_rate>48000</sample_rate>
</audio>
</meta>
<nclients>2</nclients>
<publishing/>
<active/>
</stream>
<nclients>2</nclients>
</live>
</server>
</rtmp>
本项目支持的接口远不止此,更多控制接口请继续关注后续的文章或者进群交流。