java 合并mp3
程序员文章站
2022-06-21 15:08:20
...
参考文档:http://www.zhuhongliang.com/archives/670
MP3合并的时候如果文件的采样率,比特率,通道不一致直接合并的话,会导致合并后的mp3播放不出来,或者播放的时候时间不断变化。
如果将文件转换成相同的采样率,比特率,通道合并的话,合并后的文件的大小和单个文件加起来的大小不一致,并且合并后的mp3的声音会发生改变。暂时没有找到可以解决的方式
引入jar包
<dependency>
<groupId>it.sauronsoftware</groupId>
<artifactId>jave</artifactId>
<version>1.0.2</version>
</dependency>
package com.ddp;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.RandomAccessFile;
import java.io.SequenceInputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import it.sauronsoftware.jave.AudioAttributes;
import it.sauronsoftware.jave.AudioInfo;
import it.sauronsoftware.jave.Encoder;
import it.sauronsoftware.jave.EncodingAttributes;
import it.sauronsoftware.jave.MultimediaInfo;
public class Mp3Util {
public static void main(String[] args) throws Exception {
/*
File file = new File("C:/Users/ddp/Desktop/aa");
File[] allFiles = file.listFiles();
for (int i = 0; i < allFiles.length; i++) {
File filei = allFiles[i];
ReadFileUtils readFileUtils = new ReadFileUtils(filei);
System.out.println( "String file" + i + " = \"" + filei.getAbsolutePath().replace("\\", "/") + "\";"
+ "\n//" + readFileUtils.getFileSizeToMB() + "==" + readFileUtils.m);
}
*/
List<String> files = new ArrayList<>();
String file0 = "C:/Users/ddp/Desktop/aa/1.mp3";
//3.82==it.sauronsoftware.jave.MultimediaInfo (format=mp3, duration=250000, video=null, audio=it.sauronsoftware.jave.AudioInfo (decoder=mp3, samplingRate=44100, channels=2, bitRate=128))
String file1 = "C:/Users/ddp/Desktop/aa/10.mp3";
//2.59==it.sauronsoftware.jave.MultimediaInfo (format=mp3, duration=169600, video=null, audio=it.sauronsoftware.jave.AudioInfo (decoder=mp3, samplingRate=44100, channels=2, bitRate=128))
String file2 = "C:/Users/ddp/Desktop/aa/11.mp3";
//9.33==it.sauronsoftware.jave.MultimediaInfo (format=mp3, duration=244400, video=null, audio=it.sauronsoftware.jave.AudioInfo (decoder=mp3, samplingRate=44100, channels=2, bitRate=320))
String file3 = "C:/Users/ddp/Desktop/aa/12.mp3";
//3.92==it.sauronsoftware.jave.MultimediaInfo (format=mp3, duration=171400, video=null, audio=it.sauronsoftware.jave.AudioInfo (decoder=mp3, samplingRate=44100, channels=2, bitRate=192))
String file4 = "C:/Users/ddp/Desktop/aa/13.mp3";
//8.02==it.sauronsoftware.jave.MultimediaInfo (format=mp3, duration=350600, video=null, audio=it.sauronsoftware.jave.AudioInfo (decoder=mp3, samplingRate=44100, channels=2, bitRate=192))
String file5 = "C:/Users/ddp/Desktop/aa/2.mp3";
//10.43==it.sauronsoftware.jave.MultimediaInfo (format=mp3, duration=273500, video=null, audio=it.sauronsoftware.jave.AudioInfo (decoder=mp3, samplingRate=44100, channels=2, bitRate=320))
String file6 = "C:/Users/ddp/Desktop/aa/3.mp3";
//4.84==it.sauronsoftware.jave.MultimediaInfo (format=mp3, duration=317000, video=null, audio=it.sauronsoftware.jave.AudioInfo (decoder=mp3, samplingRate=44100, channels=2, bitRate=128))
String file7 = "C:/Users/ddp/Desktop/aa/4.mp3";
//4.84==it.sauronsoftware.jave.MultimediaInfo (format=mp3, duration=317000, video=null, audio=it.sauronsoftware.jave.AudioInfo (decoder=mp3, samplingRate=44100, channels=2, bitRate=128))
String file8 = "C:/Users/ddp/Desktop/aa/5.mp3";
//3.82==it.sauronsoftware.jave.MultimediaInfo (format=mp3, duration=250000, video=null, audio=it.sauronsoftware.jave.AudioInfo (decoder=mp3, samplingRate=44100, channels=2, bitRate=128))
String file9 = "C:/Users/ddp/Desktop/aa/6.mp3";
//4.84==it.sauronsoftware.jave.MultimediaInfo (format=mp3, duration=317000, video=null, audio=it.sauronsoftware.jave.AudioInfo (decoder=mp3, samplingRate=44100, channels=2, bitRate=128))
String file10 = "C:/Users/ddp/Desktop/aa/7.mp3";
//10.43==it.sauronsoftware.jave.MultimediaInfo (format=mp3, duration=273500, video=null, audio=it.sauronsoftware.jave.AudioInfo (decoder=mp3, samplingRate=44100, channels=2, bitRate=320))
String file11 = "C:/Users/ddp/Desktop/aa/8.mp3";
//10.43==it.sauronsoftware.jave.MultimediaInfo (format=mp3, duration=273500, video=null, audio=it.sauronsoftware.jave.AudioInfo (decoder=mp3, samplingRate=44100, channels=2, bitRate=320))
String file12 = "C:/Users/ddp/Desktop/aa/9.mp3";
//9.33==it.sauronsoftware.jave.MultimediaInfo (format=mp3, duration=244400, video=null, audio=it.sauronsoftware.jave.AudioInfo (decoder=mp3, samplingRate=44100, channels=2, bitRate=320))
String file13 = "C:/Users/ddp/Desktop/aa/9(0).mp3";
String file14 = "C:/Users/ddp/Desktop/aa/qjhy_hh.mp3";
//0.08==it.sauronsoftware.jave.MultimediaInfo (format=mp3, duration=5000, video=null, audio=it.sauronsoftware.jave.AudioInfo (decoder=mp3, samplingRate=48000, channels=2, bitRate=128))
String file15 = "C:/Users/ddp/Desktop/aa/qjhy_jq.mp3";
//0.02==it.sauronsoftware.jave.MultimediaInfo (format=mp3, duration=5400, video=null, audio=it.sauronsoftware.jave.AudioInfo (decoder=mp3, samplingRate=16000, channels=1, bitRate=24))
String file16 = "C:/Users/ddp/Desktop/aa/Sleep Away.mp3";
//4.62==it.sauronsoftware.jave.MultimediaInfo (format=mp3, duration=201700, video=null, audio=it.sauronsoftware.jave.AudioInfo (decoder=mp3, samplingRate=44100, channels=2, bitRate=192))
String file17 = "C:/Users/ddp/Desktop/aa/初见.mp3";
//4.07==it.sauronsoftware.jave.MultimediaInfo (format=mp3, duration=266500, video=null, audio=it.sauronsoftware.jave.AudioInfo (decoder=mp3, samplingRate=44100, channels=2, bitRate=128))
String file18 = "C:/Users/ddp/Desktop/aa/周笔畅 - 岁月神偷.mp3";
//3.82==it.sauronsoftware.jave.MultimediaInfo (format=mp3, duration=250000, video=null, audio=it.sauronsoftware.jave.AudioInfo (decoder=mp3, samplingRate=44100, channels=2, bitRate=128))
Long start = new Date().getTime();
String outFile1 = testCompressMp3Samll(file15, 128, 44100);
Long end = new Date().getTime();
System.out.println("花费时长:"+ (end - start));
ReadFileUtils readFileUtils1 = new ReadFileUtils(new File(outFile1));
System.out.println(readFileUtils1.getFileSizeToMB() + "==" + readFileUtils1.m);
Long start1 = new Date().getTime();
String outFile = testCompressMp3Samll(file2, 128, 44100);
Long end1 = new Date().getTime();
System.out.println("花费时长:"+ (end1 - start1));
ReadFileUtils readFileUtils = new ReadFileUtils(new File(outFile));
System.out.println(readFileUtils.getFileSizeToMB() + "==" + readFileUtils.m);
//String outFile1 = testCompressMp3Samll(file6, 128, 44100);
//ReadFileUtils readFileUtils1 = new ReadFileUtils(new File(outFile1));
//System.out.println(readFileUtils1.m);
String finalFile = "C:/Users/ddp/Desktop/aa/final6.mp3";
files.add(outFile1);
files.add(outFile);
Long start3 = new Date().getTime();
packageMp3(finalFile, files);
Long end3 = new Date().getTime();
System.out.println("合并时长:"+ (end3 - start3));
ReadFileUtils readFileUtils3 = new ReadFileUtils(new File(finalFile));
System.out.println(readFileUtils3.getFileSizeToMB() + "==" + readFileUtils3.m);
ReadFileUtils readFileUtils2 = new ReadFileUtils(new File(file13));
System.out.println(readFileUtils2.getFileSizeToMB() + "==" + readFileUtils2.m);
}
/**
* 对文件进行转换处理
* @param filePaths
* @throws Exception
*/
public static void changeMp3(List<String> filePaths) throws Exception {
if(CollectionUtils.isEmpty(filePaths)) return;
//获取mp3中的最多的samplingRate,如果是一个文件不转换,如果文件的samplingRate一致不转换
if(filePaths.size() == 1) return;
Map<Integer, Integer> sampLingRateNums = new HashMap<>();
//节目最大的sampLingRate
Integer maxSampLingRate = 0;
//最大文件的大小
Long maxFileSize = 0L;
for (String file : filePaths) {
ReadFileUtils readFileUtils = new ReadFileUtils(new File(file));
Long fileSize = readFileUtils.getFileSize();
MultimediaInfo m = readFileUtils.m;
AudioInfo audioInfo = m.getAudio();
int sampLingRate = audioInfo.getSamplingRate();
if(fileSize > maxFileSize) {
maxFileSize = fileSize;
maxSampLingRate = sampLingRate;
}
Integer num = sampLingRateNums.get(sampLingRate);
if(num == null) {
num = 0;
}
sampLingRateNums.put(sampLingRate, ++num);
}
//如果是一个文件不转换,如果文件的samplingRate一致不转换
Set<Integer> sampLingRates = sampLingRateNums.keySet();
if(CollectionUtils.isEmpty(sampLingRates) || sampLingRates.size() == 1) return;
if(sampLingRates.size() != filePaths.size()) {//有节目相同时
//获取samplingRate最多的samplingRate值
Integer maxSampLingRateNum = 0;
for (Integer integer : sampLingRateNums.keySet()) {
Integer sampLingRateNum = sampLingRateNums.get(integer);
if(sampLingRateNum == null) continue;
if(sampLingRateNum > maxSampLingRateNum) {
maxSampLingRateNum = sampLingRateNum;
maxSampLingRate = integer;
}
}
}
//循环判断文件是否需要转换
for (int i = 0; i < filePaths.size(); i++) {
String file = filePaths.get(i);
ReadFileUtils readFileUtils = new ReadFileUtils(new File(file));
MultimediaInfo m = readFileUtils.m;
AudioInfo audioInfo = m.getAudio();
int bitRate = audioInfo.getBitRate();
int sampLingRate = audioInfo.getSamplingRate();
//为最多的samplingRate时不处理
if(sampLingRate == maxSampLingRate) continue;
try {
String oupPutFile = testCompressMp3Samll(file, bitRate, maxSampLingRate);
//list中删除原来的数据,添加新的文件数据
filePaths.set(i, oupPutFile);
} catch (Exception e) {
throw new Exception("转换采样率失败");
}
}
}
/**
* 转换文件采样率
* @param inputFilePath
* @param bitRate
* @param samplingRate
* @throws Exception
*/
public static String testCompressMp3Samll(String inputFilePath, int bitRate, int samplingRate) throws Exception{
AudioAttributes audio = new AudioAttributes();
audio.setCodec("libmp3lame");
audio.setBitRate(bitRate);//设置比特率
audio.setChannels(new Integer(2));
audio.setSamplingRate(samplingRate);//采样率
EncodingAttributes attrs = new EncodingAttributes();
attrs.setFormat("mp3");//设置格式,我的文件原本就是mp3格式的
attrs.setAudioAttributes(audio);
//attrs.setDuration(360f); // 设置截取的时长
Encoder encoder = new Encoder();
File inputFile = new File(inputFilePath);
String outPutFile = inputFile.getParent() + File.separator + "changeMp3_" + inputFile.getName();
encoder.encode(inputFile,new File(outPutFile), attrs);
return outPutFile;
}
public static void uniteAMRFile(String[] partsPaths, String unitedFilePath) {
try {
File unitedFile = new File(unitedFilePath);
FileOutputStream fos = new FileOutputStream(unitedFile);
RandomAccessFile ra = null;
for (int i = 0; i < partsPaths.length; i++) {
ra = new RandomAccessFile(partsPaths[i], "r");
if (i != 0) {
ra.seek(6);
}
byte[] buffer = new byte[1024 * 8];
int len = 0;
while ((len = ra.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
}
ra.close();
fos.close();
} catch (Exception e) {
}
}
public static void packageMp3(String fileOutPath, List<String> filePaths) throws Exception {
if (StringUtils.isEmpty(fileOutPath))
throw new Exception("mp3节目文件存储地址为空");
if (CollectionUtils.isEmpty(filePaths))
throw new Exception("素材文件列表为空");
//changeMp3(filePaths);
FileOutputStream fos = new FileOutputStream(fileOutPath);
String[] fileList = new String[filePaths.size()];
// 需要合并的素材的集合
ArrayList<FileInputStream> list = new ArrayList<>();
for (String string : filePaths) {
FileInputStream fistream1 = new FileInputStream(string);
list.add(fistream1);
}
filePaths.toArray(fileList);
//uniteAMRFile(fileList, fileOutPath);
Iterator<FileInputStream> it = list.iterator();
SequenceInputStream sis = new SequenceInputStream(new Enumeration<FileInputStream>() {
@Override
public boolean hasMoreElements() {
return it.hasNext();
}
@Override
public FileInputStream nextElement() {
return it.next();
}
});
byte buff[] = new byte[1024];
int length = 0;
while ((length = sis.read(buff)) != -1) {
fos.write(buff, 0, length);
}
fos.close();
sis.close();
}
}