视频肯定用摄像头采集
渲染可以用 SurfaceView 和 TextureView, 也可以用 OpenGL ES 渲染
首先开启摄像头权限,Android6.0以上需要动态申请
通过 SurfaceView 预览
camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
camera.setDisplayOrientation(90);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
Log.d(TAG, "surfaceDestroyed");
camera.stopPreview();
camera.release();
}
});
通过 TextureView 预览
TextureView textureView = findViewById(R.id.texttureview);
textureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
camera = Camera.open();
try {
camera.setPreviewTexture(surface);
camera.setDisplayOrientation(90);
camera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
camera.stopPreview();
camera.release();
return true;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
}
});
通过 camera.setParameters 设置摄像头参数
Camera.Parameters parameters = camera.getParameters();
parameters.setPreviewFormat(ImageFormat.NV21); // 默认就是 YUV420SP 即 NV21 格式
parameters.setPictureSize(1280, 720); // 后置摄像头默认采集图像是横版的
camera.setParameters(parameters);
默认采集的格式是 YUV420SP 即 NV21 格式。
YUV 是图像的另一种编码格式,图像还有 RGB 编码格式,每一个像素用 RGB 三个分量表示, 如 RGB_888 就是 RGB 各用一个字节表示, 编码一个像素就需要 3 个字节。 YUV 和 RGB 可以相互转换。
在 camera.setPreviewCallback 回调中可以获取到采集的视频帧
camera.setPreviewCallback(new Camera.PreviewCallback() {
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
// 这里的 data 就是每一帧图像
// 做流媒体时会编码为 h.264 等推送到流媒体服务器上
}
});
Android5.0 (API 21)之后有了一套新的 API android.hardware.camera2, Camera 不推荐使用了, 但为了兼容4.x 版本还得用 Camera 类
TODO: 之后会学习用 OpenGL ES 渲染视频流