【JAVA】将多个WAV或MP3文件合成一个文件

10 篇文章 1 订阅
8 篇文章 0 订阅

JAVA将多个WAV文件合成一个文件,或者多个mp3合成一个文件

话不多说

直接上源码

使用:

 public static void main(String[] args) throws IOException {
        String out = "D:\\new.wav";
        String filepath1 = "D:\\1.wav";
        String filepath2 = "D:\\2.wav";
        String filepath3 = "D:\\3.wav";
        String filepath4 = "D:\\4.wav";
        String filepath5 = "D:\\5.wav";
        WavCompose wav = new WavCompose();
        wav.addWav(out, filepath1, filepath2, filepath3, filepath4, filepath5);
        System.out.println("合成完毕");
    }

全部源码:

import java.io.*;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;

/**
 * Wav文件多合一
 *
 * @author yujing 2020年6月15日15:43:20
 */
public class WavCompose {
    private int headLength1 = 0;
    private int headLength2 = 0;

    public static int byteArrayToInt(byte[] b) {
        return b[3] & 0xFF | (b[2] & 0xFF) << 8 | (b[1] & 0xFF) << 16 | (b[0] & 0xFF) << 24;
    }

    public static byte[] intToByteArray(int a) {
        return new byte[]{(byte) ((a >> 24) & 0xFF), (byte) ((a >> 16) & 0xFF), (byte) ((a >> 8) & 0xFF), (byte) (a & 0xFF)};
    }

    //字节翻转
    public static byte[] byteToByte(byte[] a) {
        if (a.length == 4)
            return new byte[]{a[3], a[2], a[1], a[0]};
        return null;
    }

    //更改文件头
    private void updateFileHead(String out, boolean ifUpdate) throws IOException {
        RandomAccessFile raf = new RandomAccessFile(out, "rw");
        //long fileLength = raf.length();
        // 打开一个文件通道
        FileChannel channel = raf.getChannel();
        // 映射文件中的某一部分数据以读写模式到内存中
        MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_WRITE, 0, 44);// 文件头长度
        // 修改头部文件
        if (ifUpdate) {
            byte[] head1 = byteToByte(intToByteArray(headLength1));
            byte[] head2 = byteToByte(intToByteArray(headLength2));
            // 进行修改操作
            buffer.put(4, head1[0]);
            buffer.put(5, head1[1]);
            buffer.put(6, head1[2]);
            buffer.put(7, head1[3]);
            buffer.put(40, head2[0]);
            buffer.put(41, head2[1]);
            buffer.put(42, head2[2]);
            buffer.put(43, head2[3]);
            buffer.force();//强制输出,在buffer中的改动生效到文件
        } else {
            //noinspection ConstantConditions
            headLength1 = headLength1 + byteArrayToInt(byteToByte(new byte[]{buffer.get(4), buffer.get(5), buffer.get(6), buffer.get(7)}));;
            //noinspection ConstantConditions
            headLength2 = headLength2 + byteArrayToInt(byteToByte(new byte[]{buffer.get(40), buffer.get(41), buffer.get(42), buffer.get(43)}));;
        }
        buffer.clear();
        channel.close();
        raf.close();
    }

    /**
     * 将多个wav合成一个新的wav
     *
     * @param out 输出文件
     * @param in  输入文件数组
     * @throws IOException
     */
    public void addWav(String out, String... in) throws IOException {
        File outFile = new File(out);
        if (!outFile.getParentFile().exists())
            outFile.getParentFile().mkdirs();
        if (!outFile.exists())
            outFile.createNewFile();
        OutputStream os = new FileOutputStream(outFile);// 追加
        for (int i = 0; i < in.length; i++) {
            File file1 = new File(in[i]);
            if (!file1.exists())
                continue;
            //System.out.println(in[i] + "文件长度:" + file1.length());
            InputStream is = new FileInputStream(file1);
            if (i != 0) {
                //noinspection ResultOfMethodCallIgnored
                is.skip(44);// 跳过后面的.wav的文件头
            }
            byte[] tempBuffer = new byte[1024];
            int nRed = 0;
            // 将wav全部内容复制到out.wav
            while ((nRed = is.read(tempBuffer)) != -1) {
                os.write(tempBuffer, 0, nRed);
                os.flush();
            }
            is.close();
        }
        os.close();
        // 到此完成了in数组全部wav合并成out.wav,但是此时播放out.wav,音频内容仍然只是第一个音频的内容,所以还要更改out.wav的文件头
        for (String s : in) updateFileHead(s, false);
        updateFileHead(out, true);//头部合成
    }

    public static void main(String[] args) throws IOException {
        String out = "D:\\new.wav";
        String filepath1 = "D:\\1.wav";
        String filepath2 = "D:\\2.wav";
        String filepath3 = "D:\\3.wav";
        String filepath4 = "D:\\4.wav";
        String filepath5 = "D:\\5.wav";
        WavCompose wav = new WavCompose();
        wav.addWav(out, filepath1, filepath2, filepath3, filepath4, filepath5);
        System.out.println("合成完毕");
    }
}

我测试的音频文件是,Audition保存的,采样率44100HZ,16位整数,波形未压缩。
转换有问题的同仁们,你们可以先用AU转换一下源文件。

或者先转换成mp3,再合成。

转换成mp3:

//以下代码需要引入jave-1.0.2.jar
Long time1 = System.currentTimeMillis();
AudioAttributes audio = new AudioAttributes();
audio.setCodec("libmp3lame");
audio.setBitRate(64000);//设置比特率
audio.setSamplingRate(44100);
EncodingAttributes attrs = new EncodingAttributes();
attrs.setFormat("mp3");//设置格式
attrs.setAudioAttributes(audio);
//attrs.setDuration(360f); // 设置截取的时长
Encoder encoder = new Encoder();
encoder.encode(new File("D:\\CloudMusic\\1.wav"),new File("D:\\CloudMusic\\1.mp3"), attrs);
System.out.println("消耗:"+(System.currentTimeMillis()-time1)+"ms");

再合成mp3:

 public static void main(String[] args) throws IOException {
        String out = "D:\\new.mp3";
        String filepath1 = "D:\\1.mp3";
        String filepath2 = "D:\\2.mp3";
        String filepath3 = "D:\\3.mp3";
        String filepath4 = "D:\\4.mp3";
        String filepath5 = "D:\\5.mp3";
        WavCompose wav = new WavCompose();
        wav.addWav(out, filepath1, filepath2, filepath3, filepath4, filepath5);
        System.out.println("合成完毕");
    }
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值