错误:Camera录制视频(6.0错误),5.1正常,7.1正常 (java.lang.RuntimeException: start failed.at android.media.MediaRecorder.native_start(Native Method))

   Process: com.example.mycamera2, PID: 24086
              java.lang.RuntimeException: start failed.
                    at android.media.MediaRecorder.native_start(Native Method)
                    at android.media.MediaRecorder.start(MediaRecorder.java:1157)
                    at com.example.mycamera2.CameraUtils.startRecord(CameraUtils.java:161)
                    at com.example.mycamera2.MainActivity$1.onClick(MainActivity.java:88)
                    at android.view.View.performClick(View.java:5264)
                    at android.view.View$PerformClick.run(View.java:21297)
                    at android.os.Handler.handleCallback(Handler.java:743)
                    at android.os.Handler.dispatchMessage(Handler.java:95)
                    at android.os.Looper.loop(Looper.java:150)
                    at android.app.ActivityThread.main(ActivityThread.java:5621)
                    at java.lang.reflect.Method.invoke(Native Method)
                    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:794)
                 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:684)

 code:

package com.example.mycamera2;

import android.content.Context;
import android.hardware.Camera;
import android.media.CamcorderProfile;
import android.media.MediaCodec;
import android.media.MediaRecorder;
import android.os.Environment;
import android.os.StatFs;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import java.io.File;
import java.io.IOException;
import java.util.List;

import static android.content.ContentValues.TAG;

/**
 * Created by guoxw on 2017/10/31.
 */

public class CameraUtils {



    private MediaRecorder mediaRecorder;
    private Camera camera;
    private boolean isCheck;
    private SurfaceHolder.Callback callback;
    private Context context;
    private SurfaceView surfaceView;
    private int height=240,width=300;

    private MediaCodec mediaCodec;

    public void create(SurfaceView surfaceView, Context context) {
        this.context = context;
        this.surfaceView = surfaceView;
        surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        surfaceView.setKeepScreenOn(true);
        callback = new SurfaceHolder.Callback() {
            public void surfaceCreated(SurfaceHolder holder) {
                camera = Camera.open();
                getVideoSize();
                //setVideoFrameRate();
                mediaRecorder = new MediaRecorder();
            }
            public void surfaceChanged(SurfaceHolder holder, int format,
                                       int width, int height) {
                doChange(holder);
               // setVideoFrameRate();
            }
            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                if(camera!=null){
                    camera.release();
                    camera=null;
                }
            }
        };
        surfaceView.getHolder().addCallback(callback);

    }

    private void doChange(SurfaceHolder holder) {
        try {
            camera.setPreviewDisplay(holder);
            camera.setDisplayOrientation(0);
            camera.startPreview();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * startRecord 前调用一次,保证为前置摄像头
     */
    public void changeCamera() {
        int cameraCount = 0;
        Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
        cameraCount = Camera.getNumberOfCameras();
        for (int i = 0; i < cameraCount; i++) {
            Camera.getCameraInfo(i, cameraInfo);
            if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
                camera.stopPreview();
                camera.release();
                camera = null;
                camera = Camera.open(i);
                try {
                    camera.setPreviewDisplay(surfaceView.getHolder());
                    camera.setDisplayOrientation(0);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                camera.startPreview();
                isCheck = true;
                break;
            }
        }

    }

    public void stopRecord() {
        mediaRecorder.release();
        /****/
        camera.stopPreview();
        camera.release();
        mediaRecorder = null;
        camera = Camera.open();
        mediaRecorder = new MediaRecorder();
        doChange(surfaceView.getHolder());
    }

    public void destroy(){
        if(mediaRecorder!=null&&camera!=null){
            mediaRecorder.release();
            camera.release();
            mediaRecorder = null;
            camera=null;
        }

    }

    /**
     *
     * @param path 保存的路径
     * @param name  录像视频名称(不包含后缀)
     */
    public void startRecord(String path, String name) {
        camera.unlock();
        mediaRecorder.setCamera(camera);
        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
        mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
        //--mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_LOW));
        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        //--好像不起作用
        //mediaRecorder.setVideoFrameRate(14);
        mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
        mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
        mediaRecorder.setVideoEncodingBitRate(500*1024);
        mediaRecorder.setVideoSize(width, height);
//        setVideoFrameRate();
       // mediaRecorder.setVideoFrameRate(14);
        //--getVideoSize();
        File file = new File(path);
        if (!file.exists()) {
            file.mkdirs();
        }
        mediaRecorder.setOutputFile(path + File.separator + name + ".mp4");
        File file1=new File(path + File.separator + name + ".mp4");
        if(file1.exists()){
            file1.delete();
        }
        mediaRecorder.setPreviewDisplay(surfaceView.getHolder().getSurface());
        /***不设置时,录制的视频总是倒着,翻屏导致视频上下翻滚*/
        mediaRecorder.setOrientationHint(0);
        try {
            mediaRecorder.prepare();
            mediaRecorder.start();
        } catch (IOException e) {
            e.printStackTrace();
            Log.d(TAG, "startRecord: --"+e.getMessage());
        }
    }

    /***
     * 获取SupportedVideoSizes 控制输出视频width在300到600之间,选择最小的
     */
    public void getVideoSize(){
        Camera.Parameters parameters=camera.getParameters();
        List<Camera.Size> videoSize=parameters.getSupportedVideoSizes();
        if(videoSize!=null){
            for(int i=0;i<videoSize.size();i++){
                int width1=videoSize.get(i).width;
                int height1=videoSize.get(i).height;
                if(width1>=300&&width1<=500){
                    if(height1>=200&&height1<=500){
                        width=width1;
                        height=height1;
                        break;
                    }

                }
                Log.d(TAG, "getVideoSize:----w:-- "+videoSize.get(i).width+"---h:--"+videoSize.get(i).height);
            }
        }



    }


    /**
     * 没用
     */
    public void setVideoFrameRate(){
        CamcorderProfile cProfile = CamcorderProfile.get(CamcorderProfile.QUALITY_TIME_LAPSE_LOW);
        mediaRecorder.setProfile(cProfile);
        //设置录制的视频帧率,注意文档的说明:
        mediaRecorder.setVideoFrameRate(20);
    }

    /**
     * 获取手机内存可用大小 (返回kb值)
     */
    public long getAvailableBlicks(){
        File path = Environment.getDataDirectory();
        StatFs stat = new StatFs(path.getPath());
        long blockSize = stat.getBlockSize();
        long Blocks = stat.getAvailableBlocks();
        long size=blockSize*Blocks/1024;
       return size;
    }
}

  

 btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(x==0){
                    cameraUtils.changeCamera();
                    cameraUtils.startRecord(path,name);
                    image.setVisibility(View.INVISIBLE);
                    btn.setImageResource(R.drawable.camera_begain);
                    x=1;
                } else if(x==1){
                    cameraUtils.stopRecord();
                    image.setVisibility(View.VISIBLE);
                    btn.setImageResource(R.drawable.camera_stop);
                    x=0;
                }

            }
        });

 

 

 

 结论:

  方法: public void getVideoSize()获取手机支持的分辨率时,获得到的 List<Camera.Size> videoSize这个
   结果集为null,导致seartRecord方法中的 mediaRecorder.setVideoSize(width, height)设置的宽高不支持。
  至于getVideoSize返回为null的原因,待查。

 

public List<Size> getSupportedVideoSizes() {
            String str = get(KEY_VIDEO_SIZE + SUPPORTED_VALUES_SUFFIX);
            return splitSize(str);
        }
		
		
		
		
private ArrayList<Size> splitSize(String str) {
            if (str == null) return null;

            TextUtils.StringSplitter splitter = new TextUtils.SimpleStringSplitter(',');
            splitter.setString(str);
            ArrayList<Size> sizeList = new ArrayList<Size>();
            for (String s : splitter) {
                Size size = strToSize(s);
                if (size != null) sizeList.add(size);
            }
            if (sizeList.size() == 0) return null;
            return sizeList;
 }

 

  

 

posted @ 2017-11-16 15:47  咖喱不见不散啊  阅读(2407)  评论(1编辑  收藏  举报