mp3格式音频剪切方法,此方法不涉及音频解码格式转换等流程,只针对文件长度做裁剪。
public static StringclipAudio(String audioPath, String audioName, double startTime, double stopTime) {
if (TextUtils.isEmpty(audioPath) || TextUtils.isEmpty(audioName)) {
return null;
}
String separatePath =separateFile(audioPath);
if (TextUtils.isEmpty(separatePath)) {
return null;
}
List frames =getAudioFrame(separatePath);
if (frames ==null || frames.size() ==0) {
return null;
}
String clipAudioPath =clipFile(separatePath, audioName, frames, startTime, stopTime);
if (!TextUtils.isEmpty(clipAudioPath)) {
return clipAudioPath;
}
return null;
}
private static StringseparateFile(String path) {
try {
// 原文件
File file =new File(path);
// 分离ID3V2后的文件,这是个中间文件,最后要被删除
File file1 =new File(path +"01");
// 分离id3v1后的文件
File file2 =new File(path +"001");
RandomAccessFile rf =new RandomAccessFile(file, "rw");
FileOutputStreamfos =new FileOutputStream(file1);
byte ID3[] =new byte[3];
rf.read(ID3);
String ID3str =new String(ID3);
// 分离ID3v2
if (ID3str.equals("ID3")) {
rf.seek(6);
byte[] ID3size =new byte[4];
rf.read(ID3size);
int size1 = (ID3size[0] &0x7f) <<21;
int size2 = (ID3size[1] &0x7f) <<14;
int size3 = (ID3size[2] &0x7f) <<7;
int size4 = (ID3size[3] &0x7f);
int size = size1 + size2 + size3 + size4 +10;
rf.seek(size);
int lens =0;
byte[] bs =new byte[1024 *4];
while ((lens = rf.read(bs)) != -1) {
fos.write(bs, 0, lens);
}
fos.close();
rf.close();
}else {// 否则完全复制文件
int lens =0;
rf.seek(0);
byte[] bs =new byte[1024 *4];
while ((lens = rf.read(bs)) != -1) {
fos.write(bs, 0, lens);
}
fos.close();
rf.close();
}
RandomAccessFile raf = new RandomAccessFile(file1, "rw"); byte TAG[] =new byte[3];
raf.seek(raf.length() -128);
raf.read(TAG);
String tagstr =new String(TAG);
if (tagstr.equals("TAG")) {
FileOutputStream fs =new FileOutputStream(file2);
raf.seek(0);
byte[] bs =new byte[(int) (raf.length() -128)];
raf.read(bs);
fs.write(bs);
raf.close();
fs.close();
}else {
// 否则完全复制内容至file2
FileOutputStream fs =new FileOutputStream(file2);
raf.seek(0);
byte[] bs =new byte[1024 *4];
int len =0;
while ((len = raf.read(bs)) != -1) {
fs.write(bs, 0, len);
}
raf.close();
fs.close();
}
if (file1.exists()) {
file1.delete();
}
return file2.getAbsolutePath();
}catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* 获取帧
*/
private static ListgetAudioFrame(String path) {
File file =new File(path);
List list =new ArrayList<>();
int framSize =0;
RandomAccessFile rad =null;
try {
rad =new RandomAccessFile(file, "rw");
}catch (FileNotFoundException e) {
e.printStackTrace();
}
while (framSize < file.length()) {
byte[] head =new byte[4];
try {
rad.seek(framSize);
}catch (IOException e) {
e.printStackTrace();
}
try {
rad.read(head);
}catch (IOException e) {
e.printStackTrace();
}
int bitRate =getBitRate((head[2] >>4) &0x0f) *1000;
int sampleRate =getSampleRate((head[2] >>2) &0x03);
int paing = (head[2] >>1) &0x01;
if (bitRate ==0 || sampleRate ==0)return null;
int len =144 * bitRate / sampleRate + paing;
// 将数据帧的长度添加进来
list.add(len);
framSize += len;
}
return list;
}
private static StringclipFile(String path, String name, List list, double startTime, double stopTime) {
String audioFolder = Environment
.getExternalStorageDirectory() +"/audio";
try {
File file =new File(path);
File folder =new File(audioFolder);
if (!folder.exists()) {
folder.mkdirs();
}
File nomedia =new File(audioFolder +"/.nomedia");
if (!nomedia.exists()) {
try {
nomedia.createNewFile();
}catch (Exception e) {
e.printStackTrace();
}
}
int start = (int) (startTime /0.026);
int stop = (int) (stopTime /0.026);
if ((start > stop) || (start <0) || (stop <0) || (stop > list.size())) {
return null;
}else {
long seekStart =0;
for (int i =0; i < start; i++) {
seekStart += list.get(i);
}
long seekStop =0;
for (int i =0; i < stop; i++) {
seekStop += list.get(i);
}
RandomAccessFile accessFile =new RandomAccessFile(file, "rw");
accessFile.seek(seekStart);
File audioFile =new File(folder +"/" + name +".mp3");
FileOutputStream outputStream =new FileOutputStream(audioFile);
byte[] bs =new byte[(int) (seekStop - seekStart)];
accessFile.read(bs);
outputStream.write(bs);
accessFile.close();
outputStream.close();
File filed =new File(path);
if (filed.exists())
filed.delete();
return audioFile.getAbsolutePath();
}
}catch (Exception e) {
e.printStackTrace();
}
return null;
}
private static int getBitRate(int i) {
int a[] = {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0};
return a[i];
}
private static int getSampleRate(int i) {
int a[] = {44100, 48000, 32000, 0};
return a[i];
}
网友评论