You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:15:53