我正在开发一个Android项目,我想知道如何以编程方式在Android Studio中修整一首歌曲,我正在尝试使用 ffmpeg ,但我仍然无法将其嵌入码。
如果有任何用于修剪歌曲的代码,那将很有帮助。
答案 0 :(得分:0)
下面的示例是剪切和合并代码,您可以参考:
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;
/**
* Operating in android certainly requires SD card permissions.
*invoke sort:
*1、fenLiData//Whenever it is called, an intermediate file is generated
*2、initMP3Frame
*3、CutingMp3
*4、At the calling end, the garbage file generated in the middle is deleted after cutting
*String fenLiData = CutingMp3.fenLiData(str1);
*File file=new File(fenLiData);
*if(file.exists())file.delete();
*The reason is that the deletion failed when the intermediate file was deleted on the tool side. Too lazy to continue to draw energy to find, so must be in the call side after the end of the cutting delete, avoid garbage files occupying memory
*/
public class CaoZuoMp3Utils {
/**
* Returns the file path that separates the data frames in the MP3 file
*
*/
public static String fenLiData(String path) throws IOException {
File file = new File(path);// The original file
File file1 = new File(path + "01");// After the separation of ID3V2 file, this is an intermediate file, and finally to be deleted
File file2 = new File(path + "001");// Split id3v1 after the file
RandomAccessFile rf = new RandomAccessFile(file, "rw");// Random read file
FileOutputStream fos = new FileOutputStream(file1);
byte ID3[] = new byte[3];
rf.read(ID3);
String ID3str = new String(ID3);
// The separation of 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 {// Otherwise the file is copied completely
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 {// Otherwise, copy the contents completely to 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())// Delete intermediate files
{
file1.delete();
}
return file2.getAbsolutePath();
}
/**
* The size of each data frame is separated and stored in the list array
* Failure returns null
* @param path
* @return
* @throws IOException
*/
public static List<Integer> initMP3Frame(String path) {
File file = new File(path);
List<Integer> 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<lens;i++){
list.add(len);// Add the length of the data frame
}*/
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);// Add the length of the data frame
framSize += len;
}
return list;
}
/**
* The path that returns the MP3 file after cutting returns null. The integer part of the starting time and ending time of the cutting failure is seconds
*
*
* @param list
* @param startTime
* @param stopTime
* @return
* @throws IOException
*/
public static String CutingMp3(String path, String name,
List<Integer> list, double startTime, double stopTime)
throws IOException {
File file = new File(path);
String luJing="/storage/emulated/0/"+"HH music player/cut /";
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;// The location of the byte where the clipping begins
for (int i = 0; i < start; i++) {
seekStart += list.get(i);
}
long seekStop = 0;// The position of the byte that ends the clipping
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 cutting).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];
}
/**
* Returns the path name of the merged file, which is placed by default in the directory of the first file
* @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 music player/merge /";
File f=new File(luJing);
f.mkdirs();
//Generate the processed file
File file2=new File(luJing+name+"(HH merger).mp3");
FileInputStream in=new FileInputStream(file);
FileOutputStream out=new FileOutputStream(file2);
byte bs[]=new byte[1024*4];
int len=0;
//Read the first one first
while((len=in.read(bs))!=-1){
out.write(bs,0,len);
}
in.close();
out.close();
//Read the second one
in=new FileInputStream(file1);
out=new FileOutputStream(file2,true);//Open the output stream at the end of the file
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<Integer> list = CaoZuoMp3Utils.initMP3Frame(fenLiData);
if(list==null){
han.post(new Runnable() {
@Override
public void run() {
Toast.makeText(Cut_Mp3_Activity.this, "cut fail",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);
由于这是一项耗时的操作,因此需要在线程中完成。