【问题标题】:Concatenate two audio files and play resulting file连接两个音频文件并播放结果文件
【发布时间】:2013-09-13 13:21:04
【问题描述】:

最近几天我确实遇到了问题,但我无法找到确切的解决方案,请帮助我。

我想合并两个 .mp3 或任何音频文件并播放最后一个 mp3 文件。但是当我合并两个文件时,最终文件大小还可以,但是当我尝试播放它时,只播放第一个文件,我已经尝试使用 SequenceInputStream 或字节数组,但我无法获得确切的结果,请帮助我。

我的代码如下:

public class MerginFileHere extends Activity {
public ArrayList<String> audNames;
byte fileContent[];
byte fileContent1[];
FileInputStream ins,ins1;
FileOutputStream fos = null;
String combined_file_stored_path = Environment
        .getExternalStorageDirectory().getPath()
        + "/AudioRecorder/final.mp3";

@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);
    audNames = new ArrayList<String>();
    String file1 = Environment.getExternalStorageDirectory().getPath()
            + "/AudioRecorder/one.mp3";

    String file2 = Environment.getExternalStorageDirectory().getPath()
            + "/AudioRecorder/two.mp3";

    File file = new File(Environment.getExternalStorageDirectory()
            .getPath() + "/AudioRecorder/" + "final.mp3");

    try {
        file.createNewFile();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    audNames.add(file1);
    audNames.add(file2);

    Button btn = (Button) findViewById(R.id.clickme);
    btn.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View arg0) {
            // TODO Auto-generated method stub
            createCombineRecFile();
        }
    });
}

public void createCombineRecFile() {
    // String combined_file_stored_path = // File path in String to store
    // recorded audio

    try {
        fos = new FileOutputStream(combined_file_stored_path, true);
    } catch (FileNotFoundException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }

        try {
            File f = new File(audNames.get(0));
            File f1 = new File(audNames.get(1));
            Log.i("Record Message", "File Length=========>>>" + f.length()+"------------->"+f1.length());


            fileContent = new byte[(int) f.length()];
            ins = new FileInputStream(audNames.get(0));
            int r = ins.read(fileContent);// Reads the file content as byte

            fileContent1 = new byte[(int) f1.length()];
            ins1 = new FileInputStream(audNames.get(1));
            int r1 = ins1.read(fileContent1);// Reads the file content as byte
                                            // from the list.






            Log.i("Record Message", "Number Of Bytes Readed=====>>>" + r);

            //fos.write(fileContent1);// Write the byte into the combine file.


            byte[] combined = new byte[fileContent.length + fileContent1.length];

            for (int i = 0; i < combined.length; ++i)
            {
                combined[i] = i < fileContent.length ? fileContent[i] : fileContent1[i - fileContent.length];
            }
            fos.write(combined);
            //fos.write(fileContent1);*



        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    try {
        fos.close();
        Log.v("Record Message", "===== Combine File Closed =====");
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
}

【问题讨论】:

  • 您不能一个接一个地复制两个单独的 MP3 文件的字节并期望它能够工作。 MP3 文件是NOT 原始音频数据...它们具有标题和时间数据...简单的串联将导致无效的 MP3 文件。第一个文件通常可以正常播放,因为它是“有效的”,因为时间数据仍然有效,但对于已附加的第二个 MP3 文件,情况并非如此。
  • 其实在某些情况下你可以拼接mp3文件。但是您应该注意一些事项(例如,参见this post)。
  • @Michael 嗯...有趣...但鉴于 OP 在播放方面存在问题,我认为简单的连接对他/她不起作用...尤其是如果他/她正在生成将用于所有 MP3 文件的代码...
  • 这里提到的一个解决方案相当不错stackoverflow.com/a/11452687/3098394

标签: android audio


【解决方案1】:

我已经发布了具有此功能的应用程序...尝试使用 SequenceInputStream 的方法,在我的应用程序中,我只是将 17 个 MP3 文件合并为一个并使用 JNI 库 MPG123 播放它,但我使用 MediaPlayer 测试了该文件没有问题。

这段代码不是最好的,但它可以工作......

private void mergeSongs(File mergedFile,File...mp3Files){
        FileInputStream fisToFinal = null;
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(mergedFile);
            fisToFinal = new FileInputStream(mergedFile);
            for(File mp3File:mp3Files){
                if(!mp3File.exists())
                    continue;
                FileInputStream fisSong = new FileInputStream(mp3File);
                SequenceInputStream sis = new SequenceInputStream(fisToFinal, fisSong);
                byte[] buf = new byte[1024];
                try {
                    for (int readNum; (readNum = fisSong.read(buf)) != -1;)
                        fos.write(buf, 0, readNum);
                } finally {
                    if(fisSong!=null){
                        fisSong.close();
                    }
                    if(sis!=null){
                        sis.close();
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            try {
                if(fos!=null){
                    fos.flush();
                    fos.close();
                }
                if(fisToFinal!=null){
                    fisToFinal.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    } 

【讨论】:

  • 它打印任何错误?你能给我更多的信息吗?您是否尝试过调试代码并理解为什么只合并了一个文件?
  • 是的,我已经调试了代码。它正常执行,但是当我播放最终文件时,它只有第一个剪辑。它没有第二个和第三个剪辑。
  • 合并所有文件后文件大小达到预期大小,只播放第一个剪辑或文件未合并?
  • 只合并第一个文件。
  • 这真的很奇怪,刚刚用 4 个 mp3 文件再次测试了代码并按预期工作。不知道是什么问题,你对我上一个问题的回答也与这个问题相冲突。如果只合并第一个文件,那么在您声明代码正常运行之前,应该会发生错误或某些事情以阻止文件被合并。
【解决方案2】:

Mp3 文件是一些

您可以通过将流彼此附加当且仅当您的文件的bit ratesample rate 相同来连接这些文件。

如果不是,则播放第一个文件,因为它具有真正的真正编码,但第二个文件无法解码为真正的 mp3 文件。

建议:用一些特定的bit ratesample rate 转换你的文件,然后使用你的函数。

【讨论】:

  • 我已经使用 mRecorder.setAudioSamplingRate(44100); 设置了采样率和编码比特率; mRecorder.setAudioEncodingBitRate(96000);但它仍然只播放第一个文件。有什么想法吗?
猜你喜欢
  • 2015-08-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-20
  • 2012-03-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多