因为工作需要,这边花了2天时间 做了一个基于javacv进行音视频转码,以及音视频截取功能,已经进行部分压测,没有问题。本文章是参考网上的方案,但是原来的链接没有记录。如果原作者发现了,可以私聊我,或者直接在下方评论把链接粘贴。本帖只发视频转码部分
# maven依赖
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv-platform</artifactId>
<version>1.5.3</version>
</dependency>
大致流程:
import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.FrameGrabber;
import org.springframework.util.StopWatch
public long convert2mp4(File file, String videoSavePath) throws IOException {
// 判断文件夹存在
File saveVideoPath = new File(videoSavePath);
if (!saveVideoPath.exists() && !saveVideoPath.isDirectory()) {
saveVideoPath.mkdirs();
}
//第一步:设置输出的文件路径
String csvname = videoSavePath + File.separator + file.getAbsolutePath().substring(file.getAbsolutePath().lastIndexOf(File.separator) + 1) + ".csv";
//如果该目录下不存在该文件,则文件会被创建到指定目录下。如果该目录有同名文件,那么该文件将被覆盖。
File writeFile = new File(csvname);
//第二步:通过BufferedReader类创建一个使用默认大小输出缓冲区的缓冲字符输出流
BufferedWriter writeText = new BufferedWriter(new FileWriter(writeFile));
//创建并启动StopWatch
StopWatch stopwatch = new StopWatch();
stopwatch.start();
FFmpegFrameGrabber frameGrabber = new FFmpegFrameGrabber(file.getAbsolutePath());
String fileFullPathName = null;
Frame captured_frame = null;
FFmpegFrameRecorder recorder = null;
try {
frameGrabber.start();
//获取转换后的文件名
String filename = file.getName().substring(0, file.getName().lastIndexOf(".")) + "_" + file.getName().substring(file.getName().lastIndexOf(".") + 1) + ".mp4";
//更换转码后视频存储位置
fileFullPathName = videoSavePath + File.separator + filename;
recorder = new FFmpegFrameRecorder(fileFullPathName, frameGrabber.getImageWidth(), frameGrabber.getImageHeight(), frameGrabber.getAudioChannels());
recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
recorder.setFormat("mp4");
recorder.setFrameRate(frameGrabber.getFrameRate());
recorder.setVideoBitrate(frameGrabber.getVideoBitrate());
recorder.setAudioBitrate(192000);
recorder.setAudioOptions(frameGrabber.getAudioOptions());
recorder.setAudioQuality(0);
recorder.setSampleRate(44100);
recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);
recorder.start();
while (true) {
try {
captured_frame = frameGrabber.grabFrame();
if (captured_frame == null) {
System.out.println("\n\nfinish " + fileFullPathName+"\n\n");
break;
}
recorder.record(captured_frame);
} catch (Exception e) {
e.printStackTrace();
}
}
recorder.stop();
recorder.release();
frameGrabber.stop();
frameGrabber.release();
recorder.close();
frameGrabber.close();
} catch (Exception e) {
e.printStackTrace();
}
stopwatch.stop();
writeText.newLine(); //换行
//调用write的方法将字符串写到流中
writeText.write(fileFullPathName +","+ stopwatch.getLastTaskTimeMillis()/1000 +"s," + (float) new FileInputStream(fileFullPathName).getChannel().size() / 1024 / 1024+"MB");
//使用缓冲区的刷新方法将数据刷到目的地中
writeText.flush();
//关闭缓冲区,缓冲区没有调用系统底层资源,真正调用底层资源的是FileWriter对象,缓冲区仅仅是一个提高效率的作用
//因此,此处的close()方法关闭的是被缓存的流对象
writeText.close();
return stopwatch.getLastTaskTimeMillis()/1000;
}