繁体   English   中英

android 中的 MediaCodec、MediaExtractor 和 MediaMuxer 是什么?

[英]What is MediaCodec, MediaExtractor and MediaMuxer in android?

MediaCodec、MediaExtractor 和 MediaMuxer 在安卓中是什么意思? 我不是视频爱好者,但我知道编码和解码的基本含义。 我需要知道每个类的功能是什么以及它们在哪些用例中使用。
我也想知道:

  • 如果我想从相机预览中提取帧并创建视频文件以及一些编辑(如速度),我应该使用哪些类以及它如何协同工作?
  • 如果我想创建一个像 Exoplayer 这样的视频播放器(不是所有的功能,而是一个简单的 Dash 自适应流媒体播放器),我应该使用哪些类以及它如何协同工作?

希望你能回答。 谢谢你。

首先让我说,如果您不了解视频编码/解码的工作原理,就很难理解这个 API。 我建议对编码器/解码器的工作原理进行研究。

我将提供每个的过于简化的解释。


媒体编解码器

MediaCodec 类可用于访问低级媒体编解码器,即编码器/解码器组件。 它是 Android 底层多媒体支持基础设施的一部分

因此MediaCodec处理视频数据包/缓冲区的解码或编码,并负责与编解码器的交互。

以下是如何初始化MediaCodec的示例:

// Create Mediacodec instance by passing a mime type. It will select the best codec for this mime type
MediaCodec mDecoder = MediaCodec.createDecoderByType(mimeType); 
// Pass an instance on MediaFormat and the output/rendering Surface
mDecoder.configure(format, surface, null, 0); 
mDecoder.start();

然后,您将开始将缓冲区传递给MediaCodec ,如下所示:

ByteBuffer[] inputBuffers = mDecoder.getInputBuffers();
int index = mDecoder.dequeueInputBuffer(timeout);
// Check if buffers are available
if (index >= 0) { 
    // Get dequeued buffer
    ByteBuffer buffer = inputBuffers[index]; 
    // Get sample data size to determine if we should keep queuing more buffers or signal end of stream
    int sampleSize = mExtractor.readSampleData(buffer, 0); 
    if (sampleSize < 0) { 
        // Signal EOS, this happens when you reach the end if the video, for example.
        mDecoder.queueInputBuffer(inIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM); 
    } else { 
        // Queue the dequeued buffer and pass the extractors sample time
        mDecoder.queueInputBuffer(index, 0, sampleSize, mExtractor.getSampleTime(), 0);
        mExtractor.advance(); 
    } 
}

然后您将输出缓冲区出列并将其释放到您的表面:

BufferInfo frameInfo = new BufferInfo(); 
int index mDecoder.dequeueOutputBuffer(frameInfo, timeout);

switch (index) { 
    case
        MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED: 
    break; 
    case
        MediaCodec.INFO_OUTPUT_FORMAT_CHANGED: 
        MediaFormat newFormat = mDecoder.getOutputFormat(); 
    break; 
    case
        MediaCodec.INFO_TRY_AGAIN_LATER: break; default: 
    break; 
}

// You can now push the frames to the surface
// This is where you can control the playback speed, you can do this by letting your thread sleep momentarily

if (index > 0) {
    mDecoder.releaseOutputBuffer(bufferIndex, true);
}



媒体提取器

MediaExtractor 有助于从数据源中提取解复用的、通常是编码的媒体数据。

文档说明是不言自明的。

看看下面,我添加了评论以使其更容易理解:

// Initialize the extractor
MediaExtractor() mExtract = new MediaExtractor(); mExtract.setDataSource(mSource);

// Select/set the video track (if available)
int trackIndex = selectVideoTrack(mExtract);
if(trackIndex < 0) 
    throw new IOException("Can't find track");
mExtract.selectTrack(trackIndex);

// The extractor is now ready to be used

// Get the track format
mFormat = mExtractor.getTrackFormat(trackIndex);

// Get buffer size to check if a buffer is available
// This will be used by MediaCodec to determine if buffers are available
sampleSize = mExtractor.readSampleData(buffer, 0);

媒体复用器

MediaMuxer 有助于混合基本流。 目前 MediaMuxer 支持 MP4、Webm 和 3GP 文件作为输出。 自 Android Nougat 以来,它还支持在 MP4 中混合 B 帧。

这又是不言自明的。 它用于创建视频/音频文件。 例如,将两个视频文件合并在一起。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM