nginx + rtmp 搭建流媒体服务器直播平台

一、安装与配置nginx服务器

安装nginx:

1,安装参考播客:https://blog.csdn.net/u012946310/article/details/81535751

2,安装完成后下载 nginx-rtmp-module 模块(我这里的目录是在/usr/local/nginx-1.15.0 下面)

cd /usr/local/nginx-1.15.0/

nginx-rtmp-module 的官方 github 下载地址:https://github.com/arut/nginx-rtmp-module
这里使用git进行下载:

git clone https://github.com/arut/nginx-rtmp-module.git 

( 如果没有安装git使用yun进行安装,yum install git)

3,重新编译 nginx,添加 nginx-rtmp-module 模块

./configure --prefix=/usr/local/nginx  --add-module=nginx-rtmp-module  --with-http_ssl_module
make
make install

4,nginx 与 nginx-rtmp-module 模块安装完成,修改 nginx.conf 配置文件

#在最外层增加如下配置
rtmp {
    server {
        listen 1935; #监听的端口
        chunk_size 4000;

        #rtmp配置
        application live{ #rtmp推流请求路径 (切记路径错了会推不上流)
            live on; #开启实时
            hls on; #开启hls
            hls_path /www/rtmp; #rtmp推流请求路径,文件存放路径
            hls_fragment 5s; #每个TS文件包含5秒的视频内容

            #开始推流回调,url地址为java接口
            on_publish http://192.168.2.101:6540/rtmp/uploadRtmp;
            #推流停止回调,url地址为java接口
            on_done http://192.168.2.101:6540/rtmp/uploadRtmp;
        }
    }
}

nginx + rtmp 搭建流媒体服务器直播平台_第1张图片
至此,nginx 及 nginx-rtmp-module 部分配置完成 。

二、OBS推流测试

1,百度OBS下载及安装

2,添加来源,选择媒体源,选择本地的播放文件
nginx + rtmp 搭建流媒体服务器直播平台_第2张图片
nginx + rtmp 搭建流媒体服务器直播平台_第3张图片
3,添加来源后点击控件设置,配置OBS推流地址:
nginx + rtmp 搭建流媒体服务器直播平台_第4张图片

rtmp://192.168.2.122:1935/live // nginx的ip和application地址也就是推流地址
rtmp?token=123456 // 流名称,可以作为会话名称并且可以传递参数验证权限

单击开始推流,验证,查看服务器目录已经存在有流文件**(上面nginx配置的 hls_path 地址)**,并且在开始推流之前回调了所配置的java接口代码
nginx + rtmp 搭建流媒体服务器直播平台_第5张图片

以下为回调的java controller代码:

package cx.manager.client.demo.controller;

import cx.manager.common.vo.ResultPageVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

@Controller
@RequestMapping("rtmp")
@Slf4j
public class RtmpController {

    @RequestMapping("/uploadRtmp")
    @ResponseBody
    public ResultPageVo uploadRemp(String token, HttpServletRequest request, HttpServletResponse response) {
        Map parameterMap = request.getParameterMap();
        System.out.println("参数数量:" + parameterMap.size());
        /**这三个参数是比较有用的参数
         tcurl:rtmp地址
         name:"rtmp://ngnix服务器地址/live/id"地址中去除推流地址的最后一个参数,可传入直播用户ID
         type:推流类型
         */
        System.out.println("tcurl:" + request.getParameter("tcurl"));
        System.out.println("name:" + request.getParameter("name"));
        System.out.println("type:" + request.getParameter("type"));
        //打印所有回调传过来的参数
        for (Map.Entry entry : parameterMap.entrySet()) {
            System.out.println(entry.getKey() + "====================");
            for (String str : entry.getValue()) {
                System.out.println("\t" + str);
            }
        }
        return ResultPageVo.success();
//        try {
//            if (token.equals("123456")) {
//                return ResultPageVo.success();
//            } else {
//                response.setStatus(500);
//                return ResultPageVo.failure("token无效");
//            }
//        } catch (Exception e) {
//            response.setStatus(500);
//            return ResultPageVo.failure("token无效");
//        }
    }

    @GetMapping("/video")
    public String video(ModelMap modelMap) {

        modelMap.put("videoUrl", "rtmp://rtmp.test.orancrab.com:1935/live/rtmp");

        return "video";
    }
}

ResultPageVo 代码:

@ApiModel(value = "ResultPageVo", description = "页面通用响应VO")
public class ResultPageVo implements Serializable {

    private static final long serialVersionUID = 1L;

    @ApiModelProperty(value = "响应码 1:成功 0:失败,其他根据实际情况自定义在ResultCode中,同时每个接口的特殊返回码需要注释。", dataType = "int", required = true)
    private Integer status;

    @ApiModelProperty(value = "消息提示", dataType = "string")
    private String message = "";

    @ApiModelProperty(value = "响应数据", dataType = "object")
    private T data;

    @ApiModelProperty(value = "响应数据", dataType = "object")
    private Object spareData;

    private ResultPageVo(Integer status) {
        this.status = status;
    }

    private ResultPageVo(Integer status, String message) {
        this.status = status;
        this.message = message;
    }

    private ResultPageVo(Integer status, T data) {
        this.status = status;
        this.data = data;
    }

    private ResultPageVo(Integer status, String message, T data) {
        this.status = status;
        this.message = message;
        this.data = data;
    }

    public static ResultPageVo success() {
        return new ResultPageVo(ResultCode.SUCCESS.status(), ResultCode.SUCCESS.message());
    }

    public static  ResultPageVo success(T data) {
        return new ResultPageVo(ResultCode.SUCCESS.status(), ResultCode.SUCCESS.message(), data);
    }

    public static  ResultPageVo success(String message, T data) {
        return new ResultPageVo(ResultCode.SUCCESS.status(), message, data);
    }

    public static ResultPageVo failure() {
        return new ResultPageVo(ResultCode.FAILURE.status(), ResultCode.FAILURE.message());
    }

    public static ResultPageVo failure(String message) {
        return new ResultPageVo(ResultCode.FAILURE.status(), message);
    }

    public static  ResultPageVo failure(T data) {
        return new ResultPageVo(ResultCode.FAILURE.status(), ResultCode.FAILURE.message(), data);
    }

    public static  ResultPageVo failure(String message, T data) {
        return new ResultPageVo(ResultCode.FAILURE.status(), message, data);
    }

    public static ResultPageVo create(ResultCode resultCode) {
        return new ResultPageVo(resultCode.status(), resultCode.message());
    }

    public static  ResultPageVo create(ResultCode resultCode, T data) {
        return new ResultPageVo(resultCode.status(), resultCode.message(), data);
    }

    public static ResultPageVo create(Integer status) {
        return new ResultPageVo(status);
    }

    public static ResultPageVo create(Integer status, String message) {
        return new ResultPageVo(status, message);
    }

    public static  ResultPageVo create(Integer status, T data) {
        return new ResultPageVo(status, data);
    }

    public static  ResultPageVo create(Integer status, String message, T data) {
        return new ResultPageVo(status, message, data);
    }

    public Integer getStatus() {
        return status;
    }

    public String getMessage() {
        return message;
    }

    public T getData() {
        return data;
    }

    public Object getSpareData() {
        return spareData;
    }

    public void setSpareData(Object spareData) {
        this.spareData = spareData;
    }

    @Override
    public String toString() {
        return "ResultPageVo{" +
                "status=" + status +
                ", message='" + message + '\'' +
                ", data=" + data +
                ", spareData=" + spareData +
                '}';
    }
}

ResultCode 代码:

public enum ResultCode {

    //带消息的响应码
    SUCCESS(1, "成功"),
    FAILURE(0, "失败"),//其他失败,全部走这里  请注意
    TOKEN_ERROR(10, "token验证失败"),
    PERMISSION_ERROR(11, "权限不足");

    private Integer status;

    private String message;

    ResultCode(Integer status) {
        this.status = status;
    }

    ResultCode(Integer status, String message) {
        this.status = status;
        this.message = message;
    }

    public Integer status() {
        return status;
    }

    public String message() {
        return message;
    }

}

只做了个简单测试,可根据这些参数完善后台,实现用户推流开始把用户ID和推流地址存入redis或其他高性能存储,前台展示当前直播的用户,点击用户返回推流地址,实现直播,用spring boot写的

三、http拉流播放

拉流地址:rtmp://192.168.2.122:1935/live/rtmp

1,百度VLC下载及安装

2,安装好之后选择媒体 -> 流,选择网络,输入流地址后开始拉流

nginx + rtmp 搭建流媒体服务器直播平台_第6张图片
输入后点击串流直接下一步到完成就好了
nginx + rtmp 搭建流媒体服务器直播平台_第7张图片
最后看到已经拉取到流了

3,使用网络播放器进行验证

(网络拉流播放器地址:http://www.cutv.com/demo/live_test.swf)
RTMP拉流地址:rtmp://192.168.2.122:1935/live/rtmp(和VLC拉流地址一样)

验证通过,已经可以拉到流了。。。。。。。

4,使用移动端app设置推流与h5拉流测试

安卓推流App下载地址(小米9可用,其他机型没试,IOS自己在网上找):https://download.csdn.net/download/u012946310/11170486

下载好后打开APP点击左上角 -> Profile 里面编辑推流地址和其他参数,推流地址就是之前的推流地址
nginx + rtmp 搭建流媒体服务器直播平台_第8张图片
4-1,h5播放页面代码(页面需要放在服务容器里面运行,如nginx、tomcat等,电脑需要安装flash,手机端不支持),拉流地址改成自己的流地址就可以了

  
    
  视频直播  
    
    
    
    
  
  
  

直播间

本地测试

推流命令:/usr/local/ffmpeg/bin/ffmpeg -re -i rtmp.mp4 -f flv rtmp://192.168.2.122:1935/live/rtmp?token=123456

拉流地址:rtmp://192.168.2.122:1935/live/rtmp?token=123456

远程测试

推流地址:

播放地址:http://cx.manager.test.orancrab.com/client_demo/rtmp/video

4-2,搭建完成,运行页面测试
nginx + rtmp 搭建流媒体服务器直播平台_第9张图片

五、结尾

到此一个简单的 nginx + rtmp 搭建流媒体服务器,完成!虽然不是一个完整的例子,但是核心就是以上这些,大家可以在次基础上扩展,有什么不妥的地方希望大家指正,共同学习

你可能感兴趣的:(nginx)