Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android剪切合並MP3音樂

android剪切合並MP3音樂

編輯:關於Android編程

以前做過一個音樂播放器,基本的功能都有,什麼在線播放,下載,歌詞顯示,分享等。下面是剪切合並代碼,算法也有,結合算法才好看代碼

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);
		// 分離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();
	}

	/**
	 * 分離出數據幀每一幀的大小並存在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. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved