mediacode借助MediaMuxer格式转换编码成mp4例子
时间: 2023-07-09 09:54:59 浏览: 161
以下是一个简单的 MediaCodec 借助 MediaMuxer 将视频转换并编码成 MP4 格式的示例代码:
```
private void transcodeVideo(String inputFilePath, String outputFilePath) {
try {
// 创建 MediaExtractor 对象,用于读取输入文件的视频数据
MediaExtractor extractor = new MediaExtractor();
extractor.setDataSource(inputFilePath);
// 获取输入文件的视频格式信息
MediaFormat inputFormat = null;
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);
inputFormat = format;
break;
}
}
// 创建 MediaMuxer 对象,用于生成输出文件
MediaMuxer muxer = new MediaMuxer(outputFilePath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
// 创建 MediaFormat 对象,用于指定输出文件的视频格式
MediaFormat outputFormat = MediaFormat.createVideoFormat("video/mp4v-es", inputFormat.getInteger(MediaFormat.KEY_WIDTH), inputFormat.getInteger(MediaFormat.KEY_HEIGHT));
outputFormat.setInteger(MediaFormat.KEY_BIT_RATE, inputFormat.getInteger(MediaFormat.KEY_BIT_RATE));
outputFormat.setInteger(MediaFormat.KEY_FRAME_RATE, inputFormat.getInteger(MediaFormat.KEY_FRAME_RATE));
outputFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, inputFormat.getInteger(MediaFormat.KEY_I_FRAME_INTERVAL));
// 创建 MediaCodec 对象,用于编码视频数据
MediaCodec encoder = MediaCodec.createEncoderByType("video/mp4v-es");
encoder.configure(outputFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
encoder.start();
// 开始循环读取输入文件的视频数据,并将编码后的数据写入到输出文件中
ByteBuffer buffer = ByteBuffer.allocate(1024 * 1024);
MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
boolean sawInputEOS = false;
boolean sawOutputEOS = false;
int trackIndex = 0;
while (!sawOutputEOS) {
if (!sawInputEOS) {
int inputIndex = extractor.getSampleTrackIndex();
if (inputIndex >= 0) {
int size = extractor.readSampleData(buffer, 0);
if (size < 0) {
sawInputEOS = true;
size = 0;
}
long presentationTimeUs = extractor.getSampleTime();
extractor.advance();
if (size > 0) {
ByteBuffer inputBuffer = encoder.getInputBuffer(inputIndex);
inputBuffer.clear();
inputBuffer.put(buffer);
encoder.queueInputBuffer(inputIndex, 0, size, presentationTimeUs, sawInputEOS ? MediaCodec.BUFFER_FLAG_END_OF_STREAM : 0);
}
} else {
sawInputEOS = true;
encoder.queueInputBuffer(inputIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
}
}
int outputIndex = encoder.dequeueOutputBuffer(info, 0);
if (outputIndex >= 0) {
ByteBuffer outputBuffer = encoder.getOutputBuffer(outputIndex);
outputBuffer.position(info.offset);
outputBuffer.limit(info.offset + info.size);
if ((info.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) {
info.size = 0;
}
if (info.size > 0) {
outputBuffer.position(info.offset);
outputBuffer.limit(info.offset + info.size);
muxer.writeSampleData(trackIndex, outputBuffer, info);
}
encoder.releaseOutputBuffer(outputIndex, false);
if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
sawOutputEOS = true;
}
} else if (outputIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
trackIndex = muxer.addTrack(encoder.getOutputFormat());
muxer.start();
}
}
// 释放资源,关闭 MediaMuxer 和 MediaCodec
extractor.release();
muxer.stop();
muxer.release();
encoder.stop();
encoder.release();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
```
该代码中,我们首先创建了一个 MediaExtractor 对象,用于读取输入文件的视频数据。然后通过循环遍历每个轨道的方式,获取输入文件的视频格式信息。接着创建了一个 MediaMuxer 对象,用于生成输出文件,并创建了一个 MediaFormat 对象,用于指定输出文件的视频格式。最后创建了一个 MediaCodec 对象,用于编码视频数据,并循环读取输入文件的视频数据,并将编码后的数据写入到输出文件中,最后释放资源,关闭 MediaMuxer 和 MediaCodec。
阅读全文