FFmpeg 最好到先下载好
FFmpeg官网
经过测试 大概1G左右分段视频 大概所需要 1s左右,但是比较吃IO,所以最好 输出目录最好到 固态硬盘哈。
使用maven的依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.30<</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.16</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.6</version>
</dependency>
package com.xiaoyun.common;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class BiliMerge {
public static void main(String[] args) throws IOException {
//bilibili视频缓存所在的文件夹,自动递归查找文件夹
String inFile = "F:\\xiaoyun6";
//ffmpeg.exe 的所在目录
String ffmpegFile = ("D:\\log\\ffmpeg\\bin\\ffmpeg.exe");
//输出目录
String outFile = "F:\\xiaoyun6\\movie\\";
long start = System.currentTimeMillis();
runffmpeg(inFile, outFile, ffmpegFile);
System.out.println("所用时间:" + (System.currentTimeMillis() - start));
}
public static void runffmpeg(String inFile, String outFile, String ffmpegFile) {
fileName(new File(inFile));
list.stream().parallel()
.filter(biliName -> !new File(new StringBuilder(outFile).append(biliName.getName()).append(".mp4").toString()).isFile())
.forEach(biliName ->
{
if (StringUtils.isNotEmpty(biliName.getAudioFile()) && StringUtils.isNotEmpty(biliName.getVideoFile())) {
ffmpegUtil(biliName.getVideoFile(), biliName.getAudioFile(), new StringBuilder(outFile).append(biliName.getName()).append(".mp4").toString(),
ffmpegFile);
System.out.println(biliName.getName() + ",转换成功");
} else {
if (null == biliName.getVideoFile()) {
System.err.println("编号id为:" + biliName.getId() + " 输入的video.m4s 不存在" + ".详细信息为: " + biliName);
}
if (null == biliName.getAudioFile()) {
System.err.println("编号id为:" + biliName.getId() + " 输入的audio.m4s 不存在" + ".详细信息为: " + biliName);
}
}
}
);
}
private static List<BiliName> list = new ArrayList<>();
public static void fileName(File file) {
if (file.isDirectory()) {
String[] directoryList = file.list();
if (ArrayUtils.isNotEmpty(directoryList)) {
for (String directory : directoryList) {
fileName(new File(file, directory));
}
}
}
String fileName = file.getName();
if (file.isFile()) {
if ("entry.json".equals(fileName)) {
String id = file.getParentFile().getName();
readerName(id, file);
}
if ("audio.m4s".equals(fileName) || "video.m4s".equals(fileName)) {
File parentFile = parentName(file);
Integer avId = Integer.valueOf(parentFile.getParentFile().getName());
BiliName biliName = findBiliById(parentFile.getName(), avId);
if ("audio.m4s".equals(fileName)) {
biliName.setAudioFile(file.getPath());
}
if ("video.m4s".equals(fileName)) {
biliName.setVideoFile(file.getPath());
}
}
}
}
private static BiliName findBiliById(String id, Integer avId) {
if (list != null) {
for (BiliName biliName : list) {
if (biliName != null && id.equals(biliName.getId()) && avId.equals(biliName.getAvid())) {
return biliName;
}
}
}
BiliName biliName = new BiliName();
biliName.setId(id);
biliName.setAvid(avId);
list.add(biliName);
return biliName;
}
private static File parentName(File file) {
return file.getParentFile().getParentFile();
}
private static void setName(String id, Integer avid, String parentName, String name) {
if (list != null) {
for (BiliName biliName : list) {
if (biliName != null && id.equals(biliName.getId()) && avid.equals(biliName.getAvid())) {
biliName.setParentName(parentName);
biliName.setName(name);
biliName.setAvid(avid);
break;
}
}
}
}
private static void readerName(String id, File file) {
BufferedReader bufferedReader = null;
FileInputStream inputStream = null;
InputStreamReader inputStreamReader = null;
try {
inputStream = new FileInputStream(file);
inputStreamReader = new InputStreamReader(inputStream);
bufferedReader = new BufferedReader(inputStreamReader);
StringBuilder sb = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
sb.append(line);
}
String jsonStr = sb.toString();
Map map = JSON.parseObject(jsonStr, Map.class);
if (map.containsKey("title") && map.containsKey("avid")) {
String title = (String) map.get("title");
Integer avid = (Integer) map.get("avid");
if (map.containsKey("page_data")) {
JSONObject page_data = (JSONObject) map.get("page_data");
String download_subtitle = (String) page_data.get("download_subtitle");
setName(id, avid, title, download_subtitle);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
private static void ffmpegUtil(String videoFile, String audioFile, String outFile, String FFmpeg) {
if (videoFile == null || audioFile == null || outFile == null || FFmpeg == null) {
return;
} else {
ProcessBuilder processBuilder = new ProcessBuilder();
List<String> command = new ArrayList<>();
command.add(FFmpeg);
command.add("-i");
command.add(videoFile);
command.add("-i");
command.add(audioFile);
command.add("-codec");
command.add("copy");
command.add(outFile);
processBuilder.command(command);
processBuilder.redirectErrorStream(true);
// InputStream inputStream = null;
Process process = null;
try {
//启动进程
process = processBuilder.start();
// inputStream = process.getInputStream();
//转成字符流
// List list = IOUtils.readLines(inputStream, "utf-8");
// list.stream().forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
// } finally {
// IOUtils.closeQuietly(inputStream);
}
}
}
}
@Data
class BiliName {
private String id;
private String parentName;
private String name;
private String videoFile;
private String audioFile;
private Integer avid;
}