Zhaoss / WeiXinRecordedDemo

仿微信视频拍摄UI, 基于ffmpeg的视频录制编辑

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

多个手机出现抖动问题,请问怎么解决

Zhangxd77 opened this issue · comments

commented

在华为、荣耀、OPPO这几个手机里都出现了视频抖动,
平滑的录制的,但是预播放时候就是画面抖了,请问怎么解决,谢谢

commented

修改RecordUtil.encodeVideo()方法可以解決抖动,但是解决不了时长变长的问题

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();
    }
}
commented

不好意思,用您这个替换后,
是不会抖动了,但是画面出现类似马赛克效果,而且很虚
机型是oppo a5