WeiXinRecordedDemo icon indicating copy to clipboard operation
WeiXinRecordedDemo copied to clipboard

适配了arm64-v8a,修复部分机型绿屏,时长变长

Open mtzqc opened this issue 3 years ago • 5 comments

上周收到小米市场适配64位的最后通牒, 对于原本不懂C的我,无疑是雪上加上霜😪, so库地址:https://gitee.com/mtzqc/wei-xin-recorded_so 绿屏,花屏,时长变长需要修改一下com.zhaoss.weixinrecorded.util.RecordUtil.encodeVideo(byte[] nv21),有空整理了发出来

mtzqc avatar Oct 18 '21 05:10 mtzqc

@mtzqc 你好,绿屏,花屏,时长变长需要怎么改,能方便发一下吗

SeniorDoctorHui avatar Apr 03 '22 07:04 SeniorDoctorHui

private void encodeVideo(byte[] nv21) throws IOException {
   /* if (checkMaxFrame()) {
        currFrame--;
        return;
    }*/
    byte[] nv12 = new byte[nv21.length];
    byte[] yuvI420 = new byte[nv21.length];
    byte[] tempYuvI420 = new byte[nv21.length];
    LibyuvUtil.convertNV21ToI420(nv21, yuvI420, videoWidth, videoHeight);
    LibyuvUtil.compressI420(yuvI420, videoWidth, videoHeight, tempYuvI420, videoWidth, videoHeight, rotation, isFrontCamera);
    LibyuvUtil.convertI420ToNV12(tempYuvI420, nv12, videoWidth, videoHeight);
    //得到编码器的输入和输出流, 输入流写入源数据 输出流读取编码后的数据
    //得到要使用的缓存序列角标
    int inputIndex = videoMediaCodec.dequeueInputBuffer(TIMEOUT_USEC);
    if (inputIndex >= 0) {
        ByteBuffer inputBuffer = videoMediaCodec.getInputBuffer(inputIndex);
        inputBuffer.clear();
        //把要编码的数据添加进去
        inputBuffer.put(nv12);
        //塞到编码序列中, 等待MediaCodec编码
        //videoMediaCodec.queueInputBuffer(inputIndex, 0, nv12.length, System.nanoTime() / 1000, 0);
        videoMediaCodec.queueInputBuffer(inputIndex, 0, nv12.length, System.currentTimeMillis(), 0);
    }
    MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
    //读取MediaCodec编码后的数据
    int outputIndex = videoMediaCodec.dequeueOutputBuffer(bufferInfo, TIMEOUT_USEC);
//   boolean keyFrame = false;
    while (outputIndex >= 0) {
        ByteBuffer outputBuffer = videoMediaCodec.getOutputBuffer(outputIndex);
        byte[] h264 = new byte[bufferInfo.size];
        //这步就是编码后的h264数据了
        outputBuffer.get(h264);
        switch (bufferInfo.flags) {
            case MediaCodec.BUFFER_FLAG_CODEC_CONFIG://视频信息
                configByte = new byte[bufferInfo.size];
                configByte = h264;
                break;
            case MediaCodec.BUFFER_FLAG_KEY_FRAME://关键帧
                frameBuffer.put(configByte);
                frameBuffer.put(h264);
            //    keyFrame = true;
                break;
            default://正常帧
                frameBuffer.put(h264);
                break;
        }
        //数据写入本地成功 通知MediaCodec释放data
        videoMediaCodec.releaseOutputBuffer(outputIndex, false);
        //读取下一次编码数据
        outputIndex = videoMediaCodec.dequeueOutputBuffer(bufferInfo, TIMEOUT_USEC);
    }

    if (frameBuffer.position() > 0) {
        byte[] frameByte = new byte[frameBuffer.position()];
        frameBuffer.flip();
        frameBuffer.get(frameByte);
        frameBuffer.clear();
      /*  while (keyFrame && checkMinFrame()) {
            currFrame++;
            videoOut.write(frameByte, 0, frameByte.length);
            videoOut.flush();
        }*/
        currFrame++;
        videoOut.write(frameByte, 0, frameByte.length);
        videoOut.flush();
    }
}

在部分机型上还是有点问题,效果比之前的好一些

mtzqc avatar Apr 03 '22 07:04 mtzqc

好的,多谢 004A8F35

SeniorDoctorHui avatar Apr 06 '22 02:04 SeniorDoctorHui

@mtzqc 问个问题,frameBuffer这个变量是什么类型?

SeniorDoctorHui avatar Apr 06 '22 02:04 SeniorDoctorHui

frameBuffer

ByteBuffer

mtzqc avatar Apr 06 '22 04:04 mtzqc