音视频这块从一个懵懵懂懂的新手到现在也快一个月了,越是学习越是感受到音视频开发的博大精深,每进一步都要花费很多精力,这篇文章是在前面学习的基础上对自己的总结,实现视频的采集+渲染+编码的基类
现在9102下半年了,5.0以下的手机已经不多了,对音视频开发来说最低版本可以定位5.0了(个人意见如有错误请指正),便不再适配5.0以下手机,如果想适配5.0以下手机可以看看前面的几篇文章,自己修改一下
废话不多说,首先介绍一下我总结的视频开发流程:
1、初始化摄像头和编码器
2、开启摄像头
3、ImageReader获得摄像头返回的视频数据
4、将Image视频数据转成ByteArray
5、初始化渲染组件(GPUImage)
6、渲染原始视频数据并显示到屏幕上
7、然后将渲染后的数据导入MediaCodec创建的inputSurface
8、硬编码渲染的数据
1、初始化摄像头和编码器
/**
* 初始化Camera2
*/
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
fun initCamera2() {
cameraManager = application.getSystemService(Context.CAMERA_SERVICE) as CameraManager
cameraIdList = cameraManager.cameraIdList
cameraId = cameraIdList[index]
previewSize = getSurfaceSize()
}
/**
* 初始化MediaCodec的编码器
*/
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
fun createSurfaceVideoEncoder() {
//视频编码器
videoEncoder = MediaCodec.createEncoderByType("video/avc")
// 创建视频MediaFormat
val videoFormat =
MediaFormat.createVideoFormat("video/avc", previewSize.width, previewSize.height)
// 指定编码器颜色格式
videoFormat.setInteger(
MediaFormat.KEY_COLOR_FORMAT,
MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface
)
// 仅编码器指定比特率
videoFormat.setInteger(MediaFormat.KEY_BIT_RATE, 1250000)
// 编码器必须指定帧率
videoFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 25)
// 指定关键帧时间间隔
videoFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1)
//BITRATE_MODE_CBR输出码率恒定,BITRATE_MODE_CQ保证图像质量,BITRATE_MODE_VBR图像复杂则码率高,图像简单则码率低
videoFormat.setInteger(
MediaFormat.KEY_BITRATE_MODE,
MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_VBR
)
videoFormat.setInteger(
MediaFormat.KEY_COMPLEXITY,
MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_VBR
)
videoEncoder.configure(videoFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE)
//获取输入Surface
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
inputSurface = MediaCodec.createPersistentInputSurface()
videoEncoder.setInputSurface(inputSurface)
videoEncoder.setCallback(mediaCodecCallback, getBackgroundHandler())
} else {
inputSurface = videoEncoder.createInputSurface()
videoEncoder.setCallback(mediaCodecCallback)
}
paint = Paint()
videoEncoder.start()
}