Nginx-rtmp实现直播媒体实时流效果实现直播媒体实时流效果
主要介绍了Nginx-rtmp实现直播媒体实时流效果,文中给出了总体设计图,为了整合平台,会自建RTMP流媒体服务器和使用云厂商SaaS的RTMP流媒体服务,需要的朋友可以参考
下
0. 前言前言
这段时间在搭建一个IPCamera项目服务器。视频点对点通话,客户端会查看设备端的音视频实时流。为了省流量,是通过P2P进行穿透。但是由于NAT设备的原因和IPV4的枯竭。有些设备是无法进
行点对点传输实时流。所以需要进行服务器转发。这里为了快速实现原型,同时参考现在主流的流媒体协议。发现很多使用的是RTMP协议。
下图是总体设计图,为了整合多平台,会自建RTMP流媒体服务器和使用云厂商SaaS的RTMP流媒体服务。但是由于有时候会传输一些非流媒体数据,需要传输一些二进制文件,所以会需要自定义
媒体转发服务。
以下是我实际项目中,用到的架构实现流程图。
1. 客户端A无法进行P2P穿透,请求业务服务器要进行转发。
2. 业务服务器根据客户端A,请求类型,返回对应的转发服务器地址和对应的房间号RoomID/Token等信息
3. 上述请求类型,可以是请求自建RTMP流媒体服务,购买于云厂商RTMP流媒体服务或者自定义协议媒体转发服务
4. 客户端A得到业务服务器返回的媒体服务器地址和RoomID/Token
5. 通过信令服务器或者MQTT服务器,把对应的媒体服务器地址和RoomID/Token告诉另一端客户端B
6. 客户端A和客户端B同时进入相同房间Room,客户端A进行推流,客户端B进行拉流
7. 其他媒体信息,如编解码格式,清晰度,播放,暂停,拍照等命令,通过上述信令或MQTT服务器进行命令控制
1. 编译编译Nginx
RTMP流媒体服务器,现成的开源方案有很多,有SRS,Red5,wowoza,FMS等,我这里使用的是Nginx的rtmp插件实现实时流转发。
下载 nginx-rtmp-module https://github.com/arut/nginx-rtmp-module
重新编译nginx
--prefix=/opt/nginx --with-stream --with-http_ssl_module --with-stream_ssl_module --with-debug --add-module=../nginx-rtmp-module
2. 配置配置Nginx.conf
基本的nginx配置,这里就不进行介绍了,需要了解的可以参考我其他博客,里面有介绍。这里只介绍rtmp段的定义。
rtmp{
server{
listen 8081;
access_log logs/rtmp_access.log;
on_connect http://127.0.0.1:8080/v1/rtmp/on_connect;
application rtmp {
live on;
notify_method get;
on_play http://127.0.0.1:8080/v1/rtmp/on_play;
on_publish http://127.0.0.1:8080/v1/rtmp/on_publish;
on_done http://127.0.0.1:8080/v1/rtmp/on_done;
on_play_done http://127.0.0.1:8080/v1/rtmp/on_play_done;
on_publish_done http://127.0.0.1:8080/v1/rtmp/on_publish_done;
on_record_done http://127.0.0.1:8080/v1/rtmp/on_record_done;
on_update http://127.0.0.1:8080/v1/rtmp/on_update;
notify_update_timeout 10s;
}
application vod {
play /opt/openresty/video;
}
}
}
3. HTTP异步通知回调异步通知回调
Nginx-rtmp-module插件实现了针对RTMP协议的一些命令做了事件通知。这里我通过一个简单的SpringBoot项目,快速搭建一个HTTP服务来接收RTMP的回调。
package com.wunaozai.rtmp.notify.controller;
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping(value="/v1/rtmp/")
public class RTMPNotifyController {
@GetMapping(value="/on_connect")
public String onConnect(HttpServletRequest request){
debug(request, "on_connect");
return "on_connect";
}
@GetMapping(value="/on_play")
public String onPlay(HttpServletRequest request){
debug(request, "on_play");
return "on_play";
}
@GetMapping(value="/on_publish")
public String onPublish(HttpServletRequest request){
debug(request, "on_publish");
return "on_publish";
}
@GetMapping(value="/on_done")
public String onDone(HttpServletRequest request){
debug(request, "on_done");
return "on_done";
}
@GetMapping(value="/on_play_done")
public String onPlayDone(HttpServletRequest request){
debug(request, "on_play_done");
return "on_play_done";
}
@GetMapping(value="/on_publish_done")
public String onPublishDone(HttpServletRequest request){
debug(request, "on_publish_done");
return "on_publish_done";
}
@GetMapping(value="/on_record_done")
public String onRecordDone(HttpServletRequest request){
debug(request, "on_record_done");
return "on_record_done";
}
@GetMapping(value="/on_update")
public String onUpdate(HttpServletRequest request){
debug(request, "on_update");
return "on_update";
}
private String debug(HttpServletRequest request, String action){
String str = action + ": " + request.getRequestURI() + " " + request.getQueryString();
System.out.println(str);
return str;
}
}
4. 运行效果运行效果
(1) 启动nginx和SpringBoot