本章内容主要是简述音视频硬编码模块和部分逻辑改动
使用示例
override fun init() {
//开启surfaceTextureListener监听
textureView.surfaceTextureListener = surfaceTextureListener
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
//创建预览的回调
setOnCreateCaptureSession(onCreateCaptureSession)
//音视频编码数据回调
setOnCodingVideoCallback(onCodingVideoCallback)
}else{
//老相机数据回调
setOnOldVideoCallback(onOldVideoCallback)
}
//切换相机
switchCamera.setOnClickListener {
switchCamera()
}
}
初始化主要分为三个部分,首先是设置surfaceTextureListener监听,在基类中已经配置好了一个,当然你想自定义也没问题,其他所有配置需要你自己去实现了
/**
* 获取Surface的回调
*/
val surfaceTextureListener = object : TextureView.SurfaceTextureListener {
//SurfaceTexture大小发生变化时调用
@SuppressLint("Recycle")
override fun onSurfaceTextureSizeChanged(
surfaceTexture: SurfaceTexture,
width: Int,
height: Int
) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
//获取相机属性类
val cameraCharacteristics = getCameraCharacteristics()
//设置预览尺寸
previewSize = setPreviewSize(surfaceTexture, cameraCharacteristics)
previewSurface = Surface(surfaceTexture)
}
}
override fun onSurfaceTextureUpdated(surface: SurfaceTexture?) {
}
override fun onSurfaceTextureDestroyed(surfaceTexture: SurfaceTexture?): Boolean {
//关闭老相机API预览
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
stopPreview()
}else{
previewSurface.release()
}
return true
}
@SuppressLint("Recycle")
override fun onSurfaceTextureAvailable(
surfaceTexture: SurfaceTexture,
width: Int,
height: Int
) {
//初始化AudioRecord
initAudioRecord()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
//初始化Camera2
initCamera2()
//获取相机属性类
val cameraCharacteristics = getCameraCharacteristics()
//设置预览尺寸
previewSize = setPreviewSize(surfaceTexture, cameraCharacteristics)
//获取预览Surface
previewSurface = Surface(surfaceTexture)
//是否开启视频编码
createSurfaceVideoEncoder()
//是否开启音频编码
createAudioEncoder()
//开启摄像头
openCamera()
} else {
oldSurfaceTexture = surfaceTexture
//开启老相机API预览
startPreview()
}
}
}
然后是创建预览的回调,从基类代码中可以看到,可以使用设置好的参数,也可以自定义参数,自定义参数需要使用setOnCreateCaptureSession(onCreateCaptureSession)
/**
* 打开摄像头的回调
*/
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
private val callback = object : CameraDevice.StateCallback() {
//成功打开时的回调,可以得到一个 CameraDevice 实例
override fun onOpened(camera: CameraDevice) {
cameraDevice = camera
outputs = ArrayList()
if (onCreateCaptureSession == null){
//创建一个录像的CaptureRequest
previewCaptureRequest = camera.createCaptureRequest(CameraDevice.TEMPLATE_RECORD)
previewCaptureRequest.addTarget(previewSurface)
previewCaptureRequest.addTarget(inputSurface)
outputs.add(previewSurface)
outputs.add(inputSurface)
}else{
previewCaptureRequest = onCreateCaptureSession!!.createCaptureSession(camera,previewSurface,outputs)
}
//创建一个Session
camera.createCaptureSession(
outputs,
mSessionCallback,
getBackgroundHandler()
)
}
//当 camera 不再可用时的回调,通常在该方法中进行资源释放的操作
override fun onDisconnected(camera: CameraDevice) {
}
// 当 camera 打开失败时的回调,error 为具体错误原因,通常在该方法中也要进行资源释放的操作
override fun onError(camera: CameraDevice, error: Int) {
camera.close()
showError(error)
releaseBackgroundThread()
}
//相机关闭时回调
override fun onClosed(camera: CameraDevice) {
super.onClosed(camera)
cameraCaptureSession?.close()
}
}
自定义预览参数示例
/**
* 创建预览的回调
*/
private val onCreateCaptureSession = object : OnCreateCaptureSession {
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
override fun createCaptureSession(
camera: CameraDevice,
previewSurface: Surface,
outputs: ArrayList<Surface>
): CaptureRequest.Builder {
val previewCaptureRequest = camera.createCaptureRequest(CameraDevice.TEMPLATE_RECORD)
previewCaptureRequest.addTarget(previewSurface)
outputs.add(previewSurface)
return previewCaptureRequest
}
}
最后是设置数据回调,从代码中可以看到有两种回调,一种是5.0以上版本使用Camera2开启摄像头,一种是兼容5.0以下的Camera开启摄像头;音频方面没有什么限制,只是5.0以上回调的是编码后的音频数据,5.0以下是未编码的音频数据
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
//音视频编码数据回调
setOnCodingVideoCallback(onCodingVideoCallback)
}else{
//老相机数据回调
setOnOldVideoCallback(onOldVideoCallback)
}
完整代码
class LiveBroadcastActivity : BaseVideoActivity() {
override fun getLayoutId(): Int {
return R.layout.activity_live_broadcast;
}
override fun init() {
//开启surfaceTextureListener监听
textureView.surfaceTextureListener = surfaceTextureListener
//切换相机
switchCamera.setOnClickListener {
switchCamera()
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
//创建预览的回调
setOnCreateCaptureSession(onCreateCaptureSession)
//音视频编码数据回调
setOnCodingVideoCallback(onCodingVideoCallbac