使用MediaCodec将振动数据通过音频编码成.aac音频文件
import android.media.MediaCodec;
import android.media.MediaCodecInfo;
import android.media.MediaFormat;
import android.os.Environment;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
/**
* Created by WJY.
* Date: 2022-01-11
* Time: 14:32
* Description: 音频编码测试 .aac
*/
public class AudioEncoderTest {
private MediaFormat encoderFormat;
private MediaCodec encoder;
private FileOutputStream fos;
private MediaCodec.BufferInfo info;
private int perpcmsize;
private byte[] outByteBuffer;
private int mSamplingRate;//采样率
public void initMediaCodec(int samperate) {
try {
mSamplingRate = samperate;
File outfile = new File(Environment.getExternalStorageDirectory()+"/VbAudio", "/audio_encoded.aac");
touch(outfile);
encoderFormat = MediaFormat.createAudioFormat(MediaFormat.MIMETYPE_AUDIO_AAC,samperate,1);
encoderFormat.setInteger(MediaFormat.KEY_BIT_RATE,96000);
encoderFormat.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC);
encoderFormat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, 1000 * 1024);
encoder = MediaCodec.createEncoderByType(MediaFormat.MIMETYPE_AUDIO_AAC);
info = new MediaCodec.BufferInfo();
if (encoder == null) {
return;
}
encoder.configure(encoderFormat,null,null,MediaCodec.CONFIGURE_FLAG_ENCODE);
fos = new FileOutputStream(outfile);
encoder.start();
}catch (IOException e) {
e.printStackTrace();
}
}
private void touch(File f) {
try {
if (!f.exists())
f.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
//编码
public void encodecPcmToAAC(int size, byte[] buffer) {
if (buffer != null && encoder !=null) {
int inputBufferIndex = encoder.dequeueInputBuffer(0);
if (inputBufferIndex >= 0) {
ByteBuffer byteBuffer = encoder.getInputBuffers()[inputBufferIndex];
LoggUtils.e("byteBuffer","byteBuffer:" +byteBuffer.capacity()+",buffer:" +buffer.length);
byteBuffer.clear();
byteBuffer.put(buffer);
encoder.queueInputBuffer(inputBufferIndex,0,size,0,0);
}
int index = encoder.dequeueOutputBuffer(info,100000);
while (index < 0){
index = encoder.dequeueOutputBuffer(info,100000);
}
while (index >= 0) {
try {
perpcmsize = info.size + 7;
outByteBuffer = new byte[perpcmsize];
ByteBuffer byteBuffer = encoder.getOutputBuffers()[index];
byteBuffer.position(info.offset);
byteBuffer.limit(info.offset + info.size);
addADTSHeader(outByteBuffer,perpcmsize);
byteBuffer.get(outByteBuffer,7,info.size);
byteBuffer.position(info.offset);
fos.write(outByteBuffer,0,perpcmsize);
encoder.releaseOutputBuffer(index,false);
index = encoder.dequeueOutputBuffer(info,100000);
outByteBuffer = null;
LoggUtils.e("Player","编码中。。。");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//添加ADTS头信息
private void addADTSHeader(byte[] packet, int packetLen) {
int profile = 2; // AAC LC
// 39=MediaCodecInfo.CodecProfileLevel.AACObjectELD;
// int chanCfg = 2; // CPE (Channel Pair Element 双通道元素)
int chanCfg = 1; // 1 通道: 前中心
// int freqIdx = 4; // 44.1KHz
int freqIdx = 11; // 8000 赫兹
// int freqIdx = 10; // 11025 赫兹
// int freqIdx = 9; // 12000 赫兹
// int freqIdx = 8; // 16000 赫兹
// int freqIdx = 7; // 22050 赫兹
if (mSamplingRate == 8000){
freqIdx = 11; // 8000 赫兹
}else if (mSamplingRate == 12000){
freqIdx = 9; // 12000 赫兹
}else if (mSamplingRate == 16000){
freqIdx = 8; // 16000 赫兹
}else if (mSamplingRate == 44100){
freqIdx = 4; // 44.1KHz
}else if (mSamplingRate == 11025){
freqIdx = 10; // 11025 Hz
}
// fill in ADTS data
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);//数据长度的组合(注意packetLen是原始数据长度加上ADTS头的长度)
packet[5] = (byte) (((packetLen & 7) << 5) + 0x1F);
packet[6] = (byte) 0xFC;
}
//释放Mediacodec
public void releaseMediaCodec() {
try {
if (fos != null) {
fos.close();
}
if (encoder != null) {
encoder.stop();
encoder.release();
}
encoderFormat = null;
info = null;
} catch (IOException e) {
e.printStackTrace();
}finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
使用
private AudioEncoderTest audioEncoder;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
audioEncoder = new AudioEncoderTest();
audioEncoder.initMediaCodec(采样率);
audioEncoder.encodecPcmToAAC(数据长度,数据byte[]);
}
@Override
public void onDestory() {
if (null != audioEncoder) {
audioEncoder.releaseMediaCodec();
}
super.onDestory();
}