Данные RAW PCM, закодированные в m4a с использованием FAAC, не распознаются? - PullRequest
2 голосов
/ 03 декабря 2011

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

Ситуация такова, что я записал звук в данные RAW PCM, используяMediaRecord и сохранил файл во временном файле, скажем, «temp.pcm».Затем используйте код ниже, чтобы закодировать его в файл .m4a AAC. Проблема в том, что закодированный файл сохранен, и размер выглядит нормально, но не может быть распознан 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 в C ++, соединенная с другим файлом-оболочкой:

#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;
}

1 Ответ

0 голосов
/ 25 апреля 2013

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

...