Android前置摄像头录制视频分辨率异常:预览正常播放仅176×144求助
问题分析与解决方案
嗨,这个问题我遇见过不少次啦!核心原因是你只设置了相机预览的分辨率逻辑,但完全没给MediaRecorder指定录制视频的分辨率,导致系统默认用了最低的176×144分辨率,自然播放时就很小了。自带相机能正常录制480×640,是因为它自动适配了前置摄像头支持的最优录制参数。
下面给你一步步拆解问题和修改方案:
1. 先搞懂:预览分辨率 ≠ 录制分辨率
相机预览(FrameLayout显示的画面)和MediaRecorder录制的视频是两套独立参数控制的:
- 预览分辨率通过
Camera.Parameters.setPreviewSize()设置 - 录制视频的分辨率通过
MediaRecorder.setVideoSize()或者CamcorderProfile设置
你之前只处理了预览相关逻辑,完全没碰录制的参数,这就是问题根源。
2. 修改代码的关键步骤
步骤一:修复相机初始化的参数设置
你原来用parameters.set("orientation", "portrait")是非常老旧的写法,而且没有明确设置预览分辨率。改成这样,先获取前置摄像头支持的预览分辨率,选一个符合需求的尺寸:
for (int i = 0; i < Camera.getNumberOfCameras(); i++) { Camera.CameraInfo newInfo = new Camera.CameraInfo(); Camera.getCameraInfo(i, newInfo); if (newInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { mCamera = Camera.open(i); Camera.Parameters parameters = mCamera.getParameters(); // 替换老旧的orientation设置,改用标准旋转参数 parameters.setRotation(90); // 获取摄像头支持的预览分辨率列表,筛选目标尺寸(注意摄像头尺寸是横屏逻辑) List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes(); for (Camera.Size size : previewSizes) { // 这里找接近480×640的横屏尺寸(竖屏显示时对应640×480) if (size.width == 640 && size.height == 480) { parameters.setPreviewSize(size.width, size.height); break; } } mCamera.setParameters(parameters); mCamera.setDisplayOrientation(90); if (cameraDelegate != null) cameraDelegate.OnCameramCreated(); } }
步骤二:给MediaRecorder设置正确的录制参数
你注释掉了setProfile,但手动设置的参数里缺少了视频分辨率的关键配置。推荐两种可靠的设置方式:
方式一:用CamcorderProfile(简单且适配性好)
直接指定前置摄像头的高画质Profile,系统会自动帮你配置合适的分辨率、编码格式等参数:
private boolean prepareVideoRecorder(){ mMediaRecorder = new MediaRecorder(); mCamera.unlock(); mMediaRecorder.setCamera(mCamera); // 先设置视频源,再配置Profile(顺序不能乱) mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); CamcorderProfile profile = CamcorderProfile.get(Camera.CameraInfo.CAMERA_FACING_FRONT, CamcorderProfile.QUALITY_HIGH); mMediaRecorder.setProfile(profile); // 设置视频输出路径 mVideoPath = getOutputMediaFile(MEDIA_TYPE_VIDEO).toString(); mMediaRecorder.setOutputFile(mVideoPath); // 必须设置预览显示,否则录制可能失败(你之前注释掉了,要打开) try { mMediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface()); } catch (IOException e) { e.printStackTrace(); releaseMediaRecorder(); return false; } // 适配竖屏录制的方向 mMediaRecorder.setOrientationHint(90); // 准备录制 try { mMediaRecorder.prepare(); } catch (IllegalStateException e) { e.printStackTrace(); Log.d(TAG, "IllegalStateException preparing MediaRecorder: " + e.getMessage()); releaseMediaRecorder(); return false; } catch (IOException e) { e.printStackTrace(); Log.d(TAG, "IOException preparing MediaRecorder: " + e.getMessage()); releaseMediaRecorder(); return false; } return true; }
方式二:手动设置视频分辨率(需确认设备支持)
如果不想用Profile,手动设置的话必须先获取前置摄像头支持的录制分辨率,再配置给MediaRecorder:
private boolean prepareVideoRecorder(){ mMediaRecorder = new MediaRecorder(); mCamera.unlock(); mMediaRecorder.setCamera(mCamera); // 按顺序设置源、格式、编码器 mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); // 获取摄像头支持的录制分辨率列表,筛选目标尺寸 Camera.Parameters parameters = mCamera.getParameters(); List<Camera.Size> videoSizes = parameters.getSupportedVideoSizes(); if (videoSizes != null && !videoSizes.isEmpty()) { for (Camera.Size size : videoSizes) { if (size.width == 640 && size.height == 480) { mMediaRecorder.setVideoSize(size.width, size.height); break; } } } // 设置输出路径和预览显示 mVideoPath = getOutputMediaFile(MEDIA_TYPE_VIDEO).toString(); mMediaRecorder.setOutputFile(mVideoPath); try { mMediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface()); } catch (IOException e) { e.printStackTrace(); releaseMediaRecorder(); return false; } // 适配竖屏方向 mMediaRecorder.setOrientationHint(90); // 准备录制 try { mMediaRecorder.prepare(); } catch (IllegalStateException e) { e.printStackTrace(); Log.d(TAG, "IllegalStateException preparing MediaRecorder: " + e.getMessage()); releaseMediaRecorder(); return false; } catch (IOException e) { e.printStackTrace(); Log.d(TAG, "IOException preparing MediaRecorder: " + e.getMessage()); releaseMediaRecorder(); return false; } return true; }
3. 额外注意点
- 参数顺序不能乱:MediaRecorder的设置必须遵循固定顺序,比如先设置source,再设置格式/编码器,最后设置输出路径和prepare,顺序错误会抛出异常。
- 不要硬编码分辨率:不同设备支持的分辨率差异很大,一定要通过
getSupportedPreviewSizes()和getSupportedVideoSizes()获取列表后筛选,避免设置不支持的参数导致失败。 - 方向适配:录制时添加
setOrientationHint(90),保证播放时视频方向和预览一致。
按照上面的修改,你录制的视频应该就能和预览一样是480×640,用VideoView播放时也能正常显示了!
内容的提问来源于stack exchange,提问作者ManLok Wong
相关产品推荐
相关产品推荐

