本文介绍了使用MediaCodec和MediaMuxer录制视频,但码率和帧率不正确的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我编写了一个使用 MediaCodec 和 MediaMuxer 录制视频的演示.

I wrote a demo to record a video using MediaCodec and MediaMuxer.

我用我的演示录制了一个视频并使用 ffprobe 来检查视频,结果如下:

I record a video with my demo and use ffprobe to check the video,the result is as follows:

  Duration: 00:00:06.86, start: 0.000000, bitrate: 723 kb/s
Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 320x240, 619 kb/s, SAR 1:1 DAR 4:3, 30.02 fps, 30 tbr, 90k tbn, 180k tbc (default)
Metadata:
  creation_time   : 2015-06-05 13:19:24
  handler_name    : VideoHandle
Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, mono, fltp, 96 kb/s (default)
Metadata:
  creation_time   : 2015-06-05 13:19:24
  handler_name    : SoundHandle

里面包含了视频和音频信息,我发现音频属性和我在源码中设置的一样,但是视频属性就不行了.我的视频设置源码如下:

It contains video and audio information, I found the audio properties are the same as I set in the source code, but the video properties are not all right.My video settings source code is as follows:

        MediaFormat format = MediaFormat.createVideoFormat(MIME_TYPE, mWidth, mHeight);
    format.setInteger(MediaFormat.KEY_COLOR_FORMAT,
            MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
    format.setInteger(MediaFormat.KEY_BIT_RATE, 384000);
    format.setInteger(MediaFormat.KEY_FRAME_RATE, 19);
    format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 5);
    if (VERBOSE) Log.d(TAG, "format: " + format);
    mVideoEncoder = MediaCodec.createEncoderByType(MIME_TYPE);
    mVideoEncoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
    mInputSurface = mVideoEncoder.createInputSurface();
    mVideoEncoder.start();

视频的宽度和高度是正确的,但比特率和帧率高于我在源代码中设置的.这导致视频文件大小远大于我期望.然后,我修改了我的源代码以删除录音线程并仅录制视频.但它没有任何区别,比特率和帧率也更高.谁能告诉我原因并给我一些建议?

The width and height of the video are right but bitrate and framerate are higher than I set in source code. It results in that the video file size is much larger thanI expected.Then, I modified my source code to remove audio recording thread and just record the video only. But it didn't make any differences, the bitrate and framerate are also higher.Who can tell me the reason and give me some advices?

还有一个问题.我偶尔会录一段坏掉的视频,系统播放器可以播放,但是视频的开头是黑色的,1或2秒后显示正常图像.我不知道如何在stackoverflow中上传文件,我可以将损坏的视频文件发送给任何需要它的人.有人遇到过这个问题吗?

And there is another problem. I record a broken video occasionally which can be played by system player, but the begining of the video is just black and normal image displayed after 1 or 2 seconds. I don't know how to upload file in stackoverflow, I can send the broken video file to anyone who need it.Is there someone came with this problem?

添加:我发现了另一个奇怪的事情:我的视频编码配置:

ADD:I found another strange thing:My video encoding config:

private int mWidth = 480;
private int mHeight = 848;
private int mVideoBitrate = 1200 * 1000;

    MediaFormat format = MediaFormat.createVideoFormat(MIME_TYPE, 480, 848);

    format.setInteger(MediaFormat.KEY_COLOR_FORMAT,
            MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
    format.setInteger(MediaFormat.KEY_BIT_RATE, 1200000);
    format.setInteger(MediaFormat.KEY_FRAME_RATE, 30);
    format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1);

但实际的视频信息是:

  Duration: 00:00:06.01, start: 0.000000, bitrate: 6491 kb/s
Stream #0:0(eng): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, mono, fltp, 15 kb/s (default)
Metadata:
  creation_time   : 2015-09-30 15:44:18
  handler_name    : SoundHandle
Stream #0:1(eng): Video: h264 (Baseline) (avc1 / 0x31637661), yuv420p, 480x848, 6484 kb/s, SAR 1:1 DAR 30:53, 16 fps, 30 tbr, 90k tbn, 180k tbc (default)
Metadata:
  creation_time   : 2015-09-30 15:44:18
  handler_name    : VideoHandle

推荐答案

看起来您的预期帧速率 (19fps) 与实际帧速率 (30fps) 不匹配.编码器试图满足以 19fps 提交的帧的比特率要求,但它们的输入速度更快,因此未命中并且实际比特率更高.我假设 30fps 值是根据视频文件中的实际演示时间戳确定的,这些时间戳由传递给 MediaMuxer 的演示时间戳设置.如果您想要 19fps 的视频,则需要生成相隔 (1000/19) 毫秒的时间戳.

It looks like your expected frame rate (19fps) doesn't match the actual frame rate (30fps). The encoder is attempting to meet the bit rate requirements for frames submitted at 19fps, but they're coming in faster, so it misses and the actual bit rate is higher. I'm assuming the 30fps value is determined from the actual presentation time stamps in the video file, which are set by the presentation time stamps passed into MediaMuxer. If you want 19fps video, you need to generate time stamps that are (1000/19) milliseconds apart.

如果您的输入视频为 30fps,则需要在编码过程中丢帧才能达到 19fps.MediaCodec 不会为您丢帧——它会对您传入的所有内容进行编码.

If your input video is 30fps, you will need to drop frames during the encoding process to get to 19fps. MediaCodec does not drop frames for you -- it encodes everything you pass in.

我不知道为什么你会在视频开头看到一个破碎的部分.

I don't know why you'd be getting a broken section at the start of the video.

这篇关于使用MediaCodec和MediaMuxer录制视频,但码率和帧率不正确的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-23 15:06