output.ts
在类中定义正则表达式,以方便修改。
函数中使用文件名后缀方式判断当前文件是否是符合要求的视频文件。
// 判断是否是视频文件正则
private static String isVideoFileRegex = ".*\\.(mp4|avi|mkv)$";
/**
* 判断是否符合想要的格式
* mp4|avi|mkv
* 通过文件后缀名哦安短
*
* @param fileName 文件名称
* @return 布尔值
*/
private static boolean isVideoFile(String fileName) {
return fileName.matches(isVideoFileRegex);
}
因为在使用过程中需要使用两次命令行的操作,使用Java调起命令行,这是可以封装成单独的函数,使用时只需要将命令行传入即可。
创建了一个 ProcessBuilder
对象,并使用给定的命令字符串初始化它。ProcessBuilder
类用于创建操作系统进程,并提供一种从 Java 程序中启动外部命令的方式。
command.split(" ")
将输入的命令字符串分割成一个字符串数组,每个数组元素都是一个命令或参数。然后,这个数组被用来初始化 ProcessBuilder
对象,以便在后续步骤中启动一个新的进程来执行这些命令。
processBuilder.redirectErrorStream(true)
设置了当启动的进程产生错误流时,将错误流合并到标准输出流中。这意味着在执行命令时,任何由该命令生成的错误输出将会与标准输出一起被捕获,并可以通过 Java 程序进行处理。
ProcessBuilder processBuilder = new ProcessBuilder(command.split(" "));
processBuilder.redirectErrorStream(true);
processBuilder.start()
启动了之前创建的 ProcessBuilder
对象,执行之前设置的命令。BufferedReader
对象将其连接到外部进程的标准输出流,程序可以读取外部进程的输出。这里使用了 InputStreamReader
将字节流转换为字符流,然后通过 BufferedReader
逐行读取外部进程的输出。while
循环中,程序持续读取外部进程的输出,直到输出结束。每读取一行输出,该行内容被打印到控制台上。process.waitFor()
,程序会等待外部进程执行完毕。这会导致当前的线程暂停,直到外部进程执行完成。try {
Process process = processBuilder.start();
// 将ffmpeg执行内容输出在控制台中
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
// 等待转换完成
process.waitFor();
} catch (IOException | InterruptedException e) {
throw new RuntimeException(e);
}
// 输入文件夹
private static String inputDirectory = "C:\\Users\\13199\\Downloads";
// 输出m3u8文件
private static String outputM3u8FileName = "index.m3u8";
// 判断是否是视频文件正则
private static String isVideoFileRegex = ".*\\.(mp4|avi|mkv)$";
// 选择切片时间
private static Integer HlsTime = 1;
/**
* 执行将文件转成m3u8 hls格式
*
* @param command Ffmpeg 命令
*/
private static void executeFfmpegCommand(String command) {
ProcessBuilder processBuilder = new ProcessBuilder(command.split(" "));
processBuilder.redirectErrorStream(true);
try {
Process process = processBuilder.start();
// 将ffmpeg执行内容输出在控制台中
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
// 等待转换完成
process.waitFor();
} catch (IOException | InterruptedException e) {
throw new RuntimeException(e);
}
}
inputFilePath
确定了输出目录 outputDirectory
。使用正则表达式 \\.[^.]+$
来匹配文件路径中的文件扩展名,并将其替换为空字符串,从而得到输出目录的路径。File
对象来代表输出目录,并检查该目录是否存在。如果输出目录不存在,用 mkdirs()
方法来创建输出目录。outputFilePath
,这里假设输出文件的名称为 “output.ts”,并将其放在之前确定的输出目录中。command
,该命令使用输入文件路径来进行转换,具体命令包括了输入文件、编解码器选项、关键帧选项等参数。executeFfmpegCommand
将构建的 FFmpeg 命令字符串作为参数传递给该方法,以执行 FFmpeg 命令。convertToM3U8
的方法,该方法可能用于将生成的视频文件转换为 M3U8 格式// 输入文件夹
private static String inputDirectory = "C:\\Users\\13199\\Downloads";
// 输出m3u8文件
private static String outputM3u8FileName = "index.m3u8";
// 判断是否是视频文件正则
private static String isVideoFileRegex = ".*\\.(mp4|avi|mkv)$";
// 选择切片时间
private static Integer HlsTime = 1;
/**
* 如果文件名 后缀符合将文件先转成ts类型文件
* 有实验表名,先转成ts会快一点
*
* @param inputFilePath 当前文件的路径
*/
private static void convertToTs(String inputFilePath) {
String outputDirectory = inputFilePath.replaceFirst("\\.[^.]+$", "");
File directory = new File(outputDirectory);
if (!directory.exists()) {
directory.mkdirs();
}
String outputFilePath = outputDirectory + File.separator + "output.ts";
String command = "ffmpeg -i " + inputFilePath + " -c copy -bsf:v h264_mp4toannexb -force_key_frames expr:gte(t,n_forced*" + HlsTime + ") -f mpegts " + outputFilePath;
executeFfmpegCommand(command);
convertToM3U8(outputDirectory);
}
输出文件的路径 outputFilePath
,这个路径是由输入目录 inputDirectory
和一个名为 outputM3u8FileName
之后将这段代码放到之前封装好的执行命令函数中executeFfmpegCommand
// 输入文件夹
private static String inputDirectory = "C:\\Users\\13199\\Downloads";
// 输出m3u8文件
private static String outputM3u8FileName = "index.m3u8";
// 判断是否是视频文件正则
private static String isVideoFileRegex = ".*\\.(mp4|avi|mkv)$";
// 选择切片时间
private static Integer HlsTime = 1;
/**
* 将文件转成hls类型,并且m3u8命名为index
* 切片的ts以output.ts转换
*
* @param inputDirectory 输入的文件夹
*/
private static void convertToM3U8(String inputDirectory) {
// 使用FFmpeg将ts文件转换成m3u8文件
String outputFilePath = inputDirectory + File.separator + outputM3u8FileName;
String command = "ffmpeg -i " + inputDirectory + File.separator + "output.ts" + " -c:v libx264 -c:a aac -force_key_frames expr:gte(t,n_forced*" + HlsTime + ") -hls_time " + HlsTime + " -hls_list_size 0 -f hls " + outputFilePath;
executeFfmpegCommand(command);
}
需要使用-hls_segment_filename
参数。这个参数可以帮助你自定义切片文件的命名规则。
如果要将输入的ts文件以1,2,3这种方式命名可以使用这个方法inputDirectory + File.separator + "%d.ts"
String segmentFilename = inputDirectory + File.separator + "%d.ts"; // 定义切片文件名规则
String command = "ffmpeg -i " + inputDirectory + File.separator + "output.ts" + " -c:v libx264 -c:a aac -force_key_frames expr:gte(t,n_forced*1) -hls_time 1 -hls_list_size 0 -f hls -hls_segment_filename " + segmentFilename + " " + outputFilePath; // 定义切片文件名规则
executeFfmpegCommand(command);
File
对象来代表输入目录 inputDirectory
。isVideoFile
方法进行检查)。convertToTs
方法,传递视频文件的绝对路径作为参数,以启动视频文件的转换过程。// 输入文件夹
private static String inputDirectory = "C:\\Users\\13199\\Downloads";
// 输出m3u8文件
private static String outputM3u8FileName = "index.m3u8";
// 判断是否是视频文件正则
private static String isVideoFileRegex = ".*\\.(mp4|avi|mkv)$";
// 选择切片时间
private static Integer HlsTime = 1;
/**
* 定义目录所在位置
* 循环遍历这个目录文件,找到子目录的视频文件
* 判断当前的文件是否是视频文件
* 如果是文件夹则继续遍历
*
* @param args main program arguments
*/
public static void main(String[] args) {
File directory = new File(inputDirectory);
if (directory.isDirectory()) {
File[] files = directory.listFiles();
assert files != null;
for (File file : files) {
if (file.isFile() && isVideoFile(file.getName())) {
String inputFilePath = file.getAbsolutePath();
new Thread(() -> convertToTs(inputFilePath)).start();
}
}
}
}
// 输入文件夹
private static String inputDirectory = "C:\\Users\\13199\\Downloads";
// 输出m3u8文件
private static String outputM3u8FileName = "index.m3u8";
// 判断是否是视频文件正则
private static String isVideoFileRegex = ".*\\.(mp4|avi|mkv)$";
// 选择切片时间
private static Integer HlsTime = 1;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
@Data
public class NewTest {
// 输入文件夹
private static String inputDirectory = "C:\\Users\\13199\\Downloads";
// 输出m3u8文件
private static String outputM3u8FileName = "index.m3u8";
// 判断是否是视频文件正则
private static String isVideoFileRegex = ".*\\.(mp4|avi|mkv)$";
// 选择切片时间
private static Integer HlsTime = 1;
/**
* 定义目录所在位置
* 循环遍历这个目录文件,找到子目录的视频文件
* 判断当前的文件是否是视频文件
* 如果是文件夹则继续遍历
*
* @param args main program arguments
*/
public static void main(String[] args) {
File directory = new File(inputDirectory);
if (directory.isDirectory()) {
File[] files = directory.listFiles();
assert files != null;
for (File file : files) {
if (file.isFile() && isVideoFile(file.getName())) {
String inputFilePath = file.getAbsolutePath();
new Thread(() -> convertToTs(inputFilePath)).start();
}
}
}
}
/**
* 如果文件名 后缀符合将文件先转成ts类型文件
* 有实验表名,先转成ts会快一点
*
* @param inputFilePath 当前文件的路径
*/
private static void convertToTs(String inputFilePath) {
String outputDirectory = inputFilePath.replaceFirst("\\.[^.]+$", "");
File directory = new File(outputDirectory);
if (!directory.exists()) {
directory.mkdirs();
}
String outputFilePath = outputDirectory + File.separator + "output.ts";
String command = "ffmpeg -i " + inputFilePath + " -c copy -bsf:v h264_mp4toannexb -force_key_frames expr:gte(t,n_forced*" + HlsTime + ") -f mpegts " + outputFilePath;
executeFfmpegCommand(command);
convertToM3U8(outputDirectory);
}
/**
* 将文件转成hls类型,并且m3u8命名为index
* 切片的ts以output.ts转换
*
* @param inputDirectory 输入的文件夹
*/
private static void convertToM3U8(String inputDirectory) {
// 使用FFmpeg将ts文件转换成m3u8文件
String outputFilePath = inputDirectory + File.separator + outputM3u8FileName;
String command = "ffmpeg -i " + inputDirectory + File.separator + "output.ts" + " -c:v libx264 -c:a aac -force_key_frames expr:gte(t,n_forced*" + HlsTime + ") -hls_time " + HlsTime + " -hls_list_size 0 -f hls " + outputFilePath;
executeFfmpegCommand(command);
}
/**
* 执行将文件转成m3u8 hls格式
*
* @param command Ffmpeg 命令
*/
private static void executeFfmpegCommand(String command) {
ProcessBuilder processBuilder = new ProcessBuilder(command.split(" "));
processBuilder.redirectErrorStream(true);
try {
Process process = processBuilder.start();
// 将ffmpeg执行内容输出在控制台中
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
// 等待转换完成
process.waitFor();
} catch (IOException | InterruptedException e) {
throw new RuntimeException(e);
}
}
/**
* 判断是否符合想要的格式
* mp4|avi|mkv
* 通过文件后缀名哦安短
*
* @param fileName 文件名称
* @return 布尔值
*/
private static boolean isVideoFile(String fileName) {
return fileName.matches(isVideoFileRegex);
}
}