本文主要详细介绍在windows系统下,采用java语言来实现rtmp流媒体协议的视频的推流拉流。利用screen capturer recorder录屏工具结合ffmpeg.exe文件捕获桌面视频流并推到nginx服务器,随后使用浏览器进行视频流的拉取并播放。文末给出相关工具的下载链接。
一、环境准备
首先我们要准备好nginx的环境并安装好录屏工具
1、nginx服务搭建
解压nginx压缩包到D盘,可以看到如下目录
其中nginx-rtmp-modult就是该nginx版本自带的rtmp服务模块了,我们在conf目录下新建nginx.conf
的配置文件,文件内容如下:
worker_processes 1;
events {
worker_connections 1024;
}
#RTMP服务
rtmp {
server {
listen 1935;
chunk_size 4096;
application live {
live on; #开启直播
hls on; #开启hls直播。这个参数把直播服务器改造成实时回放服务器
hls_path ./html/hls; #切片视频文件存放位置(HLS,m3u8文件存放位置)
record off;
}
}
}
#HTTP服务
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
location /live{
#指向访问文件目录
add_header Access-Control-Allow-Origin *; # 解决资源访问的跨域问题
alias ./html/hls/; # 最后一定要加上/
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
随后在html目录下新建hls文件夹
将start.bat
内容修改为start nginx.exe
双击启动start.bat
文件来开启nginx服务,打开浏览器输入localhost
,看到如下页面即可
2、录屏软件安装
双击打开screen capturer recorder安装工具,傻瓜式安装,会看到D盘下有Screen Capturer Recorder文件夹,其中ffmpeg相关文件在如下路径中
vlc视频工具同样也是傻瓜式安装即可。
二、java代码调用ffmpeg工具实现录屏推流
public class JavaFFMpeg extends Thread{
private String ffmpegCmd = "";
private int flag = 1;
public String getFfmpegCmd(){
return this.ffmpegCmd;
}
public void setFfmpegCmd(String ffmpegCmd){
this.ffmpegCmd = ffmpegCmd;
}
public void run(){
openFFmpegExe();
System.out.println("执行完成准备退出");
}
// taskkill /F /T /IM "ffmpeg.exe"
private void openFFmpegExe() {
if(ffmpegCmd==null||ffmpegCmd.equals("")){
return;
}
Runtime rn = Runtime.getRuntime();
Process p = null;
try{
//传递ffmpeg推流命令行
p = rn.exec(ffmpegCmd);
Field field = p.getClass().getDeclaredField("handle");
field.setAccessible(true);
Long aLong = (Long) field.get(p);
System.out.println("aLong " + aLong);
RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
String name = runtime.getName(); // format: "pid@hostname"
Integer pid = Integer.parseInt(name.substring(0, name.indexOf('@')));
System.out.println(name+pid);
//ffmpeg输出的都是“错误流”,stdin,stdout,stderm
BufferedInputStream in = new BufferedInputStream(p.getErrorStream());
BufferedReader inBr = new BufferedReader(new InputStreamReader(in));
String lineStr;
System.out.println("开始...");
while ((lineStr=inBr.readLine())!= null && flag ==1){
System.out.println(lineStr);
}
System.out.println("flag"+flag);
inBr.close();
in.close();
String s = executeCmd("taskkill /F /T /IM \"ffmpeg.exe\"");
System.out.println(s);
}catch (Exception e){
System.out.println("异常:"+e.getMessage());
}
}
private static String executeCmd(String command) throws Exception{
Process process = Runtime.getRuntime().exec(command);
process.waitFor();//等待子进程完成再往下执行。
//创建bufferedReader
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream(),"GBK"));
String line = null;
StringBuilder build = new StringBuilder();
while ((line = bufferedReader.readLine()) != null) {
line = new String(line.getBytes("UTF-8"));
build.append(line);
}
bufferedReader.close();
int i = process.exitValue(); //接收执行完毕的返回值
if (i != 0) {
System.out.println("log info :cmd执行失败");
throw new RuntimeException("cmd执行失败");
}
process.destroy(); //销毁子进程
return build.toString();
}
public static void main(String[] args) throws Exception{
System.out.println("-------开始推流--------");
JavaFFMpeg javaFFMpeg = new JavaFFMpeg();
// String ffmpegCmd = "D:\\Screen Capturer Recorder\\configuration_setup_utility\\vendor\\ffmpeg\\bin\\ffmpeg -re -i D:\\BaiduNetdiskDownload\\test.mp4 -c copy -f flv rtmp://127.0.0.1:1935/live/test";
String ffmpegCmd = "D:\\Screen Capturer Recorder\\configuration_setup_utility\\vendor\\ffmpeg\\bin\\ffmpeg -f dshow -i video=\"screen-capture-recorder\" -f dshow -i audio=\"virtual-audio-capturer\" -ac 2 -b:a 128k -strict -2 -vcodec libx264 -preset:v ultrafast -pix_fmt yuv420p -acodec aac -f flv rtmp://127.0.0.1:1935/live/test";
// ffmpeg -f gdigrab -t 30 -framerate 15 -i desktop -f dshow -i audio="virtual-audio-capturer" -f flv rtmp://127.0.0.1/live/tes
javaFFMpeg.setFfmpegCmd(ffmpegCmd);
javaFFMpeg.start();
// javaFFMpeg.join();
javaFFMpeg.flag = System.in.read();
System.out.println("--------推流结束--------");
}
}
注意修改自己ffmpeg工具的目录
其中flag
是为了在视频推流过程中可以输入其他字符来中断我们的视频推流过程
String s = executeCmd("taskkill /F /T /IM \"ffmpeg.exe\"");
这是为了结束ffmpeg进程,否则关闭java程序,推流仍然进行
直接运行main方法可以看到如下日志记录
在html下的hls目录中可以看到如下文件
此时打开vlc视频播放工具,选择“媒体”,”打开网络串流“,输入rtmp://localhost/live/test
,点击播放
此时可以看到桌面录屏视频
3、使用网页播放视频
新建play.html文件放在html目录下
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8>
<title>demo</title>
<link href="https://vjs.zencdn.net/7.0.3/video-js.css" rel="stylesheet">
</head>
<body>
<video id="myVideo" class="video-js vjs-default-slin vjs-big-play-centered" controls preload="auto" width="720" height="540" data-setup='{}'>
<source id="source” type="application/x-mpegURL" src="http://192.168.58.52:80/live/test.m3u8">
</video>
</body>
<script src="https://vjs.zencdn.net/7.0.3/video.js"></script>
</html>
输入网址http://localhost/play.html
看到如下页面
点击play video按钮播放视频
最后我们就实现了一个简单的视频推流拉流示例,视频推流拉流工具包点击这里下载,无需积分