FFmpegExecUtils.java
5.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
package top.panll.assist.service;
import net.bramp.ffmpeg.FFmpeg;
import net.bramp.ffmpeg.FFmpegExecutor;
import net.bramp.ffmpeg.FFmpegUtils;
import net.bramp.ffmpeg.FFprobe;
import net.bramp.ffmpeg.builder.FFmpegBuilder;
import net.bramp.ffmpeg.job.FFmpegJob;
import net.bramp.ffmpeg.probe.FFmpegProbeResult;
import net.bramp.ffmpeg.progress.Progress;
import net.bramp.ffmpeg.progress.ProgressListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.util.DigestUtils;
import top.panll.assist.dto.UserSettings;
import top.panll.assist.utils.RedisUtil;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.List;
import java.util.concurrent.TimeUnit;
@Component
public class FFmpegExecUtils implements InitializingBean{
private final static Logger logger = LoggerFactory.getLogger(FFmpegExecUtils.class);
// private static FFmpegExecUtils instance;
//
// public FFmpegExecUtils() {
// }
//
// public static FFmpegExecUtils getInstance(){
// if(instance==null){
// synchronized (FFmpegExecUtils.class){
// if(instance==null){
// instance=new FFmpegExecUtils();
// }
// }
// }
// return instance;
// }
@Autowired
private UserSettings userSettings;
@Autowired
private RedisUtil redisUtil;
private FFprobe ffprobe;
private FFmpeg ffmpeg;
public FFprobe getFfprobe() {
return ffprobe;
}
public FFmpeg getFfmpeg() {
return ffmpeg;
}
@Override
public void afterPropertiesSet() throws Exception {
String ffmpegPath = userSettings.getFfmpeg();
String ffprobePath = userSettings.getFfprobe();
this.ffmpeg = new FFmpeg(ffmpegPath);
this.ffprobe = new FFprobe(ffprobePath);
logger.info("wvp-pro辅助程序启动成功。 \n{}\n{} ", this.ffmpeg.version(), this.ffprobe.version());
}
public interface VideoHandEndCallBack {
void run(String status, double percentage, String result);
}
@Async
public void mergeOrCutFile(List<File> fils, File dest, String destFileName, VideoHandEndCallBack callBack){
if (fils == null || fils.size() == 0 || ffmpeg == null || ffprobe == null || dest== null || !dest.exists()){
callBack.run("error", 0.0, null);
return;
}
File tempFile = new File(dest.getAbsolutePath());
if (!tempFile.exists()) {
tempFile.mkdirs();
}
FFmpegExecutor executor = new FFmpegExecutor(ffmpeg, ffprobe);
String fileListName = tempFile.getAbsolutePath() + File.separator + "fileList";
double durationAll = 0.0;
try {
BufferedWriter bw =new BufferedWriter(new FileWriter(fileListName));
for (File file : fils) {
String[] split = file.getName().split("-");
if (split.length != 3) continue;
String durationStr = split[2].replace(".mp4", "");
Double duration = Double.parseDouble(durationStr)/1000;
bw.write("file " + file.getAbsolutePath());
bw.newLine();
durationAll += duration;
}
bw.flush();
bw.close();
} catch (IOException e) {
e.printStackTrace();
callBack.run("error", 0.0, null);
}
String recordFileResultPath = dest.getAbsolutePath() + File.separator + destFileName + ".mp4";
long startTime = System.currentTimeMillis();
FFmpegBuilder builder = new FFmpegBuilder()
.setFormat("concat")
.overrideOutputFiles(true)
.setInput(fileListName) // Or filename
.addExtraArgs("-safe", "0")
.addExtraArgs("-threads", userSettings.getThreads() + "")
.addOutput(recordFileResultPath)
.setVideoCodec("copy")
.setAudioCodec("copy")
.setFormat("mp4")
.done();
double finalDurationAll = durationAll;
FFmpegJob job = executor.createJob(builder, (Progress progress) -> {
final double duration_ns = finalDurationAll * TimeUnit.SECONDS.toNanos(1);
double percentage = progress.out_time_ns / duration_ns;
// Print out interesting information about the progress
// System.out.println(String.format(
// "[%.0f%%] status:%s frame:%d time:%s ms fps:%.0f speed:%.2fx",
// percentage * 100,
// progress.status,
// progress.frame,
// FFmpegUtils.toTimecode(progress.out_time_ns, TimeUnit.NANOSECONDS),
// progress.fps.doubleValue(),
// progress.speed
// ));
if (progress.status.equals(Progress.Status.END)){
callBack.run(progress.status.name(), percentage, recordFileResultPath);
}else {
callBack.run(progress.status.name(), percentage, null);
}
});
job.run();
}
public double duration(File file) throws IOException {
FFmpegProbeResult in = ffprobe.probe(file.getAbsolutePath());
return in.getFormat().duration * 1000;
}
}