首页 > 编程 > Java > 正文

Java实现多个wav文件合成一个的方法示例

2019-11-26 09:01:15
字体:
来源:转载
供稿:网友

本文实例讲述了Java实现多个wav文件合成一个的方法。分享给大家供大家参考,具体如下:

前面一篇介绍了java切割wav音频文件的方法,这里再给出合并多个wav音频文件的方法。

package com.cmos.nomsapp.utils.wavmeger;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.RandomAccessFile;import java.nio.ByteBuffer;import java.nio.ByteOrder;import java.util.ArrayList;import java.util.List;/** * 获取wav头文件然后合并成单个wav * @author zcf * @date 2017-10-17 */public class WavMergeUtil {  /**   * meger多个wav   * @param inputs 多个wav   * @param output 要生成的wav   * @throws IOException   */  public static void mergeWav(File[] inputs, String output) throws IOException {    if (inputs.length < 1) {      return;    }    try(FileInputStream fis = new FileInputStream(inputs[0]);      FileOutputStream fos = new FileOutputStream(new File(output))){      byte[] buffer = new byte[1024 * 4];      int total = 0;      int count;      while ((count = fis.read(buffer)) > -1) {        fos.write(buffer, 0, count);        total += count;      }      fis.close();      for (int i = 1; i < inputs.length; i++) {        File file = inputs[i];        try(FileInputStream fisH = new FileInputStream(file)){          Header header = resolveHeader(fisH);          FileInputStream dataInputStream = header.dataInputStream;          while ((count = dataInputStream.read(buffer)) > -1) {            fos.write(buffer, 0, count);            total += count;          }        }      }      fos.flush();      fos.close();      FileInputStream fisHo = new FileInputStream(new File(output));      Header outputHeader = resolveHeader(fisHo);      outputHeader.dataInputStream.close();      try(RandomAccessFile res = new RandomAccessFile(output, "rw")){        res.seek(4);        byte[] fileLen = intToByteArray(total + outputHeader.dataOffset - 8);        res.write(fileLen, 0, 4);        res.seek(outputHeader.dataSizeOffset);        byte[] dataLen = intToByteArray(total);        res.write(dataLen, 0, 4);      }    }  }  /**   * 解析头部,并获得文件指针指向数据开始位置的InputStreram,记得使用后需要关闭   */  private static Header resolveHeader(FileInputStream fis) throws IOException {      byte[] byte4 = new byte[4];      byte[] buffer = new byte[2048];      int readCount = 0;      Header header = new Header();      fis.read(byte4);// RIFF      fis.read(byte4);      readCount += 8;      header.fileSizeOffset = 4;      header.fileSize = byteArrayToInt(byte4);      fis.read(byte4);// WAVE      fis.read(byte4);// fmt      fis.read(byte4);      readCount += 12;      int fmtLen = byteArrayToInt(byte4);      fis.read(buffer, 0, fmtLen);      readCount += fmtLen;      fis.read(byte4);// data or fact      readCount += 4;      if (isFmt(byte4, 0)) {// 包含fmt段        fis.read(byte4);        int factLen = byteArrayToInt(byte4);        fis.read(buffer, 0, factLen);        fis.read(byte4);// data        readCount += 8 + factLen;      }      fis.read(byte4);// data size      int dataLen = byteArrayToInt(byte4);      header.dataSize = dataLen;      header.dataSizeOffset = readCount;      readCount += 4;      header.dataOffset = readCount;      header.dataInputStream = fis;      return header;  }  private static boolean isRiff(byte[] bytes, int start) {    if (bytes[start + 0] == 'R' && bytes[start + 1] == 'I' && bytes[start + 2] == 'F' && bytes[start + 3] == 'F') {      return true;    } else {      return false;    }  }  private static boolean isFmt(byte[] bytes, int start) {    if (bytes[start + 0] == 'f' && bytes[start + 1] == 'm' && bytes[start + 2] == 't' && bytes[start + 3] == ' ') {      return true;    } else {      return false;    }  }  private static boolean isData(byte[] bytes, int start) {    if (bytes[start + 0] == 'd' && bytes[start + 1] == 'a' && bytes[start + 2] == 't' && bytes[start + 3] == 'a') {      return true;    } else {      return false;    }  }  /**   * 将int转化为byte[]   */  private static byte[] intToByteArray(int data) {    return ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(data).array();  }  /**   * 将short转化为byte[]   */  private static byte[] shortToByteArray(short data) {    return ByteBuffer.allocate(2).order(ByteOrder.LITTLE_ENDIAN).putShort(data).array();  }  /**   * 将byte[]转化为short   */  private static short byteArrayToShort(byte[] b) {    return ByteBuffer.wrap(b).order(ByteOrder.LITTLE_ENDIAN).getShort();  }  /**   * 将byte[]转化为int   */  private static int byteArrayToInt(byte[] b) {    return ByteBuffer.wrap(b).order(ByteOrder.LITTLE_ENDIAN).getInt();  }  /**   * 头部部分信息   */  static class Header {    public int fileSize;    public int fileSizeOffset;    public int dataSize;    public int dataSizeOffset;    public int dataOffset;    public FileInputStream dataInputStream;  }}

更多关于java算法相关内容感兴趣的读者可查看本站专题:《Java文件与目录操作技巧汇总》、《Java数据结构与算法教程》、《Java操作DOM节点技巧总结》和《Java缓存操作技巧汇总

希望本文所述对大家java程序设计有所帮助。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表