1.1ffmpeg:核心文件,用于负责转换视频流;
1.2Nginx:代理服务器,用于将转换后的视频流转发到其他地址。
1.3vlc播放器:播放器/转换器,用于在测试时将mp4视频文件转换成rtsp流。
1.4Video相关CSS、JS:用于在浏览器端播放。
二、相关文件下载2.1ffmpeg下载:
ffmpeg地址:Download FFmpeg
2.1.1Linux系统
2.1.2Windows系统
2.1.3MAC系统(略)
2.2Nginx
rtmp转换流使用到的Nginx与之前的Nginx是有区别,下载地址:GitHub - illuspas/nginx-rtmp-win32: Nginx-rtmp-module Windows builds.或者使用自己的nginx-1.8.1(推荐)。
注意Nginx所在目录不要有中文!
2.3vlc播放器
2.4Video相关CSS、JS
三、配置3.1ffmpeg:无改变,解压后存放的目录不要有中文!
3.2rtmp使用到的Nginx:
可能集成了 Rtmp、openssl、pcre、zlib,具体还没看,主要是拿来使用。
nginx.conf里的配置:
worker_processes 1;
error_log logs/error.log debug;
events {
worker_connections 1024;
}
rtmp {
server {
listen 1935;
application live {
live on;
}
application hls {
live on;
hls on;
hls_path temp/hls;
hls_fragment 8s;
}
}
}
3.3vlc播放器:
3.4Video相关CSS、JS:
参考2.4Video相关CSS、JS的链接里的代码,里面的视频地址是rtmp流。
四:使用【CMD命令行】4.1开启Nginx服务;
4.2使用VLC转换MP4视频为rtsp流;
4.3在CMD命令窗口执行,使用ffmpeg.exe将rtsp视频转为rtmp流:
ffmpeg -i rtsp://192.168.1.121:8554/test -vcodec copy -acodec copy -f flv rtmp://127.0.0.1:1935/live/play1
注意:
1、rtsp://192.168.1.121:8554/test
这是VLC播放器转换后的rtsp流地址。
2、rtmp://127.0.0.1:1935/live/play1
①端口要与Nginx的监听的rtmp端口一致。
②端口后面的live是必须要与Nginx里监听的一致,如下图:
③live后面的地址任意,每一个地址代表一个rmtp流,即一个视频。
五:使用【Java核心代码】5.1启动Nginx、停止Nginx
/**
* 启动Nginx、停止Nginx
*/
public static void startNginx(){
if(!StringUtils.isEmpty(Nginx)){
return;
}
//启动nginx
String nginxStart = "cmd /c cd E:\\Others\\VideoConvertTest\\nginx-1.8.1 && start nginx";
//关闭nginx
String nginxStop ="cmd /c cd E:\\Others\\VideoConvertTest\\nginx-1.8.1 && nginx.exe -s stop";
Runtime run = Runtime.getRuntime();
Nginx = "startNginx";
try {
Process stop = run.exec(nginxStop);
Process start = run.exec(nginxStart);
} catch (IOException e) {
e.printStackTrace();
}
}
5.2rtsp转为rtmp
/**
* rtsp转为rtmp
* @param videoPort
* @param videoName
* @return
*/
public static void convert(String videoPort,String videoName){
String videoId = videoPort + videoName;
if(rtspList.contains(videoId)){
return;
}
rtspList.add(videoId);
// String convertVideo = "cmd /c start E:\\Others\\VideoConvertTest\\ffmpeg\\bin\\ffmpeg.exe -i \"rtsp://192.168.1.121:" + videoPort + "/test\" -vcodec copy -acodec copy -f flv \"rtmp://127.0.0.1:1935/live/" + videoName + "\"";
String convertVideo = "cmd /c start E:\\Others\\VideoConvertTest\\ffmpeg2020\\bin\\ffmpeg.exe -i \"rtsp://192.168.1.121:" + videoPort + "/test\" -vcodec copy -acodec copy -f flv \"rtmp://127.0.0.1:1935/live/" + videoName + "\"";
String line = null;
StringBuilder sb = new StringBuilder();
Runtime runtime = Runtime.getRuntime();
try {
Process process = runtime.exec(convertVideo);
// BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
// while((line = bufferedReader.readLine()) != null) {
// sb.append(line + "\n");
// System.out.println("line------" + line);
// process.destroy();
// }
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
5.3完整代码
package video.player.utils;
import org.thymeleaf.util.StringUtils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
public class RtspToRtmpUtil {
/**
* 记录Nginx是否已启动
*/
public static String Nginx = "";
/**
* 记录rtsp流是否已启动转换
*/
public static List<String> rtspList = new ArrayList<>();
/**
* 启动Nginx、停止Nginx
*/
public static void startNginx(){
if(!StringUtils.isEmpty(Nginx)){
return;
}
//启动nginx
String nginxStart = "cmd /c cd E:\\Others\\VideoConvertTest\\nginx-1.8.1 && start nginx";
//关闭nginx
String nginxStop ="cmd /c cd E:\\Others\\VideoConvertTest\\nginx-1.8.1 && nginx.exe -s stop";
Runtime run = Runtime.getRuntime();
Nginx = "startNginx";
try {
Process stop = run.exec(nginxStop);
Process start = run.exec(nginxStart);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* rtsp转为rtmp
* @param videoPort
* @param videoName
* @return
*/
public static void convert(String videoPort,String videoName){
String videoId = videoPort + videoName;
if(rtspList.contains(videoId)){
return;
}
rtspList.add(videoId);
// String convertVideo = "cmd /c start E:\\Others\\VideoConvertTest\\ffmpeg\\bin\\ffmpeg.exe -i \"rtsp://192.168.1.121:" + videoPort + "/test\" -vcodec copy -acodec copy -f flv \"rtmp://127.0.0.1:1935/live/" + videoName + "\"";
String convertVideo = "cmd /c start E:\\Others\\VideoConvertTest\\ffmpeg2020\\bin\\ffmpeg.exe -i \"rtsp://192.168.1.121:" + videoPort + "/test\" -vcodec copy -acodec copy -f flv \"rtmp://127.0.0.1:1935/live/" + videoName + "\"";
String line = null;
StringBuilder sb = new StringBuilder();
Runtime runtime = Runtime.getRuntime();
try {
Process process = runtime.exec(convertVideo);
// BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
// while((line = bufferedReader.readLine()) != null) {
// sb.append(line + "\n");
// System.out.println("line------" + line);
// process.destroy();
// }
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
5.4 需要异步开启转换,所以要用到多线程
@GetMapping("/convert")
@ResponseBody
public String convert(@RequestParam(value = "videoPort") String videoPort, @RequestParam(value = "videoName") String videoName){
//启动新的线程
new Thread() {
public void run() {
RtspToRtmpUtil.startNginx();
RtspToRtmpUtil.convert(videoPort, videoName);
}
}.start();
return "rtmp://127.0.0.1:1935/live/" + videoName + "/";
}
完整代码:
package video.player.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import video.player.utils.RtspToRtmpUtil;
@Controller
public class VideoPlayerController {
@GetMapping("/player")
public String player(){
return "video/player.html";
}
@GetMapping("/rtmp")
public String rtmp(){
return "video/rtmp.html";
}
@GetMapping("/rtmp2")
public String rtmp2(){
return "video/rtmp2.html";
}
@GetMapping("/convert")
@ResponseBody
public String convert(@RequestParam(value = "videoPort") String videoPort, @RequestParam(value = "videoName") String videoName){
//启动新的线程
new Thread() {
public void run() {
RtspToRtmpUtil.startNginx();
RtspToRtmpUtil.convert(videoPort, videoName);
}
}.start();
return "rtmp://127.0.0.1:1935/live/" + videoName + "/";
}
}
六、其他
6.1其他参考地址
6.2完整代码及工具包地址:https://gitee.com/XiMuQi/RtspToRtmp