美文网首页Android音视频Android技术简化开发
Android音视频开发——MedCodec实现屏幕录制编码成H

Android音视频开发——MedCodec实现屏幕录制编码成H

作者: Peakmain | 来源:发表于2021-08-25 18:18 被阅读0次

前言

基本知识

  • 主要用到的服务是系统服务的MEDIA_PROJECTION_SERVICE
 private lateinit var mMediaProjectionManager: MediaProjectionManager
   mMediaProjectionManager =
            getSystemService(Context.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager

  val intent: Intent = mMediaProjectionManager.createScreenCaptureIntent()
  startActivityForResult(intent, screenRequestCode)
  • 获取开启屏幕录制之后的数据
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == screenRequestCode && resultCode == Activity.RESULT_OK) {
            mMediaProjection = mMediaProjectionManager.getMediaProjection(resultCode, data)
            //开始编码
        }
    }

  • 屏幕数据怎么给Medcodec呢?


    问题.png

    解决办法:Medcodec提供一个场地,MediaProjection把数据放到那个场地,如下图


    解决办法.png

实现编码

代码很简单,主要几个方法

  • createEncoderByType创建编码器
  • configure:配置信息,我们需要配置帧率,码率,I帧等等
  • createInputSurface:创建场地
  • createVirtualDisplay:数据放到场地上去
  • 我们前篇文章讲Android音视频开发——MediaCodec播放H264视频的时候,提供给MediaCodec的左边的源数据是本地的H264视频文件,这里我们的源数据是我们的屏幕录制的数据,所以我们不需要像MediaCodec传入数据,只需要获取数据就可以了
    image.png
    private fun initMediaCodec() {
        mMediaCodec = MediaCodec.createEncoderByType("video/avc")
        //配置信息
        val format = MediaFormat.createVideoFormat(
            "video/avc",
            SizeUtils.screenWidth,
            SizeUtils.screenHeight
        )
        format.setInteger(
            MediaFormat.KEY_COLOR_FORMAT,
            MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface
        )

        format.setInteger(MediaFormat.KEY_FRAME_RATE, 15)
        //码率,码率越高,字节越长,视频就越清晰
        format.setInteger(MediaFormat.KEY_BIT_RATE, 400_000)
        //2s一个I帧
        format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 2)
        //CONFIGURE_FLAG_ENCODE:表示编码
        mMediaCodec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE)
        //创建一个场地
        val surface = mMediaCodec.createInputSurface()
        mHandler = Handler(mHandlerThread.looper)
        mHandler.post {
            mMediaCodec.start()
            mMediaProjection.createVirtualDisplay(
                "screen_codec",
                SizeUtils.screenWidth,
                SizeUtils.screenHeight,
                1,
                DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC,
                surface,
                null, null
            )
            //此时有了源数据,就可以取出数据进行编码
            val bufferInfo = MediaCodec.BufferInfo()
            while (true) {
                val outIndex = mMediaCodec.dequeueOutputBuffer(bufferInfo, 10000)
                if (outIndex >= 0) {
                    //这是dsp的数据,无法直接使用
                    val byteBuffer = mMediaCodec.getOutputBuffer(outIndex)
                    val outData = ByteArray(bufferInfo.size)
                    byteBuffer.get(outData)
                    FileUtils.writeBytes(outData, "codec.h264")
                    FileUtils.writeContent(outData, "codec.txt")
                    mMediaCodec.releaseOutputBuffer(outIndex, false)
                }
            }
        }

    }
  • 编码后的文件分析


    image.png

相关文章

网友评论

    本文标题:Android音视频开发——MedCodec实现屏幕录制编码成H

    本文链接:https://www.haomeiwen.com/subject/ajreiltx.html