需要对mp3文件进行剪辑,剪掉几秒到几秒,然后生成新的文件。
目前有两种方法,
方法一、是用脚本+安装FFmpeg执行包,
方法二、不需要安装FFmpeg,直接调用ffmpeg包解码。
本文介绍的为方法二,不需要下载安装FFmpeg.
1、maven 需要添加2个依赖
javacv 和 ffmpeg-platform 都是org.bytedeco,这两个版本要匹配
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv</artifactId>
<version>1.5.6</version>
</dependency>
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>ffmpeg-platform</artifactId>
<version>4.4-1.5.6</version>
</dependency>
2、写个测试类
public class Mp3Cutter {
public static void main(String[] args) {
// 输入音频文件和输出音频文件路径
String inputFile = "F:\\temp\\欢乐谷.mp3";
String outputFile = "F:\\temp\\mp3_out.mp3";
cutAudio(inputFile, outputFile);
}
public static void cutAudio(String inputFile, String outputFile) {
try {
// 创建 FFmpegFrameGrabber 以读取输入音频文件
FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(inputFile);
int bitrate=grabber.getAudioBitrate();
int sampleRate=grabber.getSampleRate();
// 创建 FFmpegFrameRecorder 以写入输出音频文件
FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(outputFile, 2);
recorder.setAudioCodec(grabber.getAudioCodec());
recorder.setAudioQuality(0);
recorder.setAudioBitrate(64000);//比特,中等效果
recorder.setAudioChannels(2);//grabber.getAudioChannels());
recorder.setSampleRate(44100);//grabber.getSampleRate());
recorder.setAudioOption("crf", "0");
recorder.start();
grabber.start();
//这个顺序要在后面
Frame f;
int total=0;
//计算音频样本帧的数量
while((f=grabber.grabSamples())!=null)
{
total++;
}
//设置要剪辑掉的 18秒--30秒
long startSec=18;
long endSec=startSec+12;
//计算时长
long durationInSec = grabber.getFormatContext().duration() / 1000000;
//设置要剪辑掉的 倒数50秒--60秒
long startSec2=durationInSec-50;
if(durationInSec<=140) {
startSec2=durationInSec-45;
}
long endSec2=startSec2+10;
//按比例计算开始录入的帧
int startFrameNum = getStartOrEndFrameNumber(startSec, durationInSec, total);
int endSecFN=getStartOrEndFrameNumber(endSec, durationInSec, total);
int startFrameNum2=getStartOrEndFrameNumber(startSec2, durationInSec, total);
int endSecFN2=getStartOrEndFrameNumber(endSec2, durationInSec, total);
System.out.println("时长:"+durationInSec+",20秒的帧数:"+startFrameNum+"--"+endSecFN+";"+startFrameNum2+"--"+endSecFN2);
//输出剪辑的开始时间,时长,总共帧数量,开始记录的帧位置
// System.out.println("Start second at {}'s,the duration is {}'s,Total Frame - {},Start frame number - {}", startSec,
// durationInSec, total, startFrameNum);
int i = 0;
//再次读取
grabber.restart();
while ((f = grabber.grabSamples()) != null) {
//略过不需要记录的帧,只从需要的帧位置开始记录
if (i > startFrameNum&&i<endSecFN) {
i++;
System.out.print(".");
continue;
}
if (i > startFrameNum2&&i<endSecFN2) {
i++;
continue;
}
i++;
recorder.record(f);
}
// 关闭资源
grabber.stop();
recorder.stop();
} catch (Exception e) {
e.printStackTrace();
}
}
public static int getStartOrEndFrameNumber(long startOrEndAtSecond, long durationInSecond, int totalFrame) {
if (startOrEndAtSecond >= durationInSecond)
return (int) durationInSecond;
double percent = startOrEndAtSecond / (double) durationInSecond;
return (int) Math.round(totalFrame * percent);
}
}
运行测试。上面的代码可以直接跑。