如何在三星设备android上录制特定宽度和高度的视频?

时间:2013-11-27 14:53:11

标签: android samsung-mobile android-mediarecorder

您好我正在制作一个Android应用程序,其中我使用自定义摄像头录制摄像头。我在三星设备上遇到问题。我无法将媒体记录器的配置文件设置为CamcorderProfile.get(cameraid, CamcorderProfile.QUALITY_HIGH)

也在尝试使用

profile = CamcorderProfile.get(cameraid, CamcorderProfile.QUALITY_LOW);
                       profile.videoFrameHeight=360;
                       profile.videoFrameWidth=640;

然后我的应用程序正在处理某些设备但在许多设备上崩溃。任何类型的帮助都会很明显。谢谢提前请检查代码

Camera.Parameters param = mCamera.getParameters();
            param.set( "cam_mode", 1 );  
         // Enable video stabilization. Convenience methods not available in API
            // level <= 14
            String vstabSupported = param.get("video-stabilization-supported");
            if ("true".equals(vstabSupported)) {
                param.set("video-stabilization", "true");
            }
            List<Size> sizes = mCamera.getParameters() .getSupportedVideoSizes();
            mCamera.setParameters( param );
            mMediaRecorder = new MediaRecorder();
            // Step 1: Unlock and set camera to MediaRecorder
            mCamera.unlock();
            mMediaRecorder.setCamera(mCamera);
            mMediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface());
            // Step 2: Set sources
            mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
            mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
            String deviceMan = android.os.Build.MANUFACTURER;
            Toast.makeText(getApplicationContext(), deviceMan, Toast.LENGTH_SHORT).show();
            // Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
            CamcorderProfile profile = CamcorderProfile.get(cameraid, CamcorderProfile.QUALITY_LOW);
//          if(!CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_HIGH)){Log.d("", "the camcorder profile instance is null");
            int currentapiVersion = android.os.Build.VERSION.SDK_INT;
            if (currentapiVersion >= android.os.Build.VERSION_CODES.FROYO){
                // Do something for froyo and above versions
                 boolean tellbol=CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_HIGH);
                 if(deviceMan.equals("samsung")){
                       profile = CamcorderProfile.get(cameraid, CamcorderProfile.QUALITY_LOW);
                       profile.videoFrameHeight=360;
                       profile.videoFrameWidth=640;
                 }
                 else{
                        profile = CamcorderProfile.get(cameraid, CamcorderProfile.QUALITY_HIGH);
                 }
                 mMediaRecorder.setProfile(profile);
            } else{
                // do something for phones running an SDK before froyo
                mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
                mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
//              mMediaRecorder.setVideoSize(720, 480);
                mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
            }

            // Step 4: Set output file
            mMediaRecorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).toString());
            // Step 5: Set the preview output
            // Step 6: Prepare configured MediaRecorder
            try {
                mMediaRecorder.prepare();
            } catch (IllegalStateException e) {
                Log.d("Video", "IllegalStateException preparing MediaRecorder: " + e.getMessage());
                releaseMediaRecorder();
                return false;
            } catch (IOException e) {
                Log.d("Video", "IOException preparing MediaRecorder: " + e.getMessage());
                releaseMediaRecorder();
                return false;
            }
            return true;

2 个答案:

答案 0 :(得分:38)

这是因为您要请求所需的尺寸,但并非所有尺寸都能满足每个尺寸。

此外,某些设备的相机纵横比稍有不同,因此如果您要求的比例错误,或者尺寸与支持的尺寸不同,则会在某些设备中崩溃。

怎么办?

第1步。

您必须检查支持的尺寸。你可以用

来做
Camera.Parameters p = myCamera.getParameters(); 
List<Size> previewsizes = p.getSupportedPreviewSizes();
List<Size> videosizes = p.getSupportedVideoSizes();

然后,你可以选择一个。如果您想自动化这个,您可以更进一步,并按照

第2步

编写一个函数来选择最佳可用大小,它将获得支持的大小和所需的大小,如:

private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
        final double ASPECT_TOLERANCE = 0.2;
        double targetRatio = (double) w / h;
        if (sizes == null)
            return null;

        Size optimalSize = null;
        double minDiff = Double.MAX_VALUE;

        int targetHeight = h;

        // Try to find an size match aspect ratio and size
        for (Size size : sizes) {
            Log.d("Camera", "Checking size " + size.width + "w " + size.height
                    + "h");
            double ratio = (double) size.width / size.height;
            if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
                continue;
            if (Math.abs(size.height - targetHeight) < minDiff) {
                optimalSize = size;
                minDiff = Math.abs(size.height - targetHeight);
            }
        }

        // Cannot find the one match the aspect ratio, ignore the
        // requirement
        if (optimalSize == null) {
            minDiff = Double.MAX_VALUE;
            for (Size size : sizes) {
                if (Math.abs(size.height - targetHeight) < minDiff) {
                    optimalSize = size;
                    minDiff = Math.abs(size.height - targetHeight);
                }
            }
        }
        return optimalSize;
    }

最后一步,设置参数

第3步

private int desiredwidth=640, desiredheight=360; 

Size optimalPreviewSize = getOptimalPreviewSize(previewsizes, desiredwidth, desiredheight);         

Size optimalVideoSize = getOptimalPreviewSize(videosizes, desiredwidth, desiredheight);      

p.setPreviewSize(optimalPreviewSize.width, optimalPreviewSize.height);

 mCamera.unlock();
 mMediaRecorder = new MediaRecorder();
 mMediaRecorder.setCamera(mCamera);

 mMediaRecorder.setVideoSize(optimalVideoSize.width, optimalVideoSize.height);
 myCamera.setParameters(p);

有了这个,你的相机应用程序将在每台带摄像头的设备上运行!

更新

使用我编写的getOptimalPreviewSize,你得到的比例更接近所需的大小,如果没有足够好,你得到一个高度接近所需的大小。如果你想提供更大的重量,你可以做一个简单的改变,比如

private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
    final double ASPECT_TOLERANCE = 0.2;
    double targetRatio = (double) w / h;
    if (sizes == null)
        return null;

    Size optimalSize = null;
    double minDiff = Double.MAX_VALUE;

    int targetHeight = h;

   if (  you want ratio as closed to what i asked for)
   {  for (Size size : sizes) {
        Log.d("Camera", "Checking size " + size.width + "w " + size.height
                + "h");
        double ratio = (double) size.width / size.height;
        if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
            continue;
        if (Math.abs(size.height - targetHeight) < minDiff) {
            optimalSize = size;
            minDiff = Math.abs(size.height - targetHeight);
        }
    }
   }

   if (you want height as closed to what i asked for) { //you can do other for width
        minDiff = Double.MAX_VALUE;
        for (Size size : sizes) {
            if (Math.abs(size.height - targetHeight) < minDiff) {
                optimalSize = size;
                minDiff = Math.abs(size.height - targetHeight);
            }
        }
    }

   if (you want the bigest one) { 
       minDiff = 0;
       for (Size size : sizes) {
           if (  size.height * size.width > minDiff ) {
               optimalSize = size;
               minDiff = size.height * size.width ;
           }
       }
   }
  return optimalSize;
}

答案 1 :(得分:0)

使用参数可以设置视频预览宽度和高度..

        Camera.Parameters param = camera.getParameters();

        param.setPreviewSize("your width"
                "your height");
        camera.setParameters(param);