2019-04-07 音頻文件合并

兩個(gè)wav文件合并過(guò)程

主要的思路 :wav格式的音頻文件有一定的格式:head+數(shù)據(jù)字節(jié)數(shù)組!兩個(gè)wav格式的文件,消息頭中主要文件大小區(qū)間和數(shù)據(jù)量大小區(qū)間不一樣,以及具體的數(shù)據(jù)字節(jié)數(shù)組不一樣而已! 主要生成兩個(gè)文件量的文件head+兩個(gè)音頻文件的數(shù)據(jù)字節(jié)數(shù)組!

具體解說(shuō)wav 和 RIFF文件格式:詳情參照

具體的代碼過(guò)程:

多個(gè)文件合并一個(gè)文件
/**
 * 合并文件2
 * @param fileList
 */
public static void fixFils2(List<File> fileList,String fileOutPath){
    //先進(jìn)行獲取文件長(zhǎng)度 和音頻文件長(zhǎng)度 寫(xiě)入到Head byte數(shù)組中!
    long []length=new long[4];
    long totalLength=0;
    for (int i=0;i<fileList.size();++i) {
        length[i]=fileList.get(i).length()-44;//每個(gè)文件長(zhǎng)度-44
        totalLength+=length[i];
    }
    //設(shè)置總長(zhǎng)度:
    ByteBuffer byteBuffer=ByteBuffer.allocate(4);//整型為4個(gè)字節(jié)
    byteBuffer.putInt(Integer.parseInt(totalLength+"")+36);
    byte []fileLength=byteBuffer.array();//獲取文件長(zhǎng)度

    ByteBuffer byteBuffer1=ByteBuffer.allocate(4);
    byteBuffer1.putInt(Integer.parseInt(totalLength+""));
    byte []dataLength=byteBuffer1.array();//音頻數(shù)據(jù)長(zhǎng)度

    fileLength = reverse(fileLength);  //數(shù)組反轉(zhuǎn)
    dataLength = reverse(dataLength);

    byte []head=new byte[44];
    ByteArrayOutputStream byteArrayOutputStream=new ByteArrayOutputStream();
    int len=-1;
    byte []buffer=new byte[1024];
    //進(jìn)行獲取頭部信息:
    try {
        for (int i=0;i<fileList.size();++i) {
            //
            FileInputStream fileInputStream=new FileInputStream(fileList.get(i));
            if(i==0){
                //讀取第一個(gè)文件頭的信息
                fileInputStream.read(head,0,head.length);
                for(int j=0; j<4; j++){  //4代表一個(gè)int占用字節(jié)數(shù)
                    head[j+4] = fileLength[j];  //替換原頭部信息里的文件長(zhǎng)度
                    head[j+40] = dataLength[j];  //替換原頭部信息里的數(shù)據(jù)長(zhǎng)度
                }
                //先將頭文件 寫(xiě)進(jìn)去!
                byteArrayOutputStream.write(head,0,head.length);
                while ((len = fileInputStream.read(buffer, 0, buffer.length)) != -1) {
                    byteArrayOutputStream.write(buffer,0,len);
                }
                fileInputStream.close();
            }else{
                fileInputStream.read(buffer,0,44);
                while ((len = fileInputStream.read(buffer, 0, buffer.length)) != -1) {
                    byteArrayOutputStream.write(buffer,0,len);
                }
                fileInputStream.close();
            }
        }

        //進(jìn)行寫(xiě)出文件:
        FileOutputStream fileOutputStream=new FileOutputStream(fileOutPath);
        byteArrayOutputStream.writeTo(fileOutputStream);
        fileOutputStream.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}


將一個(gè)wav文件切成多個(gè)wav文件: 主要確定切割時(shí)間的范圍,解析到對(duì)應(yīng)區(qū)間的數(shù)據(jù)量,跳轉(zhuǎn)間隔值將head的文件大小和音頻數(shù)據(jù)量改為對(duì)應(yīng)切割小文件的數(shù)據(jù)量(由時(shí)間-->數(shù)據(jù)量):


剪切過(guò)程

  /**
 * 截取wav音頻文件
 * @param start  截取開(kāi)始時(shí)間(秒)
 * @param end  截取結(jié)束時(shí)間(秒)
 *
 * return  截取成功返回true,否則返回false
 */
public static boolean cut(String sourcefile, String targetfile, int start, int end) {
    try{
        if(!sourcefile.toLowerCase().endsWith(".wav") || !targetfile.toLowerCase().endsWith(".wav")){
            return false;
        }
        File wav = new File(sourcefile);
        if(!wav.exists()){
            return false;
        }
        long t1 = getTimeLen(wav);  //總時(shí)長(zhǎng)(秒)
        if(start<0 || end<=0 || start>=t1 || end>t1 || start>=end){
            return false;
        }
        FileInputStream fis = new FileInputStream(wav);
        long wavSize = wav.length()-44;  //音頻數(shù)據(jù)大小(44為128kbps比特率wav文件頭長(zhǎng)度)
        long splitSize = (wavSize/t1)*(end-start);  //截取的音頻數(shù)據(jù)大小
        long skipSize = (wavSize/t1)*start;  //截取時(shí)跳過(guò)的音頻數(shù)據(jù)大小
        int splitSizeInt = Integer.parseInt(String.valueOf(splitSize));
        int skipSizeInt = Integer.parseInt(String.valueOf(skipSize));

        ByteBuffer buf1 = ByteBuffer.allocate(4);  //存放文件大小,4代表一個(gè)int占用字節(jié)數(shù)
        buf1.putInt(splitSizeInt+36);  //放入文件長(zhǎng)度信息
        byte[] flen = buf1.array();  //代表文件長(zhǎng)度

        ByteBuffer buf2 = ByteBuffer.allocate(4);  //存放音頻數(shù)據(jù)大小,4代表一個(gè)int占用字節(jié)數(shù)
        buf2.putInt(splitSizeInt);  //放入數(shù)據(jù)長(zhǎng)度信息
        byte[] dlen = buf2.array();  //代表數(shù)據(jù)長(zhǎng)度
        System.out.println("flen length:"+flen.length+".....dlen length:"+dlen.length);
        flen = reverse(flen);  //數(shù)組反轉(zhuǎn)
        dlen = reverse(dlen);
        byte[] head = new byte[44];  //定義wav頭部信息數(shù)組
        fis.read(head, 0, head.length);  //讀取源wav文件頭部信息
        for(int i=0; i<4; i++){  //4代表一個(gè)int占用字節(jié)數(shù)
            head[i+4] = flen[i];  //替換原頭部信息里的文件長(zhǎng)度
            head[i+40] = dlen[i];  //替換原頭部信息里的數(shù)據(jù)長(zhǎng)度
        }
        byte[] fbyte = new byte[splitSizeInt+head.length];  //存放截取的音頻數(shù)據(jù)
        for(int i=0; i<head.length; i++){  //放入修改后的頭部信息
            fbyte[i] = head[i];
        }
        byte[] skipBytes = new byte[skipSizeInt];  //存放截取時(shí)跳過(guò)的音頻數(shù)據(jù)
        fis.read(skipBytes, 0, skipBytes.length);  //跳過(guò)不需要截取的數(shù)據(jù)
        fis.read(fbyte, head.length, fbyte.length-head.length);  //讀取要截取的數(shù)據(jù)到目標(biāo)數(shù)組
        fis.close();

        File target = new File(targetfile);
        if(target.exists()){  //如果目標(biāo)文件已存在,則刪除目標(biāo)文件
            target.delete();
        }
        FileOutputStream fos = new FileOutputStream(target);
        fos.write(fbyte);
        fos.flush();
        fos.close();
    }catch(IOException e){
        e.printStackTrace();
        return false;
    }
    return true;
}

/**
 * 獲取音頻文件總時(shí)長(zhǎng)
 * @return
 */
public static long getTimeLen(File file){
    long tlen = 0;
    if(file!=null && file.exists()){
        Encoder encoder = new Encoder();
        try {
            MultimediaInfo m = encoder.getInfo(file);
            long ls = m.getDuration();
            tlen = ls/1000;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    return tlen;
}

/**
 * 數(shù)組反轉(zhuǎn)
 * @param array
 */
public static byte[] reverse(byte[] array){
    byte temp;
    int len=array.length;
    for(int i=0;i<len/2;i++){
        temp=array[i];
        array[i]=array[len-1-i];
        array[len-1-i]=temp;
    }
    return array;
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容