Android 解码AAC声音到AudioTrack怪异声音

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

我正在将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 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)相同的故事,伙计!我不知道该怎么做:(相同的故事,伙计!我不知道该怎么做:(