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、解压并放置在某个盘符的根目录下
2、配置环境变量
(1)找到bin目录所在文件夹
拷贝该地址:D:\ffmpeg\ffmpeg\bin
(2)配置环境变量
配置好之后确认
(3)检查是否安装完成
win+r输入cmd:ffmpeg -version
出现如下字样即可
二、安装Nginx
1、解压压缩包并放置在某盘符下
2、修改nginx.conf文件
注释:
rtmp监听端口:即为rtmp流输出地址端口;
http监听端口:即为http-flv流输出地址端口;
http配置开启:flv_live on;
3、启动Nginx
双击启动,查看进程中是否存在该进程,如果存在,则启动成功
三、测试
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流
四、前端流媒体处理及分析
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、文件配置
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;
}
}