Данные RAW PCM, закодированные в m4a с использованием FAAC, не распознаются?

Я пытаюсь использовать FAAC через JNI, чтобы включить кодирование AAC для моего проекта приложения для Android. Кажется, все работает нормально, но часть кодирования, хм... довольно странная. Должен признаться, что я не знаком с программированием аудио и искал решения и ответы уже несколько дней, но ответа пока не нашел.

Ситуация такова, что я записал звук в данные RAW PCM с помощью MediaRecord и сохранил файл во временный файл, скажем, «temp.pcm». Затем с помощью приведенного ниже кода закодируйте его в файл AAC .m4a. Проблема в том, что закодированный файл сохраняется, и размер выглядит нормально, но не может быть распознан mPlayer или любым другим медиаплеером. При их воспроизведении будет выдаваться ошибка, например, неподдерживаемый формат. Похоже, закодированный файл имеет неправильную структуру.

Я понятия не имею об этом. Кто-нибудь пробовал это раньше? Поделитесь своим опытом или подскажите, пожалуйста... Я так в отчаянии от этого... :(

РЕДАКТИРОВАТЬ 1: Просто подумал, как показано в приведенном ниже коде, действительно ли я получаю необработанные данные файла m4a, но не имею заголовка или других структур, чтобы игроки не узнали его?

Java-часть:

jint Java_com_phonegap_plugins_cjplugs_CJPlugs_JNIconvPCM2FAAC(
    JNIEnv* env,
    jobject thiz, 
    jstring inputPath, 
    jstring outputPath  )
{
    const char *inFile = (*env)->GetStringUTFChars(env, inputPath, NULL);
    const char *outFile = (*env)->GetStringUTFChars(env, outputPath, NULL);

    return cppJNIconvPCM2FAAC(inFile, outFile);
}

Фактическая часть JNI на С++ соединена с другим файлом-оболочкой:

#include <cerrno>
#include <cstddef>

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <math.h>

#include "ipaws.h"
#include "faac.h"

int cppJNIconvPCM2FAAC(
    const char *inputPath, 
    const char *outputPath  )
{
    unsigned long faacInputSamples;
    unsigned long faacMaxOutputBytes;

    faacEncHandle faac = faacEncOpen(16000, 1, &faacInputSamples, &faacMaxOutputBytes);
    if ( !faac ) {
        return 0;
    }

    faacEncConfigurationPtr faacConfig = faacEncGetCurrentConfiguration(faac);

    faacConfig->mpegVersion   = MPEG4;
//  faacConfig->aacObjectType = MAIN;
    faacConfig->aacObjectType = LOW;
    faacConfig->allowMidside  = 0;
    faacConfig->useLfe        = 0;
    faacConfig->useTns        = 0;
    faacConfig->bitRate       = 16000; // per channel
//  faacConfig->quantqual     = 100;
    faacConfig->outputFormat  = 0;  // Raw
    faacConfig->inputFormat   = FAAC_INPUT_16BIT;
    faacConfig->bandWidth     = 0;

    if ( !faacEncSetConfiguration(faac, faacConfig) ) {
        return -1;
    }

    FILE* fd = fopen(inputPath, "rb");
    if ( fd == NULL ) {
        return -2;
    }
    FILE* fdout = fopen(outputPath, "wb+");
    if ( fdout == NULL ) {
        return -3;
    }

    char* bufSrc = new char[faacInputSamples*2];    // 每个采样16位PCM,2字节
    char* bufDst = new char[faacMaxOutputBytes];

    while ( 1 ) {
        int read = fread( bufSrc, faacInputSamples, 2, fd );
        if( read < 1 )
            break;
        int nread = faacEncEncode(faac, (int32_t *)bufSrc, (unsigned int)faacInputSamples, (unsigned char*)bufDst, faacMaxOutputBytes);

        fwrite( bufDst, nread, 1, fdout );
    }

    fclose( fdout );
    fclose( fd );
    delete[] bufSrc;
    delete[] bufDst;

    faacEncClose( faac );

    return 1;
}

person JiangCat    schedule 03.12.2011    source источник


Ответы (1)


В вашей программе нет ничего плохого. Но вы настраиваете выходной формат RAW, поэтому внешний файл не имеет заголовка. Вы должны настроить внешний файл как faacConfig->outputFormat = 1; И тогда вы можете использовать FAAD2 для декодирования файла!

person Khoa Pham    schedule 25.04.2013