android剪切合并MP3音乐
以前做过一个音乐播放器,基本的功能都有,什么在线播放,下载,歌词显示,分享等。下面是剪切合并代码,算法也有,结合算法才好看代码
package com.cdu.hhmusic.utils;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.RandomAccessFile;import java.util.ArrayList;import java.util.List;/** * 使用注意事项 * @作者 胡楠启 * 在android中操作肯定需要操作SD卡的权限的。 *调用顺序: *1、fenLiData//只要调用了它就会产生中间文件 *2、initMP3Frame *3、CutingMp3 *4、在调用端,切割完毕后删除中间产生的垃圾文件 *String fenLiData = CutingMp3.fenLiData(str1); *File file=new File(fenLiData); *if(file.exists())file.delete(); *原因是在工具端删除中间文件时,这个删除失败。懒得继续画精力去找 ,所以必须在调用端切割完毕后删除, *一避免垃圾文件占用内存 */public class CaoZuoMp3Utils {/** * 返回分离出MP3文件中的数据帧的文件路径 * * @作者 胡楠启 * */public 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);// 分离ID3v2if (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 {// 否则完全复制内容至file2FileOutputStream 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();}/** * 分离出数据帧每一帧的大小并存在list数组里面 *失败则返回空 * @param path * @return * @throws IOException */public static List initMP3Frame(String path) {File file = new File(path);List list = new ArrayList<>();/*int framSize=0;RandomAccessFile rad = new RandomAccessFile(file, "rw");byte[] head = new byte[4];rad.seek(framSize);rad.read(head);int bitRate = getBitRate((head[2] >> 4) & 0x0f) * 1000;int sampleRate = getsampleRate((head[2] >> 2) & 0x03);int paing = (head[2] >> 1) & 0x01;int len = 144 * bitRate / sampleRate + paing;for(int i=0,lens=(int)(file.length())/len;i> 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;}/** * 返回切割后的MP3文件的路径 返回null则切割失败 开始时间和结束时间的整数部分都是秒,以秒为单位 * * * @param list * @param startTime * @param stopTime * @return * @throws IOException */public static String CutingMp3(String path, String name, List list, double startTime, double stopTime)throws IOException {File file = new File(path); String luJing="/storage/emulated/0/"+"HH音乐播放器/切割/";File f=new File(luJing);f.mkdirs();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 raf = new RandomAccessFile(file, "rw");raf.seek(seekStart);File file1 = new File(luJing + name + "(HH切割).mp3");FileOutputStream out = new FileOutputStream(file1);byte[] bs=new byte[(int)(seekStop-seekStart)];raf.read(bs);out.write(bs);raf.close();out.close();File filed=new File(path);if(filed.exists()) filed.delete();return file1.getAbsolutePath();}}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];}/** * 返回合并后的文件的路径名,默认放在第一个文件的目录下 * @param path * @param path1 * @param name * @return * @throws IOException */public static String heBingMp3(String path,String path1,String name) throws IOException{String fenLiData = fenLiData(path);String fenLiData2 = fenLiData(path1);File file=new File(fenLiData);File file1=new File(fenLiData2);String luJing="/storage/emulated/0/"+"HH音乐播放器/合并/";File f=new File(luJing);f.mkdirs();//生成处理后的文件File file2=new File(luJing+name+"(HH合并).mp3");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);//在文件尾打开输出流len=0;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();}}
作用就是可以剪切合并音乐,各种路劲需要根据实际情况修改。 用法:剪切
String fenLiData = CaoZuoMp3Utils.fenLiData(str);
final List
(fenLiData);
if(list==null){
han.post(new Runnable() {
@Override
public void run() {
Toast.makeText(Cut_Mp3_Activity.this, "剪切失败",
Toast.LENGTH_SHORT).show();
prodiialog.dismiss();
}
});
}else{
final String path = CaoZuoMp3Utils.CutingMp3(fenLiData, cuting_name,
list,
start, stop);
final File file = new File(fenLiData);
合并:
final String s = CaoZuoMp3Utils.heBingMp3(path, path1, name);
因为是耗时操作所以需要放在线程中进行。
更多相关文章
- Android四大组件之activity之间带数据跳转
- 编译Irrlicht On Android(1)
- Android(安卓)9.0 HTTP请求报错
- android下的jni
- No compatible targets were found....
- SQLite一次性读取过多记录会造成内存溢出OutOfMemoryError
- Android(安卓)Widget开发
- Android—将Bitmap图片保存到SD卡目录下或者指定目录
- Android之应用中执行Linux命令