1
44100Hz 모노 64kbit AAC-LC 사운드를 pcm raw로 디코딩합니다. 그렇게하면 AudioTrack으로 pcm raw를 재생할 수 있습니다.AudioTrack에 디코딩 된 AAC 사운드 이상한 사운드
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();
}
}
}
로그 캣은 말한다 : 여기
는 클래스2048 bytes decoded
그리고 난 시간에 이상한 소리 시간을 얻었다. 디코딩은 괜찮아 보인다. 버퍼 크기에서 내 의견 이슈. 그러나 나는 무엇을 해야할지 모른다! 모든 것이 좋은 것처럼 보입니다.
나는 buffersize audiotrack 및 들어오는 데이터를 변경하려고했지만 변경하지 않았습니다.
아이디어가 있으십니까?