自定义音视频基类六:ImageReader+GPUImage+MediaCodec

本文介绍了Android音视频开发的基础流程,包括初始化摄像头和编码器,使用ImageReader获取视频数据,转换为ByteArray,通过GPUImage进行渲染,将渲染数据导入MediaCodec进行硬编码。详细步骤涵盖了从开启摄像头到编码的整个过程。
摘要由CSDN通过智能技术生成

音视频这块从一个懵懵懂懂的新手到现在也快一个月了,越是学习越是感受到音视频开发的博大精深,每进一步都要花费很多精力,这篇文章是在前面学习的基础上对自己的总结,实现视频的采集+渲染+编码的基类

现在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()
}

2、开启摄像头


                
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值