android - android MediaRecorder 的 IllegalStateException

标签 android camera mediarecorder

我正在学习如何在 android 中对摄像机进行编程,并编写了一个非常基本的程序(带有 SurfaceView 的 XML 和两个按钮,一个用于启动,一个用于停止视频录制)。视频预览工作正常,但单击 start_video 按钮后,我在第 71 行收到 IllegalStateException mediaRecorder.setVideoFrameRate(videoFramesPerSecond);:

IllegalStateException.<init>() line: 33 
MediaRecorder.setVideoFrameRate(int) line: not available [native method]    
CamtestActivity$2.onClick(View) line: 71

。我不明白为什么这一行会抛出此异常,而前一行则不会。 有什么提示吗?谢谢。

package com.grapp.camtest;

import java.io.IOException;

import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.hardware.Camera;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.Toast;

public class CamtestActivity extends Activity implements SurfaceHolder.Callback{
    private static final String TAG = "Camera-Tutorial";

    private SurfaceView surfaceView;
    private SurfaceHolder surfaceHolder;
    private Camera camera;
    private boolean previewRunning;

    private MediaRecorder mediaRecorder;
    private final int maxDurationInMs = 20000;
    private final int videoFramesPerSecond = 20;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);

        setContentView(R.layout.main);

        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

        surfaceView = (SurfaceView) findViewById(R.id.surface_camera);
        surfaceHolder = surfaceView.getHolder();
        surfaceHolder.addCallback(this);
        surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);


        Button start_video = (Button) findViewById(R.id.start_video);
        Button stop_video = (Button) findViewById(R.id.stop_video);


        stop_video.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                mediaRecorder.stop();
                camera.lock();
            }
        });

        start_video.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    camera.unlock();

                    mediaRecorder = new MediaRecorder();
                    mediaRecorder.setCamera(camera);
                    mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
                    mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
                    mediaRecorder.setMaxDuration(maxDurationInMs);
                    mediaRecorder.setVideoFrameRate(videoFramesPerSecond);
                    mediaRecorder.setVideoSize(surfaceView.getWidth(), surfaceView.getHeight());
                    mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
                    mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface()); 
                    mediaRecorder.setOutputFile("/sdcard/video.mp4");
                    mediaRecorder.prepare();
                    mediaRecorder.start();
                } catch (IllegalStateException e) {
                    Log.e(TAG,e.getMessage());
                    e.printStackTrace();

                } catch (IOException e) {
                    Log.e(TAG,e.getMessage());
                    e.printStackTrace();
                }
            }
        });
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        camera = Camera.open();
        if (camera != null){
            Camera.Parameters params = camera.getParameters();
            camera.setParameters(params);
        }
        else {
            Toast.makeText(getApplicationContext(), "Camera not available!", Toast.LENGTH_LONG).show();
            finish();
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        if (previewRunning){
            camera.stopPreview();
        }
        Camera.Parameters p = camera.getParameters();
        p.setPreviewSize(width, height);
        camera.setParameters(p);

        try {
            camera.setPreviewDisplay(holder);
            camera.startPreview();
            previewRunning = true;
        }
        catch (IOException e) {
            Log.e(TAG,e.getMessage());
            e.printStackTrace();
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        camera.stopPreview();
        previewRunning = false;
        camera.release();
    }
}

最佳答案

来自 setVideoFrameRate() 的文档:

Sets the frame rate of the video to be captured.
Must be called after setVideoSource().
Call this after setOutFormat() but before prepare().

在尝试 setVideoFrameRate() 之前,您似乎尚未调用 setVideoSource()。尝试设置视频源,看看是否可以解决您的问题。

关于android - android MediaRecorder 的 IllegalStateException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6976802/

相关文章:

android - 内容 ://sms/sent/not working

从 AVCaptureSession 捕获的 iPhone 图像比例

Android M - MediaRecorder 启动失败

ios - 如何使用ALAssetLibrary在相机胶卷中获取本地照片

java - Android 录制内部设备声音

Android Mediarecorder setNextOutputFile IllegalStateException

java - 将数据(ArrayList)从 Activity 发送到 Fragment

android - 带有重命名的 SQLite 列的非法参数异常

java - 如何从 Firebase 检索 boolean 值到 TextView?

java - "Camera Error 1004"使用Android相机拍照时出错