Android 深入系统完全讲解(29)

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

MediaMuxer 封装器
MediaMuxer 最多仅支持一个视频 track 和一个音频 track所以如果有多个音频 track 可以先
把它们混合成为一个音频 track 然后再使用 MediaMuxer 封装到 mp4 容器中。
MediaMuxer 支持输出格式为 MP4webm 和 3gp. 默认我们就用 mp4. MUXER_OUTPUT_3GPP对应 3gp 文件
MUXER_OUTPUT_HEIF定影 HEIF 文件
MUXER_OUTPUT_MPEG_4对应 mp4 文件
MUXER_OUTPUT_WEBM对应 webm 文件。
主要函数说明
addTrack(MediaFormat format)利用 MediaFormat 添加音频或视频轨道。
release释放 MediaMuxer 的资源。
setLocationfloat latitude,float longitude:设置并存储地理位置信息到生成文件中。
setOrientationHintint degrees:设置输出视频回放的方向提示。
start() :开始 muxer等待数据的输入。
Stop():停止 muxer调用这个函数后将生成合成的文件。
writeSampleData(int trackIndex, ByteBuffer byteBuf, MediaCodec.BufferInfo bufferInfo)往 muxer 中写入编码的数据。
参数说明
trackIndexsample样本的 track index可以利用 MediaExtractor 获取。
byteBuf写入的数据不可为 null
bufferInfo当前 sample样本相关的 buffer 的信息不可为 null。
MediaCodec.BufferInfo:
主要包括四个数据
flags:输入 buffer 相关的 buffer flags。
offsetbuffer 开始的偏移量通常设为 0。
presentationTimeUs:buffer 的时间戳。
sizebuffer 的数据大小。
我们看下例子
MediaMuxer muxer = new MediaMuxer(“temp.mp4”, OutputFormat.MUXER_OUTPUT_MPEG_4);
// More often, the MediaFormat will be retrieved from MediaCodec.getOutputFormat()
// or MediaExtractor.getTrackFormat(). MediaFormat audioFormat = new MediaFormat(…);
MediaFormat videoFormat = new MediaFormat(…);
int audioTrackIndex = muxer.addTrack(audioFormat);
int videoTrackIndex = muxer.addTrack(videoFormat);
ByteBuffer inputBuffer = ByteBuffer.allocate(bufferSize);
boolean finished = false;
BufferInfo bufferInfo = new BufferInfo();
muxer.start();
while(!finished) {
// getInputBuffer() will fill the inputBuffer with one frame of encoded
// sample from either MediaCodec or MediaExtractor, set isAudioSample to
// true when the sample is audio data, set up all the fields of bufferInfo, // and return true if there are no more samples. finished = getInputBuffer(inputBuffer, isAudioSample, bufferInfo);
if (!finished) {
int currentTrackIndex = isAudioSample ? audioTrackIndex : videoTrackIndex;
muxer.writeSampleData(currentTrackIndex, inputBuffer, bufferInfo);
}};
muxer.stop();
muxer.release();
主要流程创建混合 MediaMuxer
addTrack 加入从 MediaExtractor 解出来的轨道信息
调用开始启动
MediaMuxer.writeSampleData() 写入数据每次只有一个视频或者音频信息
完成了这块知识下来我们进入核心领域编码 MediaCodec。MediaCodec 介绍
MediaCodec 类可以用于使用一些基本的多媒体编解码器音视频编解码组件它是 Android
基本的多媒体支持基础架构的一部分通常和 MediaExtractor , MediaSync , MediaMuxer , MediaCrypto , MediaDrm , Image , Surface , and AudioTrack 一起使用。
一个编解码器可以处理输入的数据来产生输出的数据编解码器使用一组输入和输出缓冲器
来异步处理数据。你可以创建一个空的输入缓冲区填充数据后发送到编解码器进行处理。
编解码器使用输入的数据进行转换然后输出到一个空的输出缓冲区。最后你获取到输出缓
冲区的数据消耗掉里面的数据 释放回编解码器。如果后续还有数据需要继续处理编
解码器就会重复这些操作。输出流程如下在这里插入图片描述
编解码器能处理的数据类型为**压缩数据、原始音频数据和原始视频数据。**你可以通过
ByteBuffers 能够处理这三种数据但是需要你提供一个 Surface用于对原始的视频数据进
行展示这样也能提高编解码的性能。
Surface 使用的是本地的视频缓冲区这个缓冲区不映射或拷贝到 ByteBuffers。这样的机制
让编解码器的效率更高。通常在使用 Surface 的时候无法访问原始的视频数据但是你可
以使用 ImageReader 访问解码后的原始视频帧。在使用 ByteBuffer 的模式下您可以使用
Image 类和 getInput/OutputImageint访问原始视频帧。编解码器的生命周期
主要的生命周期为Stopped、Executing、Released。
Stopped 的状态下也分为三种子状态Uninitialized、Configured、Error。
Executing 的状态下也分为三种子状态Flushed, Running、End-of-Stream。

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: android