gpt4 book ai didi

android - 使用 MediaCodec 和 MediaExtractor 播放视频和音频

转载 作者:搜寻专家 更新时间:2023-11-01 09:36:50 24 4
gpt4 key购买 nike

我正在尝试使用 MediaCodec 播放视频。视频正在播放但音频静音。我想取消静音。经过研究我发现我们需要单独解码音频和视频。我想只使用一个 Mediacodec 和 MediaExtractor 对象来播放视频和音频。如何这可以实现吗?我使用以下代码播放视频。

        extractor = new MediaExtractor();
extractor.setDataSource(SAMPLE);

for (int i = 0; i < extractor.getTrackCount(); i++) {
MediaFormat format = extractor.getTrackFormat(i);
String mime = format.getString(MediaFormat.KEY_MIME);
if (mime.startsWith("video/")) {
extractor.selectTrack(i);
decoder = MediaCodec.createDecoderByType(mime);
decoder.configure(format, surface, null, 0);
break;
}
}

if (decoder == null) {
Log.e("DecodeActivity", "Can't find video info!");
return;
}

decoder.start();

ByteBuffer[] inputBuffers = decoder.getInputBuffers();
ByteBuffer[] outputBuffers = decoder.getOutputBuffers();
BufferInfo info = new BufferInfo();
boolean isEOS = false;
long startMs = System.currentTimeMillis();

while (!Thread.interrupted()) {
if (!isEOS) {
int inIndex = decoder.dequeueInputBuffer(10000);
if (inIndex >= 0) {
ByteBuffer buffer = inputBuffers[inIndex];
int sampleSize = extractor.readSampleData(buffer, 0);
if (sampleSize < 0) {
// We shouldn't stop the playback at this point, just pass the EOS
// flag to decoder, we will get it again from the
// dequeueOutputBuffer
Log.d("DecodeActivity", "InputBuffer BUFFER_FLAG_END_OF_STREAM");
decoder.queueInputBuffer(inIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
isEOS = true;
} else {
decoder.queueInputBuffer(inIndex, 0, sampleSize, extractor.getSampleTime(), 0);
extractor.advance();
}
}
}

int outIndex = decoder.dequeueOutputBuffer(info, 10000);
switch (outIndex) {
case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:
Log.d("DecodeActivity", "INFO_OUTPUT_BUFFERS_CHANGED");
outputBuffers = decoder.getOutputBuffers();
break;
case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
Log.d("DecodeActivity", "New format " + decoder.getOutputFormat());
break;
case MediaCodec.INFO_TRY_AGAIN_LATER:
Log.d("DecodeActivity", "dequeueOutputBuffer timed out!");
break;
default:
ByteBuffer buffer = outputBuffers[outIndex];
Log.v("DecodeActivity", "We can't use this buffer but render it due to the API limit, " + buffer);

// We use a very simple clock to keep the video FPS, or the video
// playback will be too fast
while (info.presentationTimeUs / 1000 > System.currentTimeMillis() - startMs) {
try {
sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
break;
}
}
decoder.releaseOutputBuffer(outIndex, true);
break;
}

// All decoded frames have been rendered, we can stop playing now
if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
Log.d("DecodeActivity", "OutputBuffer BUFFER_FLAG_END_OF_STREAM");
break;
}
}

decoder.stop();
decoder.release();
extractor.release();
}

最佳答案

您可以使用一个提取器和两个 MediaCodec 实例来播放音频和视频。只有一个 MediaCodec 实例无法做到这一点。对于解复用器,一个提取器就可以了,它将文件解复用为音频流和视频流。但音频和视频流应该使用不同的解码器,如音频 AAC、视频 AVC 等...并且 MediaCodec 不能动态更改解码类型,因此您应该创建不同的 MediaCodec每个流的实例。播放器应该考虑 AV 同步...您可以引用:https://github.com/saki4510t/AudioVideoPlayerSample

关于android - 使用 MediaCodec 和 MediaExtractor 播放视频和音频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42455987/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com