这是一个使用Android Camera2 API和MediaCodec来编码H.264单元的示例代码:
import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.media.MediaCodec;
import android.media.MediaCodecInfo;
import android.media.MediaFormat;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.util.Size;
import android.view.Surface;
import android.view.TextureView;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Arrays;
public class MainActivity extends Activity {
private static final String TAG = "Camera2MediaCodec";
private static final int PERMISSION_REQUEST_CAMERA = 0;
private CameraManager cameraManager;
private String cameraId;
private Size previewSize;
private TextureView textureView;
private CameraDevice cameraDevice;
private CaptureRequest.Builder captureRequestBuilder;
private CameraCaptureSession cameraCaptureSession;
private MediaCodec mediaCodec;
private Surface inputSurface;
private final MediaCodec.Callback mediaCodecCallback = new MediaCodec.Callback() {
@Override
public void onInputBufferAvailable(@NonNull MediaCodec codec, int index) {
// Handle input buffer availability
ByteBuffer inputBuffer = codec.getInputBuffer(index);
// TODO: Fill inputBuffer with data to be encoded
codec.queueInputBuffer(index, 0, /* size */, /* presentationTimeUs */, /* flags */);
}
@Override
public void onOutputBufferAvailable(@NonNull MediaCodec codec, int index, @NonNull MediaCodec.BufferInfo info) {
// Handle output buffer availability
ByteBuffer outputBuffer = codec.getOutputBuffer(index);
// TODO: Process encoded outputBuffer
codec.releaseOutputBuffer(index, /* render */);
}
@Override
public void onError(@NonNull MediaCodec codec, @NonNull MediaCodec.CodecException e) {
// Handle codec errors
Log.e(TAG, "MediaCodec error: " + e.getMessage());
}
@Override
public void onOutputFormatChanged(@NonNull MediaCodec codec, @NonNull MediaFormat format) {
// Handle output format change
// TODO: Update codec's output format if needed
}
};
private final TextureView.SurfaceTextureListener surfaceTextureListener = new TextureView.SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) {
// Open camera when surface texture is available
openCamera();
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int width, int height) {
// Handle surface texture size change if needed
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
// Release resources when surface texture is destroyed
releaseCamera();
return true;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
// Handle surface texture update if needed
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textureView = findViewById(R.id.textureView);
textureView.setSurfaceTextureListener(surfaceTextureListener);
cameraManager = (CameraManager) getSystemService(CAMERA_SERVICE);
try {
String[] cameraIds = cameraManager.getCameraIdList();
for (String id : cameraIds) {
CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(id);
if (characteristics.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_BACK) {
cameraId = id;
break;
}
}
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void openCamera() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, PERMISSION_REQUEST_CAMERA);
return;
}
try {
StreamConfigurationMap map = cameraManager.getCameraCharacteristics(cameraId).get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
if (map != null) {
previewSize = map.getOutputSizes(SurfaceTexture.class)[0]; // Choose appropriate size
}
cameraManager.openCamera(cameraId, cameraStateCallback, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void startPreview()