Странная проблема в объединении аудио файлов и проигрывании в разных версиях API - PullRequest
10 голосов
/ 25 ноября 2011

Все, я использую Media Recorder для записи аудио .

Случай 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 ]

3 голосов
/ 28 ноября 2011

Каждый аудиофайл имеет свой собственный заголовок (включая информацию о длине / сэмплах и т. Д.) - объединяя файлы так, как вы делаете, полученный файл имеет несколько заголовков, по одному на исходный файл (в зависимости от точного формата со смещениями файлов и т. Д.). .). Таким образом, полученный файл НЕ является правильным с точки зрения спецификации формата файла.

Более новая версия Android более гибкая и работает / работает с "множественными заголовками" ... более старые версии не ...

Для создания правильно скомбинированного аудиофайла вы должны соответствовать спецификации, которая, помимо прочего, означает создание одного нового заголовка, который описывает все включенные аудио ...

Используйте для комбинации аудиофайлов другой подход - например, через ffmpeg (см. this , чтобы узнать, как сделать ffmpeg для android).

1 голос
/ 28 ноября 2011

Предисловие: не проверял это, но я не понимаю, почему это не должно работать.

Если заголовки являются причиной этой проблемы, вы можете решить ее очень легко. Используя код, который вы дали, кодировка AMR-NB. Согласно этому документу заголовок 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");

    }
...