android中 MediaCodec 压缩视频使用示例,带调用的main方法,压缩一个测试的视频
时间: 2024-03-14 11:50:03 浏览: 402
VideoCompressor:使用硬件解码和编码API(MediaCodec)的Android高性能视频压缩器
4星 · 用户满意度95%
好的,以下是一个简单的使用 MediaCodec 压缩视频的示例代码,包括调用的 main 方法和压缩测试视频:
```java
import android.media.MediaCodec;
import android.media.MediaCodecInfo;
import android.media.MediaFormat;
import android.media.MediaMuxer;
import android.os.Environment;
import android.util.Log;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
public class VideoCompressor {
private static final String TAG = "VideoCompressor";
private static final String TEST_VIDEO_PATH = Environment.getExternalStorageDirectory() + "/test.mp4";
private static final String COMPRESSED_VIDEO_PATH = Environment.getExternalStorageDirectory() + "/compressed.mp4";
private static final String MIME_TYPE = "video/avc";
private static final int FRAME_RATE = 30;
private static final int I_FRAME_INTERVAL = 1;
private static final int BIT_RATE = 500000;
public static void main(String[] args) {
try {
VideoCompressor compressor = new VideoCompressor();
compressor.compressVideo(TEST_VIDEO_PATH, COMPRESSED_VIDEO_PATH);
} catch (Exception e) {
e.printStackTrace();
}
}
public void compressVideo(String inputFilePath, String outputFilePath) throws IOException {
Log.i(TAG, "compressVideo: inputFilePath=" + inputFilePath + ", outputFilePath=" + outputFilePath);
// Read input video file
FileInputStream inputFile = new FileInputStream(new File(inputFilePath));
byte[] inputData = new byte[inputFile.available()];
inputFile.read(inputData);
inputFile.close();
// Set up MediaCodec encoder
MediaCodec encoder = MediaCodec.createEncoderByType(MIME_TYPE);
MediaFormat format = MediaFormat.createVideoFormat(MIME_TYPE, 1920, 1080);
format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
format.setInteger(MediaFormat.KEY_BIT_RATE, BIT_RATE);
format.setInteger(MediaFormat.KEY_FRAME_RATE, FRAME_RATE);
format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, I_FRAME_INTERVAL);
encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
encoder.start();
// Set up MediaMuxer
MediaMuxer muxer = new MediaMuxer(outputFilePath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
// Start encoding
ByteBuffer[] inputBuffers = encoder.getInputBuffers();
ByteBuffer[] outputBuffers = encoder.getOutputBuffers();
MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
boolean isInputDone = false;
boolean isOutputDone = false;
int frameCount = 0;
while (!isOutputDone) {
if (!isInputDone) {
int inputBufferIndex = encoder.dequeueInputBuffer(-1);
if (inputBufferIndex >= 0) {
ByteBuffer inputBuffer = inputBuffers[inputBufferIndex];
inputBuffer.clear();
inputBuffer.put(inputData);
encoder.queueInputBuffer(inputBufferIndex, 0, inputData.length, frameCount * 1000000 / FRAME_RATE, 0);
frameCount++;
} else {
isInputDone = true;
}
}
while (!isOutputDone) {
int outputBufferIndex = encoder.dequeueOutputBuffer(bufferInfo, 0);
if (outputBufferIndex == MediaCodec.INFO_TRY_AGAIN_LATER) {
break;
} else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
MediaFormat newFormat = encoder.getOutputFormat();
Log.i(TAG, "compressVideo: output format changed: " + newFormat);
muxer.addTrack(newFormat);
} else if (outputBufferIndex < 0) {
Log.w(TAG, "compressVideo: unexpected result from encoder.dequeueOutputBuffer: " + outputBufferIndex);
} else {
ByteBuffer outputBuffer = outputBuffers[outputBufferIndex];
if ((bufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) {
bufferInfo.size = 0;
}
if (bufferInfo.size != 0) {
outputBuffer.position(bufferInfo.offset);
outputBuffer.limit(bufferInfo.offset + bufferInfo.size);
muxer.writeSampleData(0, outputBuffer, bufferInfo);
}
encoder.releaseOutputBuffer(outputBufferIndex, false);
if ((bufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
isOutputDone = true;
}
break;
}
}
}
// Release resources
muxer.stop();
muxer.release();
encoder.stop();
encoder.release();
Log.i(TAG, "compressVideo: done");
}
}
```
这个示例代码会读取指定路径下的 `test.mp4` 视频文件,并使用 MediaCodec 将其压缩为指定路径下的 `compressed.mp4` 文件。压缩的视频编码格式为 H.264,分辨率为 1920x1080,帧率为 30 帧/秒,关键帧间隔为 1 秒,比特率为 500000 bps。这些参数可以根据实际需要进行修改。
阅读全文