Android 解码AAC声音到AudioTrack怪异声音
我正在将44100Hz单声道64kbit AAC-LC声音解码为pcm原始。这样我就可以用AudioTrack播放pcm raw 下面是课堂:Android 解码AAC声音到AudioTrack怪异声音,android,audio,android-mediacodec,decoder,audiotrack,Android,Audio,Android Mediacodec,Decoder,Audiotrack,我正在将44100Hz单声道64kbit AAC-LC声音解码为pcm原始。这样我就可以用AudioTrack播放pcm raw 下面是课堂: package com.sametaylak.cstudio.lib; import android.media.AudioFormat; import android.media.AudioManager; import android.media.AudioTrack; import android.media.MediaCodec; import
package com.sametaylak.cstudio.lib;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.media.MediaCodec;
import android.media.MediaCodecInfo;
import android.media.MediaFormat;
import android.util.Log;
import net.butterflytv.rtmp_client.RtmpClient;
import java.io.IOException;
import java.nio.ByteBuffer;
public class AudioDecoder extends Thread {
private MediaCodec decoder;
private RtmpClient client;
private AudioTrack track;
public boolean startDecoder() {
try {
int bufferSizePlayer = AudioTrack.getMinBufferSize(44100, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);
track = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSizePlayer, AudioTrack.MODE_STREAM);
client = new RtmpClient();
decoder = MediaCodec.createDecoderByType("audio/mp4a-latm");
MediaFormat format = new MediaFormat();
format.setString(MediaFormat.KEY_MIME, "audio/mp4a-latm");
format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
format.setInteger(MediaFormat.KEY_SAMPLE_RATE, 44100);
format.setInteger(MediaFormat.KEY_BIT_RATE, 64 * 1024);
format.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC);
int profile = 2;
int freqIdx = 4;
int chanCfg = 1;
ByteBuffer csd = ByteBuffer.allocate(2);
csd.put(0, (byte) (profile << 3 | freqIdx >> 1));
csd.put(1, (byte)((freqIdx & 0x01) << 7 | chanCfg << 3));
format.setByteBuffer("csd-0", csd);
decoder.configure(format, null, null, 0);
client.open("rtmp://192.168.1.41/live/samet live=1", false);
track.play();
start();
return true;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
@Override
public void run() {
byte[] data;
ByteBuffer[] inputBuffers;
ByteBuffer[] outputBuffers;
ByteBuffer inputBuffer;
ByteBuffer outputBuffer;
MediaCodec.BufferInfo bufferInfo;
int inputBufferIndex;
int outputBufferIndex;
byte[] outData;
decoder.start();
try {
for (;;) {
data = new byte[1024];
client.read(data, 0, data.length);
inputBuffers = decoder.getInputBuffers();
outputBuffers = decoder.getOutputBuffers();
inputBufferIndex = decoder.dequeueInputBuffer(-1);
if (inputBufferIndex >= 0) {
inputBuffer = inputBuffers[inputBufferIndex];
inputBuffer.clear();
inputBuffer.put(data);
decoder.queueInputBuffer(inputBufferIndex, 0, data.length, 0, 0);
}
bufferInfo = new MediaCodec.BufferInfo();
outputBufferIndex = decoder.dequeueOutputBuffer(bufferInfo, 0);
while (outputBufferIndex >= 0) {
outputBuffer = outputBuffers[outputBufferIndex];
outputBuffer.position(bufferInfo.offset);
outputBuffer.limit(bufferInfo.offset + bufferInfo.size);
outData = new byte[bufferInfo.size];
outputBuffer.get(outData);
Log.d("AudioDecoder", outData.length + " bytes decoded");
track.write(outData, 0, outData.length);
decoder.releaseOutputBuffer(outputBufferIndex, false);
outputBufferIndex = decoder.dequeueOutputBuffer(bufferInfo, 0);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
package com.sametaylak.cstudio.lib;
导入android.media.AudioFormat;
导入android.media.AudioManager;
导入android.media.AudioTrack;
导入android.media.MediaCodec;
导入android.media.mediacodeinfo;
导入android.media.MediaFormat;
导入android.util.Log;
导入net.butterflytv.rtmp_client.RtmpClient;
导入java.io.IOException;
导入java.nio.ByteBuffer;
公共类音频解码器扩展线程{
专用媒体编解码器;
私有rtmpc客户端;
私人音轨;
公共布尔startDecoder(){
试一试{
int bufferSizePlayer=AudioTrack.getMinBufferSize(44100,AudioFormat.CHANNEL\u OUT\u MONO,AudioFormat.ENCODING\u PCM\u 16位);
曲目=新的音频曲目(AudioManager.STREAM\u MUSIC,44100,AudioFormat.CHANNEL\u OUT\u MONO,AudioFormat.ENCODING\u PCM\u 16位,bufferSizePlayer,AudioTrack.MODE\u STREAM);
client=新的RtmpClient();
解码器=MediaCodec.createDecoderByType(“音频/mp4a latm”);
MediaFormat=新的MediaFormat();
format.setString(MediaFormat.KEY_MIME,“音频/mp4a latm”);
format.setInteger(MediaFormat.KEY\u CHANNEL\u COUNT,1);
format.setInteger(MediaFormat.KEY\u采样率,44100);
format.setInteger(MediaFormat.KEY\u比特率,64*1024);
format.setInteger(MediaFormat.KEY_AAC_PROFILE,MediaCodecInfo.codecoprofilelevel.AACObjectLC);
int-profile=2;
int-freqIdx=4;
int-chanCfg=1;
ByteBuffer csd=ByteBuffer.allocate(2);
csd.put(0,(字节)(profile>1));
csd.put(1,(字节)((freqIdx&0x01)=0){
outputBuffer=outputBuffers[outputBufferIndex];
outputBuffer.position(bufferInfo.offset);
outputBuffer.limit(bufferInfo.offset+bufferInfo.size);
outData=新字节[bufferInfo.size];
outputBuffer.get(outData);
Log.d(“AudioDecoder”,outData.length+“已解码字节”);
track.write(outData,0,outData.length);
解码器.releaseOutputBuffer(outputBufferIndex,false);
outputBufferIndex=decoder.dequeueOutputBuffer(bufferInfo,0);
}
}
}捕获(IOE异常){
e、 printStackTrace();
}
}
}
Logcat说:
2048 bytes decoded
已解码2048字节
我不时听到奇怪的声音。我认为解码似乎还可以。我的意见是缓冲区大小的问题。但我不知道该怎么办!一切似乎都很好
我试图改变buffersize音轨和传入数据,但没有改变
有什么想法吗?我想您在调用解码方法之前没有设置解码器配置
public boolean prepare() {
mBufferInfo = new MediaCodec.BufferInfo();
//开始播放
mPlayer = new AudioTrack(AudioManager.STREAM_MUSIC, KEY_SAMPLE_RATE, CHANNEL_OUT, AUDIO_FORMAT, BUFFFER_SIZE, AudioTrack.MODE_STREAM);
mPlayer.play();
try {
mDecoder = MediaCodec.createDecoderByType(MIME_TYPE);
MediaFormat format = new MediaFormat();
//解码配置
format.setString(MediaFormat.KEY_MIME, MIME_TYPE);
format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, KEY_CHANNEL_COUNT);
format.setInteger(MediaFormat.KEY_SAMPLE_RATE, KEY_SAMPLE_RATE);
format.setInteger(MediaFormat.KEY_BIT_RATE, KEY_BIT_RATE);
format.setInteger(MediaFormat.KEY_IS_ADTS, 1);
format.setInteger(MediaFormat.KEY_AAC_PROFILE, KEY_AAC_PROFILE);
int profile = KEY_AAC_PROFILE; //AAC LC
int freqIdx = FREQ_IDX; //44.1KHz
int chanCfg = CHAN_CFG; //CPE
ByteBuffer csd = ByteBuffer.allocate(2);
csd.put(0, (byte) (profile << 3 | freqIdx >> 1));
csd.put(1, (byte)((freqIdx & 0x01) << 7 | chanCfg << 3));
format.setByteBuffer("csd-0", csd);
mDecoder.configure(format, null, null, 0);
} catch (IOException e) {
e.printStackTrace();
return false;
}
if (mDecoder == null) {
Log.e(TAG, "create mediaDecode failed");
return false;
}
mDecoder.start();
return true;
}
public boolean prepare(){
mBufferInfo=new MediaCodec.BufferInfo();
//开始播放
mPlayer=新的音频曲目(AudioManager.STREAM\u音乐、按键采样率、频道输出、音频格式、buffer\u大小、AudioTrack.MODE\u流);
mPlayer.play();
试一试{
mDecoder=MediaCodec.createDecoderByType(MIME_类型);
MediaFormat=新的MediaFormat();
//解码配置
format.setString(MediaFormat.KEY\u MIME,MIME\u类型);
format.setInteger(MediaFormat.KEY\u CHANNEL\u COUNT,KEY\u CHANNEL\u COUNT);
format.setInteger(MediaFormat.KEY\u SAMPLE\u RATE、KEY\u SAMPLE\u RATE);
format.setInteger(MediaFormat.KEY\u BIT\u RATE、KEY\u BIT\u RATE);
format.setInteger(MediaFormat.KEY_为_ADTS,1);
format.setInteger(MediaFormat.KEY_AAC_PROFILE,KEY_AAC_PROFILE);
int profile=KEY\u AAC\u profile;//AAC LC
int freqIdx=FREQ_IDX;//44.1KHz
int chanCfg=CHAN_CFG;//CPE
ByteBuffer csd=ByteBuffer.allocate(2);
csd.put(0,(字节)(profile>1));
put(1,(byte)((freqIdx&0x01)我想您在调用解码方法之前没有设置解码器配置
public boolean prepare() {
mBufferInfo = new MediaCodec.BufferInfo();
//开始播放
mPlayer = new AudioTrack(AudioManager.STREAM_MUSIC, KEY_SAMPLE_RATE, CHANNEL_OUT, AUDIO_FORMAT, BUFFFER_SIZE, AudioTrack.MODE_STREAM);
mPlayer.play();
try {
mDecoder = MediaCodec.createDecoderByType(MIME_TYPE);
MediaFormat format = new MediaFormat();
//解码配置
format.setString(MediaFormat.KEY_MIME, MIME_TYPE);
format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, KEY_CHANNEL_COUNT);
format.setInteger(MediaFormat.KEY_SAMPLE_RATE, KEY_SAMPLE_RATE);
format.setInteger(MediaFormat.KEY_BIT_RATE, KEY_BIT_RATE);
format.setInteger(MediaFormat.KEY_IS_ADTS, 1);
format.setInteger(MediaFormat.KEY_AAC_PROFILE, KEY_AAC_PROFILE);
int profile = KEY_AAC_PROFILE; //AAC LC
int freqIdx = FREQ_IDX; //44.1KHz
int chanCfg = CHAN_CFG; //CPE
ByteBuffer csd = ByteBuffer.allocate(2);
csd.put(0, (byte) (profile << 3 | freqIdx >> 1));
csd.put(1, (byte)((freqIdx & 0x01) << 7 | chanCfg << 3));
format.setByteBuffer("csd-0", csd);
mDecoder.configure(format, null, null, 0);
} catch (IOException e) {
e.printStackTrace();
return false;
}
if (mDecoder == null) {
Log.e(TAG, "create mediaDecode failed");
return false;
}
mDecoder.start();
return true;
}
public boolean prepare(){
mBufferInfo=new MediaCodec.BufferInfo();
//开始播放
mPlayer=新的音频曲目(AudioManager.STREAM\u音乐、按键采样率、频道输出、音频格式、buffer\u大小、AudioTrack.MODE\u流);
mPlayer.play();
试一试{
mDecoder=MediaCodec.createDecoderByType(MIME_类型);
MediaFormat=新的MediaFormat();
//解码配置
format.setString(MediaFormat.KEY\u MIME,MIME\u类型);
format.setInteger(MediaFormat.KEY\u CHANNEL\u COUNT,KEY\u CHANNEL\u COUNT);
format.setInteger(MediaFormat.KEY\u SAMPLE\u RATE、KEY\u SAMPLE\u RATE);
format.setInteger(MediaFormat.KEY\u BIT\u RATE、KEY\u BIT\u RATE);
format.setInteger(MediaFormat.KEY_为_ADTS,1);
format.setInteger(MediaFormat.KEY_AAC_PROFILE,KEY_AAC_PROFILE);
int profile=KEY\u AAC\u profile;//AAC LC
int freqIdx=FREQ_IDX;//44.1KHz
int chanCfg=CHAN_CFG;//CPE
ByteBuffer csd=ByteBuffer.allocate(2);
csd.put(0,(字节)(profile>1));
csd.put(1,(byte)((freqIdx&0x01)相同的故事,伙计!我不知道该怎么做:(相同的故事,伙计!我不知道该怎么做:(