ffmpeg实现rtsp转rtmp/http-flv

  • 一、安装FFmpeg
  • 1、解压并放置在某个盘符的根目录下
  • 2、配置环境变量
  • (1)找到bin目录所在文件夹
  • (2)配置环境变量
  • (3)检查是否安装完成
  • 二、安装Nginx
  • 1、解压压缩包并放置在某盘符下
  • 2、修改nginx.conf文件
  • 3、启动Nginx
  • 三、测试
  • 1、直播流CMD测试(如本地环境无直播流,直接看4,回放流)
  • (1)低画质、低延迟
  • a.输出rtmp地址:
  • b.输出http_flv地址
  • (2)高画质、高延迟
  • a.输出rtmp地址:
  • b.输出http_flv地址
  • 2、回放流测试
  • (1)回放流rtsp可用地址
  • (2)cmd测试
  • a.输出rtmp地址:
  • b.输出http_flv地址
  • 3、vlc或者网页测试播放rtmp流或http流
  • 四、前端流媒体处理及分析
  • 1、rtmp处理方式及代码
  • a.引入插件
  • b.代码实现
  • 2、http-flv处理方式及代码
  • a.引入插件
  • b.代码实现
  • c.补充说明
  • 3、异同分析
  • a.相同点
  • b.差异
  • 五、后端处理部分
  • 1、文件配置
  • 2、代码块


一、安装FFmpeg

1、解压并放置在某个盘符的根目录下

Python ffmpeg RTSP 转播 ffmpeg 转rtsp流_json

2、配置环境变量

(1)找到bin目录所在文件夹

Python ffmpeg RTSP 转播 ffmpeg 转rtsp流_java_02


拷贝该地址:D:\ffmpeg\ffmpeg\bin

(2)配置环境变量

Python ffmpeg RTSP 转播 ffmpeg 转rtsp流_java_03


Python ffmpeg RTSP 转播 ffmpeg 转rtsp流_ffmpeg_04


Python ffmpeg RTSP 转播 ffmpeg 转rtsp流_ide_05

Python ffmpeg RTSP 转播 ffmpeg 转rtsp流_ffmpeg_06

配置好之后确认

(3)检查是否安装完成

win+r输入cmd:ffmpeg -version

出现如下字样即可

Python ffmpeg RTSP 转播 ffmpeg 转rtsp流_json_07

二、安装Nginx

1、解压压缩包并放置在某盘符下

Python ffmpeg RTSP 转播 ffmpeg 转rtsp流_java_08

2、修改nginx.conf文件

Python ffmpeg RTSP 转播 ffmpeg 转rtsp流_开发语言_09

注释:
rtmp监听端口:即为rtmp流输出地址端口;
http监听端口:即为http-flv流输出地址端口;
http配置开启:flv_live on;

3、启动Nginx

Python ffmpeg RTSP 转播 ffmpeg 转rtsp流_ide_10

双击启动,查看进程中是否存在该进程,如果存在,则启动成功

三、测试

1、直播流CMD测试(如本地环境无直播流,直接看4,回放流)

(1)低画质、低延迟

ffmpeg -i "rtsp流地址" -vcodec copy -acodec copy -f flv  "rtmp://127.0.0.1:1935/live/100"
a.输出rtmp地址:
rtmp://127.0.0.1:1935/live/100
b.输出http_flv地址
http://127.0.0.1:8086/live?port=1935&app=live&stream=100

(2)高画质、高延迟

ffmpeg -re  -rtsp_transport tcp -i "rtsp流地址" -f flv -vcodec libx264 -vprofile
 baseline -acodec aac -ar 44100 -strict -2 -ac 1 -f flv -s 1280x720 -q 
 10 "rtmp://127.0.0.1:1935/live/test(输出rtmp地址)"
a.输出rtmp地址:
rtmp://127.0.0.1:1935/live/test
b.输出http_flv地址
http://127.0.0.1:8086/live?port=1935&app=live&stream=test

2、回放流测试

(1)回放流rtsp可用地址

rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov

(2)cmd测试

ffmpeg -re -rtsp_transport tcp -i "rtsp流地址" -f flv -r 25 -s 1280x720 -an "rtmp://127.0.0.1:1935/live/100"
a.输出rtmp地址:
rtmp://127.0.0.1:1935/live/100
b.输出http_flv地址
http://127.0.0.1:8086/live?port=1935&app=live&stream=100

3、vlc或者网页测试播放rtmp流或http流

Python ffmpeg RTSP 转播 ffmpeg 转rtsp流_ffmpeg_11

四、前端流媒体处理及分析

1、rtmp处理方式及代码

a.引入插件

<script src="$!{main_static_ckplayer_url}/ckplayer.js" charset="UTF-8"></script>

b.代码实现

构造容器

<div id=’divId’ class='video-js'></div>

配置插件的属性

var videoObject = {
container: `#${divId}`(`.${video-js}`), //容器的ID或className
variable: 'player',//播放函数名称
autoplay:true,//自动播放
definition:false,
loop:true,//循环播放
video:src//通过接口获取的rtmp流
};

执行播放函数

let player = new ckplayer(videoObject);

销毁视频的方法

let  player = new ckplayer(treeNodeId);//利用容器id获取视频对象
player.videoClear() //销毁视频控件方法

rtmp为tcp协议,需要flash支持,在不支持flash插件的浏览器上无法利用插件播放视频

2、http-flv处理方式及代码

a.引入插件

<script src="$!{main_static_base_url}/plug/video/flv/flv.js"></script>

b.代码实现

构造容器
因为支持http协议所以可以直接使用h5的标签作为容器

<video controls="controls" muted id='flvPlayer'></video>
let videoElement = document.getElementById('flvPlayer');根据容器id获取元素

配置插件的属性

let flvPlayer = flvjs.createPlayer({
type: 'flv',
isLive: true,//是否直播
hasAudio: false,//是否有音频
hasVideo: true,//是否有视频
enableStashBuffer: true,//是否启用IO隐藏缓冲区
url: src//接口获取的httpflv格式流
});

执行播放函数

flvPlayer.attachMediaElement(videoElement);
flvPlayer.load();
flvPlayer.play();

销毁视频的方法
通过接口传来process字段,在关闭容器时用接口销毁视频

c.补充说明

httpflv为http协议,不需要flash插件支持,原理为将音视频数据封装成FLV格式,然后通过 HTTP 协议传输给客户端,通过flv.js可以脱离flash插件,在H5上使用此插件对http-flv流进行播放

3、异同分析

a.相同点

1.均需要利用插件
2.不便于拖动进度条
3.需要对应id匹配容器

b.差异

1.http-flv为http协议,通过flv.js使其脱离flashplayer插件,利用h5对视频流进行播放,rtmp则需要在flashplayer的支持下对流进行播放
2.http-flv不支持多音频流,多视频流,有时候因为音频的原因会导致流无法播放,rtmp不会
3.flv.js可使用h5的标签作为容器播放视频流,rtmp使用


标签作为容器,无法使用标签


五、后端处理部分

1、文件配置

Python ffmpeg RTSP 转播 ffmpeg 转rtsp流_ide_12

2、代码块

/**
 * <ul>
 * <li>文件名称:RtspToRtmpUtils</li>
 * <li>文件描述:</li>
 * <li>版权所有: 版权所有(C) 2020</li>
 * <li>内容摘要:</li>
 * <li>其他说明:</li>
 * <li>创建日期: 2021-05-17</li>
 * <li>@author: 技术中心</li>
 * <li>版本号: 1.0.0</li>
 * </ul>
 **/
public class RtspToRtmpUtils {

    public static FFmpegManager manager = new FFmpegManagerImpl();

    /**
    * @功能描述: FFmpeg转流
    * @param: [rtsp]
    * @return: com.alibaba.fastjson.JSONObject
    * @author: 技术中心
    * @date: 2021/12/06 16:00
    **/
    public JSONObject getRtmp(String rtsp) throws InterruptedException {
        JSONObject jsonObject=new JSONObject();
        /**随机数*/
        int max=1000,min=1;
        /**ip*/
        String ip="192.168.106.13";
        int num = (int) (Math.random()*(max-min)+min);
        /**转流开始*/
        String start = manager.start("process" + num, "ffmpeg -i " + rtsp + " -vcodec copy -acodec copy -f flv \"rtmp://"+ip+":1935/live/" + num + "\"");
        /**输出rtmp流*/
        jsonObject.put("url","rtmp://"+ip+":1935/live/"+num);
        /**输出http-flv流*/
        jsonObject.put("httpurl","http://"+ip+":8086/live?port=1935&app=live&stream="+num);
        /**用于关闭流使用*/
        jsonObject.put("process",start);
        return jsonObject;
    }


    /**
    * @功能描述: 停止转流的进程
    * @param: [process]
    * @return: boolean
    * @author: 技术中心
    * @date: 2021/12/06 16:02
    **/
    public boolean stopProcess(String process){
        boolean stop = manager.stop(process);
        return stop;
    }

    /**
    * @功能描述: 关闭页面时停止所有视频
    * @param: []
    * @return: int
    * @author: 技术中心
    * @date: 2021/12/08 14:07
    **/
    public int stopAllProcess(){
        int i = manager.stopAll();
        return i;
    }
  
}