Android音视频Android技术简化开发

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

2021-08-25  本文已影响0人  Peakmain

前言

基本知识

 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)
            //开始编码
        }
    }

实现编码

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

    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)
                }
            }
        }

    }
上一篇下一篇

猜你喜欢

热点阅读