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

Java android中的MediaCodec、MediaExtractor和MediaMuxer是什么?,java,android,android-camera,exoplayer,android-camera2,Java,Android,Android Camera,Exoplayer,Android Camera2,MediaCodec、MediaExtractor和MediaMuxer在android中的含义是什么?我不是一个喜欢视频的人,但我知道编码和解码的基本含义。我需要知道每个类的功能是什么,在哪些用例中使用它们我也想知道: 如果我想从相机预览中提取帧并创建一个视频文件以及一些编辑(如速度),我应该使用哪些类,它们是如何协同工作的 如果我想创建一个像Exoplayer这样的视频播放器(不是所有的功能,而是一个简单的Dash adaptive流媒体播放器),我应该使用哪些类,它们是如何协同工作的

MediaCodec、MediaExtractor和MediaMuxer在android中的含义是什么?我不是一个喜欢视频的人,但我知道编码和解码的基本含义。我需要知道每个类的功能是什么,在哪些用例中使用它们
我也想知道:

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


希望你能回答。谢谢。首先让我说,如果你不了解视频编码/解码的工作原理,那么很难理解这个API。我建议对编码器/解码器的工作原理进行研究

我将对每一个问题提供一个过于简单的解释


:

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

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

下面是一个如何初始化
MediaCodec
的示例:

//通过传递mime类型创建Mediacodec实例。它将为此mime类型选择最佳编解码器
MediaCodec mDecoder=MediaCodec.createDecoderByType(mimeType);
//在MediaFormat和输出/渲染表面上传递实例
配置(格式,表面,空,0);
mDecoder.start();
然后开始将缓冲区传递给
MediaCodec
,如下所示:

ByteBuffer[]inputBuffers=mDecoder.getInputBuffers();
int index=mDecoder.dequeueInputBuffer(超时);
//检查缓冲区是否可用
如果(索引>=0){
//获取排队缓冲区
ByteBuffer缓冲区=输入缓冲区[索引];
//获取样本数据大小,以确定是否应继续排队等待更多缓冲区或发送流结束信号
int sampleSize=mExtractor.readSampleData(缓冲区,0);
如果(样本大小<0){
//信号EOS,这发生在你到达终点时,例如视频。
mDecoder.queueInputBuffer(inIndex、0、0、MediaCodec.BUFFER\u标志\u流的结束\u);
}否则{
//将退出队列的缓冲区排队,并传递提取器采样时间
mDecoder.queueInputBuffer(索引,0,sampleSize,mExtractor.getSampleTime(),0);
mExtractor.advance();
} 
}
然后将输出缓冲区出列并将其释放到曲面:

BufferInfo frameInfo=new BufferInfo();
int index mDecoder.dequeueOutputBuffer(frameInfo,超时);
开关(索引){
案例
MediaCodec.INFO\u输出\u缓冲区\u已更改:
打破
案例
MediaCodec.INFO\u输出\u格式\u已更改:
MediaFormat newFormat=mDecoder.getOutputFormat();
打破
案例
MediaCodec.INFO\u请稍后重试:中断;默认值:
打破
}
//现在可以将框架推到曲面上
//这是你可以控制播放速度的地方,你可以让你的线程暂时休眠
如果(索引>0){
mDecoder.releaseOutputBuffer(bufferIndex,true);
}

:

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

文档描述是不言自明的

看看下面,我添加了一些评论,使其更易于理解:

//初始化提取器
MediaExtractor()mExtract=新的MediaExtractor();mExtract.setDataSource(mSource);
//选择/设置视频曲目(如果可用)
int trackIndex=selectVideoTrack(mExtract);
if(trackIndex<0)
抛出新IOException(“找不到跟踪”);
mExtract.选择track(trackIndex);
//拔取器现在可以使用了
//获取曲目格式
mFormat=mExtractor.getTrackFormat(trackIndex);
//获取缓冲区大小以检查缓冲区是否可用
//MediaCodec将使用它来确定缓冲区是否可用
sampleSize=mExtractor.readSampleData(缓冲区,0);

:

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


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

您提到了Exoplayer。它使用上述三个类。看看他们是如何实施的。至于每一个都意味着什么,developer.android.com解释了它,例如-谢谢。我已经看过文件了。但是我不明白。如果你能简单地解释一下这些都是什么,那将非常有帮助。谢谢。我已经编辑了我的答案以提供更清晰的答案。如果你有什么想知道的,请告诉我。