使用ffmpeg可以从m4s音频和视频文件生成mp4文件,命令为
ffmpeg -i audio.m4s -i video.m4s -codec copy 1.mp4
java提供Process类来模拟执行命令行。
需要在项目资源路径下放置ffmpeg.exe

package com.client.util;
import com.client.spider.w12.bilibili.core.Progress;
import com.client.spider.w12.bilibili.exception.FileUnexpectedEndException;
import java.io.*;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/** 从m4s音频和视频文件生成mp4<br/>
* 使用ffmpeg命令进行,命令为<br/>
* ffmpeg -i audio.m4s -i video.m4s -codec copy 1.mp4<br/>
* 需要在项目资源路径下放置ffmpeg.exe
*/
public class TransCoding {
/**如果文件存在,删除文件*/
public static void deleteIfExist(String pathname){
File file=new File(pathname);
if(file.exists()){
file.delete();
}
}
public static boolean checkExist(String pathname){
File file=new File(pathname);
return file.exists();
}
//ffmpeg程序的位置
private static String ffmpeg="\\ffmpeg.exe";;
public void createMp4FromM4s(String audioPath,String videoPath,String output){
if(!checkExist(audioPath)|| !checkExist(videoPath))throw new RuntimeException("输入文件不存在");
deleteIfExist(output);
System.out.println("生成文件中 "+output);
String command=ffmpeg+" -i "+audioPath+" -i "+videoPath+" -codec copy "+output;
exec(Arrays.asList(command.split(" ")));
}
public void createMp4FromM4sInNewThread(String audioPath,String videoPath,String output,Runnable additionTask){
new Thread(()->{
createMp4FromM4s(audioPath, videoPath, output);
if(additionTask!=null)additionTask.run();
}).start();
}
/**
* 模拟命令行执行命令
* @param command 命令
* @return true-成功 false-失败
*/
private boolean exec(List<String> command){
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command(command);
try {
processBuilder.redirectErrorStream(true);
Process process = processBuilder.start();
new StreamHandler(process.getInputStream()).start();
process.waitFor();
process.destroy();
} catch (IOException e) {
e.printStackTrace();
return false;
} catch (InterruptedException e) {
e.printStackTrace();
}
return true;
}
//读取输出,防止阻塞
static class StreamHandler extends Thread {
private InputStream in;
public StreamHandler(InputStream in) {
this.in = in;
}
public void run() {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line;
while ((line = reader.readLine()) != null) {
//System.out.println(Thread.currentThread().getName() + "\t" + line);
}
} catch (Exception e) {
System.out.println(Thread.currentThread().getName() + "\t" + e.getMessage());
}
}
}
public static void main(String[] args) {
String v="D:\\magnetCatcher\\test\\BV1HZ4y117zQ\\Video.m4s";
String a="D:\\magnetCatcher\\test\\BV1HZ4y117zQ\\Audio.m4s";
String o="D:\\magnetCatcher\\test\\BV1HZ4y117zQ\\Video.mp4";
new TransCoding().createMp4FromM4s(a,v,o);
}
}
经测试,该类可以转化B站的缓存视频。对于几十兆大小的视频,转化时间在秒级内。

通过ffmpeg工具,利用Java的Process类执行命令行操作,可以将m4s格式的音频和视频文件转换成mp4。这种方法在处理B站缓存视频时有效,且对于几十兆的视频,转换时间仅需几秒钟。
3935

被折叠的 条评论
为什么被折叠?



