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