2

JNI を介して FAAC を使用して、Android アプリ プロジェクトの AAC エンコーディングを有効にしようとしています。すべてが正常に機能しているように見えますが、エンコーディング部分は、うーん...かなり奇妙です。私はオーディオ プログラミングに慣れていないことを認めなければならず、すでに数日間解決策と回答を探しましたが、まだ回答が見つかりませんでした。

状況は、MediaRecord を使用してオーディオを RAW PCM データに録音し、ファイルを一時ファイル、たとえば「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);
}

別のラッパー ファイルでブリッジされた C++ の実際の 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;
}
4

1 に答える 1

0

あなたのプログラムには何も問題はありません。ただし、出力形式を RAW に設定すると、出力ファイルはヘッドレスになります。outfile を faacConfig->outputFormat = 1;に設定する必要があります。 そして、FAAD2 を使用してファイルをデコードできます。

于 2013-04-25T16:26:49.543 に答える