暂停/恢复MediaCodec

9
我是一名有用的助手,可以为您翻译文本。
我正在尝试为我的应用程序实现暂停/恢复功能,该应用程序使用MediaCodec记录显示捕获。我尝试过在没有调用mEncoder.release()的情况下执行mEncoder.stop(),然后再执行mEncoder.start(),但这并没有起作用。当再次调用mEncoder.start()时,我会收到IllegalStateException。目前,我已经实现了一个解决方法,即在捕获完成后合并视频块,但是合并需要很长时间。有人能帮我吗?也许有人已经实现了这个功能?
初始化:
    MediaCodec mEncoder;
    mEncoder = MediaCodec.createEncoderByType(Preferences.MIME_TYPE);
    mEncoder.configure(mFormat, null, null,
            MediaCodec.CONFIGURE_FLAG_ENCODE);
    mInputSurface = new InputSurface(mEncoder.createInputSurface(),
            mSavedEglContext);
    mEncoder.start();
    try {
        String fileId = String.valueOf(System.currentTimeMillis());
        mMuxer = new MediaMuxer(dir.getPath() + "/Video"
                + fileId + ".mp4",
                MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
        videoParts.add(fileId);
    } catch (IOException ioe) {
        throw new RuntimeException("MediaMuxer creation failed", ioe);
    }
    isRecording = true;

暂停:

    public void pauseRecordPressed() {
    if (isRecording){
        isRecording = false;
        drainEncoder(false);

        if (mEncoder != null) {
            mEncoder.stop();
        }
    }
}

取消暂停:

    public void resumeRecordPressed() {
    mEncoder.start();
    isRecording = true;
}

异常:

01-09 15:34:27.980: E/AndroidRuntime(21467): FATAL EXCEPTION: main
01-09 15:34:27.980: E/AndroidRuntime(21467): Process: com.example.poc, PID: 21467
01-09 15:34:27.980: E/AndroidRuntime(21467): java.lang.IllegalStateException: start failed
01-09 15:34:27.980: E/AndroidRuntime(21467):    at android.media.MediaCodec.start(Native Method)
01-09 15:34:27.980: E/AndroidRuntime(21467):    at com.example.poc.MyRenderer.resumeRecordPressed(MyRenderer.java:501)
01-09 15:34:27.980: E/AndroidRuntime(21467):    at com.example.poc.MyGLSurfaceView.resumeRecordPressed(MyGLSurfaceView.java:243)
01-09 15:34:27.980: E/AndroidRuntime(21467):    at com.example.poc.MainActivity.onClick(MainActivity.java:775)
01-09 15:34:27.980: E/AndroidRuntime(21467):    at android.view.View.performClick(View.java:4438)
01-09 15:34:27.980: E/AndroidRuntime(21467):    at android.view.View$PerformClick.run(View.java:18422)
01-09 15:34:27.980: E/AndroidRuntime(21467):    at android.os.Handler.handleCallback(Handler.java:733)
01-09 15:34:27.980: E/AndroidRuntime(21467):    at android.os.Handler.dispatchMessage(Handler.java:95)
01-09 15:34:27.980: E/AndroidRuntime(21467):    at android.os.Looper.loop(Looper.java:136)
01-09 15:34:27.980: E/AndroidRuntime(21467):    at android.app.ActivityThread.main(ActivityThread.java:5017)
01-09 15:34:27.980: E/AndroidRuntime(21467):    at java.lang.reflect.Method.invokeNative(Native Method)
01-09 15:34:27.980: E/AndroidRuntime(21467):    at java.lang.reflect.Method.invoke(Method.java:515)
01-09 15:34:27.980: E/AndroidRuntime(21467):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
01-09 15:34:27.980: E/AndroidRuntime(21467):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
01-09 15:34:27.980: E/AndroidRuntime(21467):    at dalvik.system.NativeStart.main(Native Method)

媒体格式:

mFormat = createMediaFormat();

    private static MediaFormat createMediaFormat() {
    MediaFormat format = MediaFormat.createVideoFormat(
            Preferences.MIME_TYPE, mScreenWidth, mScreenHeight);
    format.setInteger(MediaFormat.KEY_COLOR_FORMAT,
            MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
    format.setInteger(MediaFormat.KEY_BIT_RATE, Preferences.BIT_RATE);
    format.setInteger(MediaFormat.KEY_FRAME_RATE, Preferences.FRAME_RATE);
    format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL,
            Preferences.IFRAME_INTERVAL);
    return format;
}

一些你的代码会帮助我们找出问题。 - user3110424
mFormat 这个代码在哪里?你能放上去吗? - user3110424
嗨,Alex,我也遇到了同样的问题。如果你能分享解决方案(代码),那对我来说会非常有帮助。 - abhishek kumar gupta
2个回答

10
MediaCodec在停止后会丢弃其配置,因此您需要再次调用configure()。 我不确定您为什么要尝试重新启动它-您可以使其保持活动状态,而无需提供数据。

例如,请参见Grafika中的CameraCaptureActivity,该活动在重启时保留编码器的活动状态。 如果您不想在重新启动期间出现视频暂停,则需要跟踪编码暂停的时间,并相应地调整输入复用器的时间戳。


1
fadden,非常感谢!我按照您的建议做了,成功地去掉了视频部分之间的间隙。现在,合并后只有一个黑色帧。不过我认为无法消除它,对吗? - Alexey
明确一下,你是在执行停止/配置/启动操作,还是让它保持活动状态?我没有尝试过前者,所以不知道是否会出现黑框。 - fadden
我停止/配置/启动 - Alexey
好的...你有没有碰巧把“CODEC_CONFIG”帧写入流中?这通常是编码器开始后输出的第一件事。 - fadden
1
是的,那就是问题所在。我忘记在暂停/恢复后重置帧计数器了。再次感谢! - Alexey
显示剩余9条评论

3
private void suspendMediaCodec(boolean suspend)
{
    if(mediaCodec != null)
    {
        Bundle params = new Bundle();
        params.putInt(MediaCodec.PARAMETER_KEY_SUSPEND, suspend ? 1 : 0);
        mediaCodec.setParameters(params);
    }
}

您可以通过设置参数MediaCodec.PARAMETER_KEY_SUSPEND来挂起/恢复mediacodec以丢弃帧。上面的例子是执行此操作的示例。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接