网页设计创建站点教程,怎么做百度自己的网站空间,个人申请公众号注册,wordpress自由度Java转成m3u8,hls格式
需求分析
大致思路
循环文件夹下面所有文件判断当前文件是否是视频文件#xff0c;如果是视频文件先转为ts文件 因为听别人说先转成ts之后再切片会快很多 转成ts文件#xff0c;并为这些文件单独生成一个目录#xff0c;如果目录不存在则新建一个目…Java转成m3u8,hls格式
需求分析
大致思路
循环文件夹下面所有文件判断当前文件是否是视频文件如果是视频文件先转为ts文件 因为听别人说先转成ts之后再切片会快很多 转成ts文件并为这些文件单独生成一个目录如果目录不存在则新建一个目录 执行转换命令—转成ts文件 执行完成后再将ts文件转成m3u8文件
详细流程
判断当前文件夹是否是一个目录如果是目录就遍历下面的文件包括所以的文件。循环这些子文件如果当前的文件是文件并且是视频文件写一个判断函数因为格式不同循环完成后将这些视频转成ts并为这些文件生成单独目录转成ts文件命名为output.ts 需要为这些文件单独写一个执行命令函数封装 转成ts后再将这些视频转成m3u8
方法实现
判断是否为文件函数
在类中定义正则表达式以方便修改。
函数中使用文件名后缀方式判断当前文件是否是符合要求的视频文件。
// 判断是否是视频文件正则
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);}
}转成ts
根据输入文件路径 inputFilePath 确定了输出目录 outputDirectory。使用正则表达式 \\.[^.]$ 来匹配文件路径中的文件扩展名并将其替换为空字符串从而得到输出目录的路径。创建了一个 File 对象来代表输出目录并检查该目录是否存在。如果输出目录不存在用 mkdirs() 方法来创建输出目录。构建了一个输出文件的路径 outputFilePath这里假设输出文件的名称为 “output.ts”并将其放在之前确定的输出目录中。FFmpeg 命令字符串 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);
}转成m3u8
输出文件的路径 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);
}自定义ts输出名
需要使用-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);}
}