首页 > 解决方案 > MediaRecorder:在无效状态下恢复调用:1

问题描述

本课程是为使用媒体记录器录制视频而编写的,然后我尝试在录制时暂停和恢复

我在 mediaRecorder.resume() 上收到 IllegalStateException;

我也阅读了文档,但无法解决错误 https://developer.android.com/reference/android/media/MediaRecorder

任何人都可以帮助我,提前谢谢

有我的代码

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
    binding = DataBindingUtil.setContentView(this, R.layout.activity_camera);
    mContext = this;
    initControls();
    identifyOrientationEvents();


    folder = new File(Environment.getExternalStorageDirectory() + File.separator + "/Media/sent");
    if (!folder.exists()) {
        folder.mkdirs();
    }

    captureImageCallback();
    if (camera != null) {
        Camera.CameraInfo info = new Camera.CameraInfo();
        if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
            imgFlashOnOff.setVisibility(View.GONE);
        }
    }

}

@SuppressLint("ClickableViewAccessibility")
private void initControls() {
    mediaRecorder = new MediaRecorder();

    binding.imgSurface.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                try {
                    setAutoFocus();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return false;
        }
    });
}


@Override
protected void onResume() {
    super.onResume();
    try {
        if (myOrientationEventListener != null)
            myOrientationEventListener.enable();
    } catch (Exception e1) {
        e1.printStackTrace();
    }
    UserModel.getInstance().lastPostTime = 0;
    binding.gallery.setVisibility(View.VISIBLE);
    // binding.squareIcon.setVisibility(View.VISIBLE);
}


private void cancelSavePicTaskIfNeed() {
    if (savePicTask != null && savePicTask.getStatus() == AsyncTask.Status.RUNNING) {
        savePicTask.cancel(true);
    }
}

private void cancelSaveVideoTaskIfNeed() {
    if (saveVideoTask != null && saveVideoTask.getStatus() == AsyncTask.Status.RUNNING) {
        saveVideoTask.cancel(true);
    }
}


private class SaveVideoTask extends AsyncTask<Void, Void, Void> {

    File thumbFilename;
    ProgressDialog progressDialog = null;

    @Override
    protected void onPreExecute() {
        progressDialog = new ProgressDialog(CameraActivity.this);
        progressDialog.setMessage("Processing a video...");
        progressDialog.show();
        super.onPreExecute();
        imgCapture.setOnTouchListener(null);
        textCounter.setVisibility(View.GONE);
        imgSwipeCamera.setVisibility(View.VISIBLE);
        imgFlashOnOff.setVisibility(View.VISIBLE);
        binding.recordButton.setImageResource(R.drawable.capturecamera);
    }

    @RequiresApi(api = Build.VERSION_CODES.N)
    @Override
    protected Void doInBackground(Void... params) {

                myOrientationEventListener.enable();
                customHandler.removeCallbacksAndMessages(null);
        try {
            mediaRecorder.stop();
        } catch (RuntimeException e) {
            e.printStackTrace();
        }

        tempFile = new File(folder.getAbsolutePath() + "/" + mediaFileName + ".mp4");
                thumbFilename = new File(folder.getAbsolutePath(), "VID_Thumb_" + mediaFileName + ".jpeg");
                // generateVideoThmb(tempFile.getPath(), thumbFilename);



        return null;
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);
        releaseMediaRecorder();
        if (progressDialog != null) {
            if (progressDialog.isShowing()) {
                progressDialog.dismiss();
            }
        }
        if (tempFile != null && thumbFilename != null)
            onVideoSendDialog(tempFile.getAbsolutePath(), thumbFilename.getAbsolutePath());
    }
}


private void setAutoFocus() {
    camera.autoFocus(new Camera.AutoFocusCallback() {
        @Override
        public void onAutoFocus(final boolean success, final Camera camera) {
            mHandler.removeCallbacksAndMessages(null);
            mHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    synchronized (mCameraLock) {
                        if (camera != null) {
                            camera.cancelAutoFocus();
                            Camera.Parameters parameters = camera.getParameters();
                            if (parameters == null) return;

                            if (parameters.getFocusMode() != Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE) {
                                parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
                                parameters.setFocusAreas(null);
                                parameters.setMeteringAreas(null);
                                camera.setParameters(parameters);
                            }

                            if (mAutofocusCallback != null) {
                                mAutofocusCallback.onAutoFocus(success, camera);
                            }
                        }
                    }
                }
            }, 10);
        }
    });
}

@Override
public void onBackPressed() {
    super.onBackPressed();
    cancelSavePicTaskIfNeed();

        finish();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

@Override
public void onClick(View v) {
    if (v == binding.btnOk) {
        cancelSaveVideoTaskIfNeed();
        saveVideoTask = new SaveVideoTask();
        saveVideoTask.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
    }

    if (v == binding.flash) {
        flashToggle();
    }

    if (v == binding.flipCamera) {
        camera.stopPreview();
        camera.release();
        if (flag == 0) {
            imgFlashOnOff.setVisibility(View.GONE);
            flag = 1;
        } else {
            imgFlashOnOff.setVisibility(View.VISIBLE);
            flag = 0;
        }
        surfaceCreated(surfaceHolder);
    }


}



private void flashToggle() {
    if (flashType == 1) {
        flashType = 2;
    } else if (flashType == 2) {
        flashType = 3;
    } else if (flashType == 3) {
        flashType = 1;
    }
    refreshCamera();
}


private void releaseMediaRecorder() {
    if (mediaRecorder != null) {
        mediaRecorder.reset();                                                                  // clear recorder configuration
        mediaRecorder.release();                                                                // release the recorder object
        mediaRecorder = new MediaRecorder();
    }
}

public void refreshCamera() {
    if (surfaceHolder.getSurface() == null) {
        return;
    }
    try {
        camera.stopPreview();
        Camera.Parameters param = camera.getParameters();

        if (flag == 0) {
            if (flashType == 1) {
                param.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
                imgFlashOnOff.setImageResource(R.drawable.ic_flash_auto_white_24dp);
            } else if (flashType == 2) {
                param.setFlashMode(Camera.Parameters.FLASH_MODE_ON);
                Camera.Parameters params;
                if (camera != null) {
                    params = camera.getParameters();

                    if (params != null) {
                        List<String> supportedFlashModes = params.getSupportedFlashModes();

                        if (supportedFlashModes != null) {
                            if (supportedFlashModes.contains(Camera.Parameters.FLASH_MODE_TORCH)) {
                                param.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
                            } else if (supportedFlashModes.contains(Camera.Parameters.FLASH_MODE_ON)) {
                                param.setFlashMode(Camera.Parameters.FLASH_MODE_ON);
                            }
                        }
                    }
                }
                imgFlashOnOff.setImageResource(R.drawable.ic_flash_on_white_24dp);
            } else if (flashType == 3) {
                param.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
                imgFlashOnOff.setImageResource(R.drawable.ic_flash_off_white_24dp);
            }
        }


        refrechCameraPriview(param);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

private void refrechCameraPriview(Camera.Parameters param) {
    try {
        camera.setParameters(param);
        setCameraDisplayOrientation(0);

        camera.setPreviewDisplay(surfaceHolder);
        camera.startPreview();

    } catch (Exception e) {
        e.printStackTrace();
    }
}

public void setCameraDisplayOrientation(int cameraId) {
    Camera.CameraInfo info = new Camera.CameraInfo();
    Camera.getCameraInfo(cameraId, info);
    int rotation = getWindowManager().getDefaultDisplay().getRotation();
    if (Build.MODEL.equalsIgnoreCase("Nexus 6") && flag == 1) {
        rotation = Surface.ROTATION_180;
    }
    int degrees = 0;
    switch (rotation) {
        case Surface.ROTATION_0:
            degrees = 0;
            break;
        case Surface.ROTATION_90:
            degrees = 90;
            break;
        case Surface.ROTATION_180:
            degrees = 180;
            break;
        case Surface.ROTATION_270:
            degrees = 270;
            break;
    }
    int result;
    if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
        result = (info.orientation + degrees) % 360;
        result = (360 - result) % 360; // compensate the mirror
    } else {
        result = (info.orientation - degrees + 360) % 360;
    }
    camera.setDisplayOrientation(result);
}

//------------------SURFACE CREATED FIRST TIME--------------------//
int flashType = 1;

@Override
public void surfaceCreated(SurfaceHolder arg0) {
    try {
        if (flag == 0) {
            camera = Camera.open(0);
        } else {
            camera = Camera.open(1);
        }
    } catch (RuntimeException e) {
        e.printStackTrace();
        return;
    }
    try {
        Camera.Parameters param;
        param = camera.getParameters();
        List<Camera.Size> sizes = param.getSupportedPreviewSizes();
        //get diff to get perfact preview sizes
        DisplayMetrics displaymetrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
        int height = displaymetrics.heightPixels;
        int width = displaymetrics.widthPixels;
        long diff = (height * 1000 / width);
        long cdistance = Integer.MAX_VALUE;
        int idx = 0;
        for (int i = 0; i < sizes.size(); i++) {
            long value = (long) (sizes.get(i).width * 1000) / sizes.get(i).height;
            if (value > diff && value < cdistance) {
                idx = i;
                cdistance = value;
            }
        }
        Camera.Size cs = sizes.get(idx);
        param.setPreviewSize(cs.width, cs.height);
        param.setPictureSize(cs.width, cs.height);
        if (camera != null) {
            camera.cancelAutoFocus();
            if (param == null) return;
            if (param.getFocusMode() != Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE) {
                param.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
                param.setFocusAreas(null);
                param.setMeteringAreas(null);
            }
        }
        camera.setParameters(param);
        setCameraDisplayOrientation(0);
        camera.setPreviewDisplay(surfaceHolder);
        camera.startPreview();
        if (flashType == 1) {
            param.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
            imgFlashOnOff.setImageResource(R.drawable.ic_flash_auto_white_24dp);
        } else if (flashType == 2) {
            param.setFlashMode(Camera.Parameters.FLASH_MODE_ON);
            Camera.Parameters params;
            if (camera != null) {
                params = camera.getParameters();
                if (params != null) {
                    List<String> supportedFlashModes = params.getSupportedFlashModes();
                    if (supportedFlashModes != null) {
                        if (supportedFlashModes.contains(Camera.Parameters.FLASH_MODE_TORCH)) {
                            param.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
                        } else if (supportedFlashModes.contains(Camera.Parameters.FLASH_MODE_ON)) {
                            param.setFlashMode(Camera.Parameters.FLASH_MODE_ON);
                        }
                    }
                }
            }
            imgFlashOnOff.setImageResource(R.drawable.ic_flash_on_white_24dp);
        } else if (flashType == 3) {
            param.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
            imgFlashOnOff.setImageResource(R.drawable.ic_flash_off_white_24dp);
        }
    } catch (Exception e) {
        e.printStackTrace();
        return;
    }
}

@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
    try {
        camera.stopPreview();
        camera.release();
        camera = null;
    } catch (Exception e) {
        e.printStackTrace();
    }
}

@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
    refreshCamera();
}
@Override
protected void onPause() {
    super.onPause();
    try {
        if (customHandler != null)
            customHandler.removeCallbacksAndMessages(null);
        releaseMediaRecorder();                                                                

        if (myOrientationEventListener != null)
            myOrientationEventListener.enable();
    } catch (Exception e) {
        e.printStackTrace();
    }
}


private void activeCameraCapture() {
    if (imgCapture != null) {
        imgCapture.setAlpha(1.0f);
        imgCapture.setOnLongClickListener(new View.OnLongClickListener() {
            @RequiresApi(api = Build.VERSION_CODES.N)
            @SuppressLint("ClickableViewAccessibility")
            @Override
            public boolean onLongClick(View v) {
                binding.gallery.setVisibility(View.GONE);
                try {
                    if (secs < 0) {
                        if (prepareMediaRecorder()) {
                            isTimeUp = true;
                            isRecordingOn = true;
                            myOrientationEventListener.disable();
                            mediaRecorder.start();
                            startTime = SystemClock.uptimeMillis();
                            binding.recordButton.setImageResource(R.drawable.camera_start_rec);
                            customHandler.postDelayed(updateTimerThread, 0);
                        } else {
                            return false;
                        }
                    } else {

                        try {
                            mediaRecorder.resume();
                        } catch (IllegalStateException e) {
                            e.printStackTrace();
                        }
                        isRecordingOn = true;
                        customHandler.postDelayed(updateTimerThread, 0);
                        binding.recordButton.setImageResource(R.drawable.camera_start_rec);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                textCounter.setVisibility(View.GONE);
                imgSwipeCamera.setVisibility(View.GONE);
                imgFlashOnOff.setVisibility(View.GONE);
                scaleUpAnimation();
                imgCapture.setOnTouchListener(new View.OnTouchListener() {
                    @RequiresApi(api = Build.VERSION_CODES.N)
                    @Override
                    public boolean onTouch(View v, MotionEvent event) {
                        if (event.getAction() == MotionEvent.ACTION_BUTTON_PRESS) {
                            return true;
                        }
                        if (event.getAction() == MotionEvent.ACTION_UP) {
                            scaleDownAnimation();


                            imgCapture.setOnTouchListener(null);
                            textCounter.setVisibility(View.GONE);
                            imgSwipeCamera.setVisibility(View.VISIBLE);
                            imgFlashOnOff.setVisibility(View.VISIBLE);

                            binding.ivSettings.setVisibility(View.GONE);

                            binding.recordButton.setImageResource(R.drawable.capturecamera);
                            if (mediaRecorder != null) {
                                try {
                                    isRecordingOn = false;

                                    mediaRecorder.pause();
                                    releaseMediaRecorder();
                                } catch (IllegalStateException e) {
                                    e.printStackTrace();
                                } catch (RuntimeException e) {
                                    e.printStackTrace();
                                }
                            }
                            if (secs < 5) {
                                Toast.makeText(CameraActivity.this, "Go for it! Record at least 5 seconds ", Toast.LENGTH_SHORT).show();
                                return false;
                            } else {
                                binding.btnOk.setVisibility(View.VISIBLE);
                                return true;
                            }
                        }
                        return true;

                    }
                });
                return true;
            }

        });

    }
}

public void onVideoSendDialog(final String videopath, final String thumbPath) {
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            if (videopath != null) {
                File fileVideo = new File(videopath);
                long fileSizeInBytes = fileVideo.length();
                long fileSizeInKB = fileSizeInBytes / 1024;
                long fileSizeInMB = fileSizeInKB / 1024;
                if (fileSizeInMB > MAX_VIDEO_SIZE_UPLOAD) {
                    new android.support.v7.app.AlertDialog.Builder(CameraActivity.this)
                            .setMessage(getString(R.string.file_limit_size_upload_format, MAX_VIDEO_SIZE_UPLOAD))
                            .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    dialog.dismiss();
                                }
                            })
                            .show();
                } else {


                }
            }
        }
    });
}

private void inActiveCameraCapture() {
    if (imgCapture != null) {
        imgCapture.setAlpha(0.5f);
        imgCapture.setOnClickListener(null);
    }
}



public int getFreeSpacePercantage() {
    int percantage = (int) (freeMemory() * 100 / totalMemory());
    int modValue = percantage % 3;
    return percantage - modValue;
}

public double totalMemory() {
    StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());
    double sdAvailSize = (double) stat.getBlockCount() * (double) stat.getBlockSize();
    return sdAvailSize / 107374182;
}

public double freeMemory() {
    StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());
    double sdAvailSize = (double) stat.getAvailableBlocks() * (double) stat.getBlockSize();
    return sdAvailSize / 107374182;
}

public boolean isSpaceAvailable() {
    if (getFreeSpacePercantage() >= 1) {
        return true;
    } else {
        return false;
    }
}


@SuppressLint("SimpleDateFormat")
protected boolean prepareMediaRecorder() throws IOException {
    mediaRecorder = new MediaRecorder(); // Works well
    camera.stopPreview();
    camera.unlock();
    mediaRecorder.setCamera(camera);
    mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
    mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    if (flag == 1) {
        mediaRecorder.setProfile(CamcorderProfile.get(1, CamcorderProfile.QUALITY_480P));
    } else {
        mediaRecorder.setProfile(CamcorderProfile.get(0, CamcorderProfile.QUALITY_HIGH));
    }
    mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());
    mediaRecorder.setOrientationHint(mOrientation);

    if (Build.MODEL.equalsIgnoreCase("Nexus 6") && flag == 1) {

        if (mOrientation == 90) {
            mediaRecorder.setOrientationHint(mOrientation);
        } else if (mOrientation == 180) {
            mediaRecorder.setOrientationHint(0);
        } else {
            mediaRecorder.setOrientationHint(180);
        }

    } else if (mOrientation == 90 && flag == 1) {
        mediaRecorder.setOrientationHint(270);
    } else if (flag == 1) {
        mediaRecorder.setOrientationHint(mOrientation);
    }
    mediaFileName = "" + System.currentTimeMillis();
    mediaRecorder.setOutputFile(folder.getAbsolutePath() + "/" + mediaFileName + ".mp4"); // Environment.getExternalStorageDirectory()
    mediaRecorder.setOnInfoListener(new MediaRecorder.OnInfoListener() {
        public void onInfo(MediaRecorder mr, int what, int extra) {
            if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED) {
                long downTime = 0;
                long eventTime = 0;
                float x = 0.0f;
                float y = 0.0f;
                int metaState = 0;
                MotionEvent motionEvent = MotionEvent.obtain(
                        downTime,
                        eventTime,
                        MotionEvent.ACTION_UP,
                        0,
                        0,
                        metaState
                );
                imgCapture.dispatchTouchEvent(motionEvent);
                Toast.makeText(CameraActivity.this, "You reached to Maximum(25MB) video size.", Toast.LENGTH_SHORT).show();
            }
        }
    });
    try {
        mediaRecorder.prepare();
    } catch (Exception e) {
        releaseMediaRecorder();
        e.printStackTrace();
        return false;
    }
    mediaRecorder.setOnInfoListener(new MediaRecorder.OnInfoListener() {
        @Override
        public void onInfo(MediaRecorder mr, int what, int extra) {
            Log.d("mRecoder", "onInfo:   "+what+"     extrs "+extra);

        }
    });
    return true;

}

OrientationEventListener myOrientationEventListener;
int iOrientation = 0;
int mOrientation = 90;

public void generateVideoThmb(String srcFilePath, File destFile) {
    try {
        Bitmap bitmap = ThumbnailUtils.createVideoThumbnail(srcFilePath, 120);
        FileOutputStream out = new FileOutputStream(destFile);
        ThumbnailUtils.extractThumbnail(bitmap, 200, 200).compress(Bitmap.CompressFormat.JPEG, 100, out);
        out.flush();
        out.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

private int normalize(int degrees) {
    if (degrees > 315 || degrees <= 45) {
        return 0;
    }
    if (degrees > 45 && degrees <= 135) {
        return 90;
    }
    if (degrees > 135 && degrees <= 225) {
        return 180;
    }
    if (degrees > 225 && degrees <= 315) {
        return 270;
    }
    throw new RuntimeException("Error....");
}

private int getPhotoRotation() {
    int rotation;
    int orientation = mPhotoAngle;
    if (mPhotoAngle == 90 || mPhotoAngle == 270) {
        orientation = 0;
    }
    Camera.CameraInfo info = new Camera.CameraInfo();
    if (flag == 0) {
        Camera.getCameraInfo(0, info);
    } else {
        Camera.getCameraInfo(1, info);
    }

    if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
        rotation = (info.orientation - orientation + 360) % 360;
    } else {
        rotation = (info.orientation + orientation) % 360;
    }
    return rotation;
}

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode == RESULT_OK) {
        if (requestCode == REQUEST_TAKE_GALLERY_VIDEO) {
            Uri selectedImageUri = data.getData();
            ContentResolver cr = mContext.getContentResolver();
            selectedImagePath = Utility.getUriPath(mContext, selectedImageUri);
            if (selectedImagePath.isEmpty()) {
                Toast.makeText(mContext, "Please select the file again..", Toast.LENGTH_SHORT).show();
                return;
            }
            String mime = Utility.getType(selectedImagePath);
            if (mime.contains("image")) {


            } else if (mime.contains("audio")) {
                Toast.makeText(mContext, "Please select only image or video.", Toast.LENGTH_LONG).show();
                return;
            } else if (mime.contains("video")) {
                if (selectedImagePath != null) {
                    int videoDuration = Utility.getMediaDuration(selectedImageUri, mContext);
                    if (videoDuration == 0) {
                        videoDuration = 30000;
                    }

                }
            } else {
                Toast.makeText(mContext, "Please select only image or video.", Toast.LENGTH_LONG).show();
                return;
            }
        }
    }
}

标签: androidmediarecorderandroid-mediarecorder

解决方案


推荐阅读