使用MediaCodec代码例子
时间: 2024-03-09 17:48:58 浏览: 190
以下是一个简单的使用MediaCodec进行视频编码的示例代码:
```
import android.media.MediaCodec;
import android.media.MediaCodecInfo;
import android.media.MediaFormat;
import android.os.Build;
import android.util.Log;
import android.view.Surface;
import java.io.IOException;
import java.nio.ByteBuffer;
public class VideoEncoder {
private static final String TAG = "VideoEncoder";
private static final String MIME_TYPE = "video/avc";
private static final int FRAME_RATE = 30;
private static final int I_FRAME_INTERVAL = 5;
private static final int TIMEOUT_USEC = 10000;
private MediaCodec mMediaCodec;
private Surface mInputSurface;
private int mWidth;
private int mHeight;
public VideoEncoder(int width, int height) {
mWidth = width;
mHeight = height;
}
public Surface getInputSurface() {
return mInputSurface;
}
public void prepare() throws IOException {
MediaFormat format = MediaFormat.createVideoFormat(MIME_TYPE, mWidth, mHeight);
format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
format.setInteger(MediaFormat.KEY_BIT_RATE, 2000000);
format.setInteger(MediaFormat.KEY_FRAME_RATE, FRAME_RATE);
format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, I_FRAME_INTERVAL);
mMediaCodec = MediaCodec.createEncoderByType(MIME_TYPE);
mMediaCodec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
mInputSurface = mMediaCodec.createInputSurface();
mMediaCodec.start();
}
public void stop() {
if (mMediaCodec != null) {
mMediaCodec.stop();
mMediaCodec.release();
mMediaCodec = null;
}
}
public void encodeFrame() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mMediaCodec.signalEndOfInputStream();
} else {
// Workaround for Android 4.3 and 4.4, where signalEndOfInputStream() is not available
int inputBufferId = mMediaCodec.dequeueInputBuffer(TIMEOUT_USEC);
if (inputBufferId >= 0) {
ByteBuffer inputBuffer = mMediaCodec.getInputBuffer(inputBufferId);
inputBuffer.clear();
inputBuffer.limit(0);
mMediaCodec.queueInputBuffer(inputBufferId, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
}
}
}
public ByteBuffer getOutputBuffer(int index) {
return mMediaCodec.getOutputBuffer(index);
}
public MediaCodec.BufferInfo getOutputBufferInfo(int index) {
MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
mMediaCodec.getOutputBuffer(index, info);
return info;
}
public int dequeueOutputBuffer(MediaCodec.BufferInfo info, long timeoutUs) {
return mMediaCodec.dequeueOutputBuffer(info, timeoutUs);
}
}
```
在这个示例代码中,我们首先定义了一些常量,包括视频格式、帧率、关键帧间隔、超时时间等。然后我们定义了一个VideoEncoder类,它封装了MediaCodec对象和一些方法,用于进行视频编码。
在prepare()方法中,我们创建了一个MediaFormat对象,用于描述视频格式。然后我们使用MediaCodec.createEncoderByType()方法创建一个MediaCodec对象,并调用configure()方法进行配置。最后,我们调用start()方法启动编码器。
在encodeFrame()方法中,我们使用mMediaCodec.signalEndOfInputStream()方法向编码器发送结束信号。如果你的应用程序需要支持Android 4.3和4.4,你需要使用一个Workaround来代替这个方法。
在stop()方法中,我们释放了MediaCodec对象。
最后,我们还定义了一些方法,包括getOutputBuffer()、getOutputBufferInfo()和dequeueOutputBuffer()方法,这些方法用于获取编码后的视频数据。
阅读全文