以前做过一个音乐播放器,基本的功能都有,什么在线播放,下载,歌词显示,分享等。下面是剪切合并代码,算法也有,结合算法才好看代码

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 list = CaoZuoMp3Utils.initMP3Frame
                                (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);

因为是耗时操作所以需要放在线程中进行。


更多相关文章

  1. Android四大组件之activity之间带数据跳转
  2. 编译Irrlicht On Android(1)
  3. Android(安卓)9.0 HTTP请求报错
  4. android下的jni
  5. No compatible targets were found....
  6. SQLite一次性读取过多记录会造成内存溢出OutOfMemoryError
  7. Android(安卓)Widget开发
  8. Android—将Bitmap图片保存到SD卡目录下或者指定目录
  9. Android之应用中执行Linux命令

随机推荐

  1. Android(安卓)GreenDao数据库—基础详解
  2. Android(安卓)- TextView 实现部分文本点
  3. Android(安卓)Fragment实践之简易的新闻
  4. Android(安卓)自定义dialogfragment
  5. 使用一:ButterKnife
  6. Android.text.TextUtils类
  7. Android(安卓)Opengl es 写字 笔记(三)
  8. onConfigurationChanged
  9. Android(安卓)Sqlite
  10. 其它