아래 주어진 코드는 에뮬레이터에서는 정상적으로 작동하지만 장치에서는 정상적으로 작동하지 않습니다.Android MediaCodec API - 장치가 아닌 에뮬레이터에서 음악 재생
V/MediaExtractor (5030) : 자신감 '오디오/MPEG'등의 자동 감지의 미디어 콘텐츠 0.20 V/ChromiumHTTPDataSource (5030) : mContentSize이 정의되지 또는 네트워크 연결이 끊어 수 있습니다 나는 나에게 의심스러운 보았다 다음 줄을 발견 V/ChromiumHTTPDataSource (5030) : mContentSize은 정의되지 않습니다 또는 네트워크 D/(5030) com.example.mediacodectest 분리 될 수 있습니다 MIME 종류 : 오디오/MPEG 내가 힌트/제안을 찾고
. 미리 감사드립니다 ...
private class PlayerThread extends Thread {
@Override
public void run() {
MediaExtractor extractor;
MediaCodec codec;
ByteBuffer[] codecInputBuffers;
ByteBuffer[] codecOutputBuffers;
AudioTrack mAudioTrack;
mAudioTrack = new AudioTrack(
AudioManager.STREAM_MUSIC,
44100,
AudioFormat.CHANNEL_OUT_STEREO,
AudioFormat.ENCODING_PCM_16BIT,
8192 * 2,
AudioTrack.MODE_STREAM);
extractor = new MediaExtractor();
try
{
extractor.setDataSource("http://anmp3streamingsource.com/stream");
MediaFormat format = extractor.getTrackFormat(0);
String mime = format.getString(MediaFormat.KEY_MIME);
Log.d(TAG, String.format("MIME TYPE: %s", mime));
codec = MediaCodec.createDecoderByType(mime);
codec.configure(
format,
null /* surface */,
null /* crypto */,
0 /* flags */);
codec.start();
codecInputBuffers = codec.getInputBuffers();
codecOutputBuffers = codec.getOutputBuffers();
extractor.selectTrack(0); // <= You must select a track. You will read samples from the media from this track!
boolean sawInputEOS = false;
boolean sawOutputEOS = false;
for (;;) {
int inputBufIndex = codec.dequeueInputBuffer(-1);
if (inputBufIndex >= 0) {
ByteBuffer dstBuf = codecInputBuffers[inputBufIndex];
int sampleSize = extractor.readSampleData(dstBuf, 0);
long presentationTimeUs = 0;
if (sampleSize < 0) {
sawInputEOS = true;
sampleSize = 0;
} else {
presentationTimeUs = extractor.getSampleTime();
}
codec.queueInputBuffer(inputBufIndex,
0, //offset
sampleSize,
presentationTimeUs,
sawInputEOS ? MediaCodec.BUFFER_FLAG_END_OF_STREAM : 0);
if (!sawInputEOS) {
extractor.advance();
}
MediaCodec.BufferInfo info = new BufferInfo();
final int res = codec.dequeueOutputBuffer(info, -1);
if (res >= 0) {
int outputBufIndex = res;
ByteBuffer buf = codecOutputBuffers[outputBufIndex];
final byte[] chunk = new byte[info.size];
buf.get(chunk); // Read the buffer all at once
buf.clear(); // ** MUST DO!!! OTHERWISE THE NEXT TIME YOU GET THIS SAME BUFFER BAD THINGS WILL HAPPEN
mAudioTrack.play();
if (chunk.length > 0) {
mAudioTrack.write(chunk, 0, chunk.length);
}
codec.releaseOutputBuffer(outputBufIndex, false /* render */);
if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
sawOutputEOS = true;
}
}
else if (res == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED)
{
codecOutputBuffers = codec.getOutputBuffers();
}
else if (res == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED)
{
final MediaFormat oformat = codec.getOutputFormat();
Log.d(TAG, "Output format has changed to " + oformat);
mAudioTrack.setPlaybackRate(oformat.getInteger(MediaFormat.KEY_SAMPLE_RATE));
}
}
}
}
catch (IOException e)
{
Log.e(TAG, e.getMessage());
}
}
}
출력 처리가 올바르지 않습니다. http://bigflake.com/mediacodec/#q11에서 FAQ 항목 # 11을 추가했습니다. 표시되는 로그 라인이 너무 의심스럽지 않습니다. 코드가 장치에서 작동하지 않는 방법을보다 명확하게 정의 할 수 있습니까? – fadden
답장을 보내 주셔서 감사합니다. 이 코드는 API 레벨 17 에뮬레이터에서는 제대로 작동하지만 API 레벨 18로 실제 장치에서는 작동하지 않습니다. 다음 줄까지 디버그 할 수 있습니다. final int res = codec.dequeueOutputBuffer (info, -1); 하지만 더 이상 ... – burakk