当我将 pcm 编码为 aac 文件时,该文件未使用 aac 分析工具正确分析
when i encode pcm to an aac file,the file is not correctly analyzed with aac analysis tool
When the sample-rate is 44100,the aac byte array can be decoded and i
can sound voice ,but others can not be decoded correctly.I don't know
why?
在编码之前,我设置了MediaFormat.the csd-0 是从其他样本复制的,并且将显示 MediaFormat 参数。
private boolean prepare() {
String codecName = null;
for (int i = 0; i < MediaCodecList.getCodecCount(); i++) {
MediaCodecInfo mediaCodecInfo = MediaCodecList.getCodecInfoAt(i);
for (String type : mediaCodecInfo.getSupportedTypes()) {
if (TextUtils.equals(type, MIME_TYPE)
&& mediaCodecInfo.isEncoder()) {
codecName = mediaCodecInfo.getName();
break;
}
}
if (null != codecName) {
break;
}
}
try {
mBufferInfo = new MediaCodec.BufferInfo();
mEncoder = MediaCodec.createByCodecName(codecName);
MediaFormat mediaFormat = MediaFormat.createAudioFormat(MIME_TYPE,
KEY_SAMPLE_RATE, KEY_CHANNEL_COUNT);
mediaFormat.setString(MediaFormat.KEY_MIME, MediaFormat.MIMETYPE_AUDIO_AAC);
mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, KEY_BIT_RATE);
mediaFormat.setInteger(MediaFormat.KEY_AAC_PROFILE,
KEY_AAC_PROFILE);
mediaFormat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, mFrameSize);
byte[] data = new byte[]{(byte) 0x11, (byte) 0x90};
ByteBuffer csd_0 = ByteBuffer.wrap(data);
mediaFormat.setByteBuffer("csd-0", csd_0);
mEncoder.configure(mediaFormat, null, null,
MediaCodec.CONFIGURE_FLAG_ENCODE);
mEncoder.start();
} catch (IOException e) {
e.printStackTrace();
return false;
}
mBuffer = new byte[mFrameSize];
int minBufferSize = AudioRecord.getMinBufferSize(KEY_SAMPLE_RATE, CHANNEL_IN,
AUDIO_FORMAT);
mRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,
KEY_SAMPLE_RATE, CHANNEL_IN, AUDIO_FORMAT, minBufferSize * 2);
mRecord.startRecording();
return true;
}
使用androidMediaCodec api编码成aac while.encoderCallback会调用MediaCodec解码
long presentationTimeUs = 0;
private void encode(byte[] data) {
//api > 21
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
int inputBufferIndex = mEncoder.dequeueInputBuffer(-1);
if (inputBufferIndex >= 0) {
ByteBuffer inputBuffer = mEncoder.getInputBuffer(inputBufferIndex);
inputBuffer.clear();
inputBuffer.put(data);
inputBuffer.limit(data.length);
mEncoder.queueInputBuffer(inputBufferIndex, 0, data.length,
computePresentationTime(presentationTimeUs), BUFFER_FLAG_CODEC_CONFIG);
presentationTimeUs+=1;
}
int outputBufferIndex = mEncoder.dequeueOutputBuffer(mBufferInfo, 0);
while (outputBufferIndex >= 0) {
ByteBuffer outputBuffer = mEncoder.getOutputBuffer(outputBufferIndex);
outputBuffer.position(mBufferInfo.offset);
outputBuffer.limit(mBufferInfo.offset + mBufferInfo.size);
int length = mBufferInfo.size + 7;
if (mFrameByte == null || mFrameByte.length < length) {
mFrameByte = new byte[length];
}
addADTStoPacket(mFrameByte, length);
outputBuffer.get(mFrameByte, 7, mBufferInfo.size);
if (encoderCallback!=null){
encoderCallback.encode(mFrameByte);
mFrameByte = null;
}
mEncoder.releaseOutputBuffer(outputBufferIndex, false);
outputBufferIndex = mEncoder.dequeueOutputBuffer(mBufferInfo, 0);
}
}
添加广告header。
private void addADTStoPacket(byte[] packet, int packetLen) {
int profile = KEY_AAC_PROFILE; //AAC LC
int freqIdx = FREQ_IDX; //44.1KHz
int chanCfg = CHAN_CFG; //CPE
packet[0] = (byte) 0xFF;
packet[1] = (byte) 0xF9;
packet[2] = (byte) (((profile - 1) << 6) + (freqIdx << 2) + (chanCfg >> 2));
packet[3] = (byte) (((chanCfg & 3) << 6) + (packetLen >> 11));
packet[4] = (byte) ((packetLen & 0x7FF) >> 3);
packet[5] = (byte) (((packetLen & 7) << 5) + 0x1F);
packet[6] = (byte) 0xFC;
}
这些是关于 sample-rate 的参数。
public interface AudioCodec {
String MIME_TYPE = MediaFormat.MIMETYPE_AUDIO_AAC;
int KEY_CHANNEL_COUNT = 2;
int KEY_BIT_RATE = 64 * 1024;
int KEY_SAMPLE_RATE = 44100;
int CHANNEL_OUT = AudioFormat.CHANNEL_OUT_STEREO;
int CHANNEL_IN = AudioFormat.CHANNEL_IN_STEREO;
int KEY_AAC_PROFILE = MediaCodecInfo.CodecProfileLevel.AACObjectLC;
int WAIT_TIME = 10000;
int AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
int BUFFFER_SIZE = 2048;
int FREQ_IDX = 4;
int CHAN_CFG = 1;
}
可能是我的英语不好,所以有人看不懂我的description.Now,我找到了AAC文件不工作或播放一半的原因speed.AAC的csd- 0配置决定成功与否
我将下面的参数设置为用于编码的 MediaCodec,decode.The 采样率为 44100。
int KEY_CHANNEL_COUNT = 2;
int KEY_BIT_RATE = 64*1024;
int KEY_SAMPLE_RATE = 44100;
int CHANNEL_OUT = AudioFormat.CHANNEL_OUT_STEREO;
int CHANNEL_IN = AudioFormat.CHANNEL_IN_STEREO;
int KEY_AAC_PROFILE = MediaCodecInfo.CodecProfileLevel.AACObjectLC;
int WAIT_TIME = 10000;
int AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
int BUFFFER_SIZE = 2048;
int FREQ_IDX = 4;
int CHAN_CFG = 2;
byte CSD_0 = 0x12;
byte CSD_1 = (byte) 0x12;
csd-0 设置为通过 MediaCodec 从 pcm 编码 aac。
byte[] data = new byte[]{CSD_0, CSD_1};
ByteBuffer csd_0 = ByteBuffer.wrap(data);
mediaFormat.setByteBuffer("csd-0", csd_0);
csd-0 可根据您的样本进行更改-rate.For 例如您的采样率为 8000。
int KEY_CHANNEL_COUNT = 1;
int KEY_SAMPLE_RATE = 8000;
int KEY_BIT_RATE = 16000;
int CHANNEL_OUT = AudioFormat.CHANNEL_OUT_STEREO;
int CHANNEL_IN = AudioFormat.CHANNEL_IN_STEREO;
int KEY_AAC_PROFILE = MediaCodecInfo.CodecProfileLevel.AACObjectLC;
int WAIT_TIME = 10000;
int AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
int BUFFFER_SIZE = 2048;
int FREQ_IDX = 11;
int CHAN_CFG = 1;
byte CSD_0 = 0x15;
byte CSD_1 = (byte) 0x88;
When the sample-rate is 44100,the aac byte array can be decoded and i can sound voice ,but others can not be decoded correctly.I don't know why?
在编码之前,我设置了MediaFormat.the csd-0 是从其他样本复制的,并且将显示 MediaFormat 参数。
private boolean prepare() {
String codecName = null;
for (int i = 0; i < MediaCodecList.getCodecCount(); i++) {
MediaCodecInfo mediaCodecInfo = MediaCodecList.getCodecInfoAt(i);
for (String type : mediaCodecInfo.getSupportedTypes()) {
if (TextUtils.equals(type, MIME_TYPE)
&& mediaCodecInfo.isEncoder()) {
codecName = mediaCodecInfo.getName();
break;
}
}
if (null != codecName) {
break;
}
}
try {
mBufferInfo = new MediaCodec.BufferInfo();
mEncoder = MediaCodec.createByCodecName(codecName);
MediaFormat mediaFormat = MediaFormat.createAudioFormat(MIME_TYPE,
KEY_SAMPLE_RATE, KEY_CHANNEL_COUNT);
mediaFormat.setString(MediaFormat.KEY_MIME, MediaFormat.MIMETYPE_AUDIO_AAC);
mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, KEY_BIT_RATE);
mediaFormat.setInteger(MediaFormat.KEY_AAC_PROFILE,
KEY_AAC_PROFILE);
mediaFormat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, mFrameSize);
byte[] data = new byte[]{(byte) 0x11, (byte) 0x90};
ByteBuffer csd_0 = ByteBuffer.wrap(data);
mediaFormat.setByteBuffer("csd-0", csd_0);
mEncoder.configure(mediaFormat, null, null,
MediaCodec.CONFIGURE_FLAG_ENCODE);
mEncoder.start();
} catch (IOException e) {
e.printStackTrace();
return false;
}
mBuffer = new byte[mFrameSize];
int minBufferSize = AudioRecord.getMinBufferSize(KEY_SAMPLE_RATE, CHANNEL_IN,
AUDIO_FORMAT);
mRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,
KEY_SAMPLE_RATE, CHANNEL_IN, AUDIO_FORMAT, minBufferSize * 2);
mRecord.startRecording();
return true;
}
使用androidMediaCodec api编码成aac while.encoderCallback会调用MediaCodec解码
long presentationTimeUs = 0;
private void encode(byte[] data) {
//api > 21
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
int inputBufferIndex = mEncoder.dequeueInputBuffer(-1);
if (inputBufferIndex >= 0) {
ByteBuffer inputBuffer = mEncoder.getInputBuffer(inputBufferIndex);
inputBuffer.clear();
inputBuffer.put(data);
inputBuffer.limit(data.length);
mEncoder.queueInputBuffer(inputBufferIndex, 0, data.length,
computePresentationTime(presentationTimeUs), BUFFER_FLAG_CODEC_CONFIG);
presentationTimeUs+=1;
}
int outputBufferIndex = mEncoder.dequeueOutputBuffer(mBufferInfo, 0);
while (outputBufferIndex >= 0) {
ByteBuffer outputBuffer = mEncoder.getOutputBuffer(outputBufferIndex);
outputBuffer.position(mBufferInfo.offset);
outputBuffer.limit(mBufferInfo.offset + mBufferInfo.size);
int length = mBufferInfo.size + 7;
if (mFrameByte == null || mFrameByte.length < length) {
mFrameByte = new byte[length];
}
addADTStoPacket(mFrameByte, length);
outputBuffer.get(mFrameByte, 7, mBufferInfo.size);
if (encoderCallback!=null){
encoderCallback.encode(mFrameByte);
mFrameByte = null;
}
mEncoder.releaseOutputBuffer(outputBufferIndex, false);
outputBufferIndex = mEncoder.dequeueOutputBuffer(mBufferInfo, 0);
}
}
添加广告header。
private void addADTStoPacket(byte[] packet, int packetLen) {
int profile = KEY_AAC_PROFILE; //AAC LC
int freqIdx = FREQ_IDX; //44.1KHz
int chanCfg = CHAN_CFG; //CPE
packet[0] = (byte) 0xFF;
packet[1] = (byte) 0xF9;
packet[2] = (byte) (((profile - 1) << 6) + (freqIdx << 2) + (chanCfg >> 2));
packet[3] = (byte) (((chanCfg & 3) << 6) + (packetLen >> 11));
packet[4] = (byte) ((packetLen & 0x7FF) >> 3);
packet[5] = (byte) (((packetLen & 7) << 5) + 0x1F);
packet[6] = (byte) 0xFC;
}
这些是关于 sample-rate 的参数。
public interface AudioCodec {
String MIME_TYPE = MediaFormat.MIMETYPE_AUDIO_AAC;
int KEY_CHANNEL_COUNT = 2;
int KEY_BIT_RATE = 64 * 1024;
int KEY_SAMPLE_RATE = 44100;
int CHANNEL_OUT = AudioFormat.CHANNEL_OUT_STEREO;
int CHANNEL_IN = AudioFormat.CHANNEL_IN_STEREO;
int KEY_AAC_PROFILE = MediaCodecInfo.CodecProfileLevel.AACObjectLC;
int WAIT_TIME = 10000;
int AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
int BUFFFER_SIZE = 2048;
int FREQ_IDX = 4;
int CHAN_CFG = 1;
}
可能是我的英语不好,所以有人看不懂我的description.Now,我找到了AAC文件不工作或播放一半的原因speed.AAC的csd- 0配置决定成功与否
我将下面的参数设置为用于编码的 MediaCodec,decode.The 采样率为 44100。
int KEY_CHANNEL_COUNT = 2;
int KEY_BIT_RATE = 64*1024;
int KEY_SAMPLE_RATE = 44100;
int CHANNEL_OUT = AudioFormat.CHANNEL_OUT_STEREO;
int CHANNEL_IN = AudioFormat.CHANNEL_IN_STEREO;
int KEY_AAC_PROFILE = MediaCodecInfo.CodecProfileLevel.AACObjectLC;
int WAIT_TIME = 10000;
int AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
int BUFFFER_SIZE = 2048;
int FREQ_IDX = 4;
int CHAN_CFG = 2;
byte CSD_0 = 0x12;
byte CSD_1 = (byte) 0x12;
csd-0 设置为通过 MediaCodec 从 pcm 编码 aac。
byte[] data = new byte[]{CSD_0, CSD_1};
ByteBuffer csd_0 = ByteBuffer.wrap(data);
mediaFormat.setByteBuffer("csd-0", csd_0);
csd-0 可根据您的样本进行更改-rate.For 例如您的采样率为 8000。
int KEY_CHANNEL_COUNT = 1;
int KEY_SAMPLE_RATE = 8000;
int KEY_BIT_RATE = 16000;
int CHANNEL_OUT = AudioFormat.CHANNEL_OUT_STEREO;
int CHANNEL_IN = AudioFormat.CHANNEL_IN_STEREO;
int KEY_AAC_PROFILE = MediaCodecInfo.CodecProfileLevel.AACObjectLC;
int WAIT_TIME = 10000;
int AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
int BUFFFER_SIZE = 2048;
int FREQ_IDX = 11;
int CHAN_CFG = 1;
byte CSD_0 = 0x15;
byte CSD_1 = (byte) 0x88;