音乐MP3文件剪切 与 两个MP3文件合并

本文介绍了一种快速剪切MP3文件的方法,剪切速度极快,不到一秒即可完成。同时,还提供了两个MP3文件的合并方法,通过分离ID3标签,确保了音频数据的完整性和正确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对Mp3文件剪切,剪切速度非常非常快。不到一秒

    /**\
     * @param inputPath  原音乐路径
     * @param outputPath  新音乐路径
     * @param start  剪裁开始位置   单位毫秒
     * @param end   剪裁结束位置   单位毫秒
     * @return
     */
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    public boolean clip(String inputPath, String outputPath, int start, int end){
        MediaExtractor extractor = null;
        BufferedOutputStream outputStream = null;
        try {
            extractor = new MediaExtractor();
            extractor.setDataSource(inputPath);
            int track = getAudioTrack(extractor);
            if(track < 0){
                return false;
            }
            //选择音频轨道
            extractor.selectTrack(track);
            outputStream = new BufferedOutputStream(
                    new FileOutputStream(outputPath), SAMPLE_SIZE);
            start = start * 1000;
            end = end * 1000;
            //跳至开始裁剪位置
            extractor.seekTo(start, MediaExtractor.SEEK_TO_PREVIOUS_SYNC);
            while (true){
                ByteBuffer buffer = ByteBuffer.allocate(SAMPLE_SIZE);
                int sampleSize = extractor.readSampleData(buffer, 0);
                long timeStamp = extractor.getSampleTime();
                if(timeStamp > end && timeStamp - end >= 1000000){
                    Toast.makeText(CutMusicActivity.this,"剪切完毕",Toast.LENGTH_SHORT).show();
                    break;
                }
                if(sampleSize <= 0){
                    break;
                }
                byte[] buf = new byte[sampleSize];
                buffer.get(buf, 0, sampleSize);
                //写入文件
                outputStream.write(buf);
                //音轨数据往前读
                extractor.advance();
            }

        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(extractor != null){
                extractor.release();
            }
            if(outputStream != null){
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return true;
    }

    /**
     * 获取音频数据轨道
     * @param extractor
     * @return
     */
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    private static int getAudioTrack(MediaExtractor extractor) {
        for(int i = 0; i < extractor.getTrackCount(); i++){
            MediaFormat format = extractor.getTrackFormat(i);
            String mime = format.getString(MediaFormat.KEY_MIME);
            if(mime.startsWith("audio")){
                return i;
            }
        }
        return -1;
    }

两个MP3文件合并


    /**
     * @param path         Mp301路径
     * @param path1        Mp302路径
     * @param compoundName 合成完毕的路径
     * @return
     * @throws IOException
     */
    public static String heBingMp3(String path, String path1, String compoundName) throws IOException {

        String fenLiData = fenLiData(path);
        String fenLiData2 = fenLiData(path1);
        File file = new File(fenLiData);
        File file1 = new File(fenLiData2);

        //生成处理后的文件
        File file2 = new File(compoundName);
        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);//在文件尾打开输出流
        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();
    }

    private 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();
    }

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值