对Mp3文件剪切,剪切速度非常非常快。不到一秒
/**\
* @param inputPath 原音乐路径
* @param outputPath 新音乐路径
* @param start 剪裁开始位置 单位毫秒
* @param end 剪裁结束位置 单位毫秒
* @return
*/
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public boolean clip(String inputPath, String outputPath, int start, int end){
MediaExtractor extractor = null;
BufferedOutputStream outputStream = null;
try {
extractor = new MediaExtractor();
extractor.setDataSource(inputPath);
int track = getAudioTrack(extractor);
if(track < 0){
return false;
}
//选择音频轨道
extractor.selectTrack(track);
outputStream = new BufferedOutputStream(
new FileOutputStream(outputPath), SAMPLE_SIZE);
start = start * 1000;
end = end * 1000;
//跳至开始裁剪位置
extractor.seekTo(start, MediaExtractor.SEEK_TO_PREVIOUS_SYNC);
while (true){
ByteBuffer buffer = ByteBuffer.allocate(SAMPLE_SIZE);
int sampleSize = extractor.readSampleData(buffer, 0);
long timeStamp = extractor.getSampleTime();
if(timeStamp > end && timeStamp - end >= 1000000){
Toast.makeText(CutMusicActivity.this,"剪切完毕",Toast.LENGTH_SHORT).show();
break;
}
if(sampleSize <= 0){
break;
}
byte[] buf = new byte[sampleSize];
buffer.get(buf, 0, sampleSize);
//写入文件
outputStream.write(buf);
//音轨数据往前读
extractor.advance();
}
} catch (IOException e) {
e.printStackTrace();
}finally {
if(extractor != null){
extractor.release();
}
if(outputStream != null){
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return true;
}
/**
* 获取音频数据轨道
* @param extractor
* @return
*/
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
private static int getAudioTrack(MediaExtractor extractor) {
for(int i = 0; i < extractor.getTrackCount(); i++){
MediaFormat format = extractor.getTrackFormat(i);
String mime = format.getString(MediaFormat.KEY_MIME);
if(mime.startsWith("audio")){
return i;
}
}
return -1;
}
两个MP3文件合并
/**
* @param path Mp301路径
* @param path1 Mp302路径
* @param compoundName 合成完毕的路径
* @return
* @throws IOException
*/
public static String heBingMp3(String path, String path1, String compoundName) throws IOException {
String fenLiData = fenLiData(path);
String fenLiData2 = fenLiData(path1);
File file = new File(fenLiData);
File file1 = new File(fenLiData2);
//生成处理后的文件
File file2 = new File(compoundName);
FileInputStream in = new FileInputStream(file);
FileOutputStream out = new FileOutputStream(file2);
byte bs[] = new byte[1024 * 4];
int len = 0;
//先读第一个
while ((len = in.read(bs)) != -1) {
out.write(bs, 0, len);
}
in.close();
out.close();
//再读第二个
in = new FileInputStream(file1);
out = new FileOutputStream(file2, true);//在文件尾打开输出流
byte bs1[] = new byte[1024 * 4];
while ((len = in.read(bs1)) != -1) {
out.write(bs1, 0, len);
}
in.close();
out.close();
if (file.exists()) file.delete();
if (file1.exists()) file1.delete();
return file2.getAbsolutePath();
}
private static String fenLiData(String path) throws IOException {
File file = new File(path);// 原文件
File file1 = new File(path + "01");// 分离ID3V2后的文件,这是个中间文件,最后要被删除
File file2 = new File(path + "001");// 分离id3v1后的文件
RandomAccessFile rf = new RandomAccessFile(file, "rw");// 随机读取文件
FileOutputStream fos = 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();
}