1. 代码示例
package com.simple.util.base.extend.video;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
* @program: simple_tools
* @description: 视频操作工具类
* @author: ChenWenLong
* @create: 2020-01-07 09:19
**/
public class VideoUtil {

private String ffmpeg_path = "D:\\Program Files\\ffmpeg-20180227-fa0c9d6-win64-static\\bin\\ffmpeg.exe";//ffmpeg的安装位置
private String video_path = "D:\\BaiduNetdiskDownload\\test1.avi";
private String m3u8_name = "test1.m3u8";
private String m3u8folder_path = "D:/BaiduNetdiskDownload/Movies/test1/";

public VideoUtil(String ffmpeg_path) {
this.ffmpeg_path = ffmpeg_path;
this.video_path = video_path;
this.m3u8_name = m3u8_name;
this.m3u8folder_path = m3u8folder_path;
}

/**
* 功能描述:
* 〈检查视频时间是否一致〉
*
* @return : java.lang.Boolean
* @params : [source, target]
* @author : cwl
* @date : 2020/1/7 9:22
*/
public Boolean check_video_time(String source, String target) {
String source_time = get_video_time(source);
//取出时分秒
source_time = source_time.substring(0, source_time.lastIndexOf("."));
String target_time = get_video_time(target);
//取出时分秒
target_time = target_time.substring(0, target_time.lastIndexOf("."));
if (source_time == null || target_time == null) {
return false;
}
if (source_time.equals(target_time)) {
return true;
}
return false;
}

/**
* 功能描述:
* 〈获取视频时间(时:分:秒:毫秒)〉
*
* @return : java.lang.String
* @params : [video_path]
* @author : cwl
* @date : 2020/1/7 9:22
*/
public String get_video_time(String video_path) {
/*
ffmpeg -i lucene.mp4
*/
List<String> commend = new ArrayList<String>();
commend.add(ffmpeg_path);
commend.add("-i");
commend.add(video_path);
try {
ProcessBuilder builder = new ProcessBuilder();
builder.command(commend);
//将标准输入流和错误输入流合并,通过标准输入流程读取信息
builder.redirectErrorStream(true);
Process p = builder.start();
String outstring = waitFor(p);
System.out.println(outstring);
int start = outstring.trim().indexOf("Duration: ");
if (start >= 0) {
int end = outstring.trim().indexOf(", start:");
if (end >= 0) {
String time = outstring.substring(start + 10, end);
if (time != null && !time.equals("")) {
return time.trim();
}
}
}

} catch (Exception ex) {

ex.printStackTrace();

}
return null;
}

public String waitFor(Process p) {
InputStream in = null;
InputStream error = null;
String result = "error";
int exitValue = -1;
StringBuffer outputString = new StringBuffer();
try {
in = p.getInputStream();
error = p.getErrorStream();
boolean finished = false;
int maxRetry = 600;//每次休眠1秒,最长执行时间10分种
int retry = 0;
while (!finished) {
if (retry > maxRetry) {
return "error";
}
try {
while (in.available() > 0) {
Character c = new Character((char) in.read());
outputString.append(c);
System.out.print(c);
}
while (error.available() > 0) {
Character c = new Character((char) in.read());
outputString.append(c);
System.out.print(c);
}
//进程未结束时调用exitValue将抛出异常
exitValue = p.exitValue();
finished = true;

} catch (IllegalThreadStateException e) {
Thread.currentThread().sleep(1000);//休眠1秒
retry++;
}
}

} catch (Exception e) {
e.printStackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
return outputString.toString();

}

private void clear_m3u8(String m3u8_path) {
//删除原来已经生成的m3u8及ts文件
File m3u8dir = new File(m3u8_path);
if (!m3u8dir.exists()) {
m3u8dir.mkdirs();
}
/* if(m3u8dir.exists()&&m3u8_path.indexOf("/hls/")>=0){//在hls目录方可删除,以免错误删除
String[] children = m3u8dir.list();
//删除目录中的文件
for (int i = 0; i < children.length; i++) {
File file = new File(m3u8_path, children[i]);
file.delete();
}
}else{
m3u8dir.mkdirs();
}*/
}

/**
* 功能描述:
* 〈生成m3u8文件〉
* 成功则返回success,失败返回控制台日志
*
* @params : []
* @return : java.lang.String
* @author : cwl
* @date : 2020/1/7 9:23
*/
public String generateM3u8() {
//清理m3u8文件目录
clear_m3u8(m3u8folder_path);
/*
ffmpeg -i lucene.mp4 -hls_time 10 -hls_list_size 0 -hls_segment_filename ./hls/lucene_%05d.ts ./hls/lucene.m3u8
*/
// String m3u8_name = video_name.substring(0, video_name.lastIndexOf("."))+".m3u8";
List<String> commend = new ArrayList<String>();
commend.add(ffmpeg_path);
commend.add("-i");
commend.add(video_path);
commend.add("-hls_time");
commend.add("10");
commend.add("-hls_list_size");
commend.add("0");
commend.add("-hls_segment_filename");
// commend.add("D:/BaiduNetdiskDownload/Movies/test1/test1_%05d.ts");
commend.add(m3u8folder_path + m3u8_name.substring(0, m3u8_name.lastIndexOf(".")) + "_%05d.ts");
// commend.add("D:/BaiduNetdiskDownload/Movies/test1/test1.m3u8");
commend.add(m3u8folder_path + m3u8_name);
String outstring = null;
try {
ProcessBuilder builder = new ProcessBuilder();
builder.command(commend);
//将标准输入流和错误输入流合并,通过标准输入流程读取信息
builder.redirectErrorStream(true);
Process p = builder.start();
outstring = waitFor(p);

} catch (Exception ex) {

ex.printStackTrace();

}
//通过查看视频时长判断是否成功
Boolean check_video_time = check_video_time(video_path, m3u8folder_path + m3u8_name);
if (!check_video_time) {
return outstring;
}
//通过查看m3u8列表判断是否成功
List<String> ts_list = get_ts_list();
if (ts_list == null) {
return outstring;
}
return "success";


}

/**
* 功能描述:
* 〈检查视频处理是否完成〉
*
* @return : java.util.List<java.lang.String>
* @params : []
* @author : cwl
* @date : 2020/1/7 9:23
*/
public List<String> get_ts_list() {
// String m3u8_name = video_name.substring(0, video_name.lastIndexOf("."))+".m3u8";
List<String> fileList = new ArrayList<String>();
List<String> tsList = new ArrayList<String>();
String m3u8file_path = m3u8folder_path + m3u8_name;
BufferedReader br = null;
String str = null;
String bottomline = "";
try {
br = new BufferedReader(new FileReader(m3u8file_path));
while ((str = br.readLine()) != null) {
bottomline = str;
if (bottomline.endsWith(".ts")) {
tsList.add(bottomline);
}
//System.out.println(str);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
if (bottomline.contains("#EXT-X-ENDLIST")) {
// fileList.add(hls_relativepath+m3u8_name);
fileList.addAll(tsList);
return fileList;
}
return null;

}
}