组合音频文件和在不同API版本中播放的奇怪问题

时间:2011-11-25 11:08:12

标签: android audio version media

全部,我正在使用录制音频的媒体录制器

案例1:如果我使用 Android 2.2安装设备,我录制的音频会合并并播放得很好。

案例2:如果我在安装了Android 1.6的设备中使用它,我将无法播放组合音频文件。

它只播放第一个录制的音频,下一个录制的音频文件保持空白没有声音

此外,我没有在Logcat 中出现错误。

我使用以下代码录制音频:

    mRecorder = new MediaRecorder();
    mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    mRecorder.setOutputFormat(MediaRecorder.OutputFormat.RAW_AMR);
    mRecorder.setOutputFile(main_record_file);
    mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
    mRecorder.prepare();
    mRecorder.start();

我也试过mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);

组合音频文件的代码:

    public void createCombineRecFile(){
    combined_file_stored_path=getFilename_combined_raw(); // File path in String to store recorded audio
    byte fileContent[]=null;
    FileInputStream ins;
    FileOutputStream fos = null;
    try{
        fos = new FileOutputStream(combined_file_stored_path,true);
    }
    catch (FileNotFoundException e1){
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
    for(int i=0;i<audNames.size();i++){
        try{
            File f=new File(audNames.get(i));
            Log.v("Record Message", "File Length=========>>>"+f.length());
            fileContent = new byte[(int)f.length()];
            ins=new FileInputStream(audNames.get(i));
            int r=ins.read(fileContent);// Reads the file content as byte from the list.
            Log.v("Record Message", "Number Of Bytes Readed=====>>>"+r);
            fos.write(fileContent);//Write the byte into the combine file.

            Log.v("Record Message", "File======="+i+"is Appended");

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

让我知道任何细节需要。谢谢。

2 个答案:

答案 0 :(得分:3)

每个音频文件都有自己的标题(包括有关长度/样本等的信息) - 通过组合文件的方式,生成的文件有多个标题,每个源文件一个(取决于具有文件偏移的确切格式等) )。 因此,在文件格式规范方面,生成的文件不正确。

较新的Android版本更宽松,可以使用“多个标题”进行工作/播放...旧版本没有......

要创建正确组合的音频文件,您必须符合规范,其中包括创建一个描述所有包含音频的新标题......

用于音频文件组合的另一种方法 - 例如通过ffmpeg(参见this了解如何为android制作ffmpeg)。

答案 1 :(得分:1)

前言:没有对此进行测试,但我不明白为什么它不起作用。

如果标题是导致此问题的原因,您可以很容易地解决它。使用您提供的代码,编码是AMR-NB。根据{{​​3}},AMR头只是前6个字节,分别是0x23,0x21,0x41,0x4D,0x52,0x0A。如果后续文件中的标题导致问题,则只需从后续文件中省略这些字节,例如

write all bytes of first file
write from byte[6] -> byte[end] of subsequent files

让我知道它是怎么回事。

编辑:根据要求,将try块更改为:

try{
        File f=new File(audNames.get(i));
        Log.v("Record Message", "File Length=========>>>"+f.length());
        fileContent = new byte[(int)f.length()];

        ///////////////new bit////////

        //same as you had, this opens a byte stream to the file
        ins=new FileInputStream(audNames.get(i));
        //reads fileContent.length bytes
        ins.read(fileContent);
        //now fileContent contains the entire audio file - in bytes.
        if(i>0){
            //we are not writing the first audio recording, but subsequent ones
            //so we don't want the header included in the write

            //copy the entire file, but not the first 6 bytes
            byte[] headerlessFileContent = new byte[fileContent.length()-6];
            for(int j=6; j<fileContent.length();j++){
                headerlessFileContent[j-6] = fileContent[j];
            }
            fileContent = headerlessFileContent;
        }
        ////////////////////////////

        Log.v("Record Message", "Number Of Bytes Readed=====>>>"+r);
        fos.write(fileContent);//Write the byte into the combine file.

        Log.v("Record Message", "File======="+i+"is Appended");

    }