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

Android一键音视频录制应用崩溃求助:RuntimeException start failed -22

解决Android音视频录制start failed -22异常

核心原因分析

RuntimeException: start failed -22 通常指向MediaRecorder参数配置不兼容——比如设备不支持所选的分辨率、帧率、编码格式,参数设置顺序错误,或是权限、Surface初始化未达标。

分步排查与修复方案

1. 严格遵循MediaRecorder参数设置顺序

参数初始化顺序错误是触发该异常的高频原因,正确流程必须按以下顺序执行:

mediaRecorder = new MediaRecorder();
// 1. 设置音频源
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
// 2. 设置视频源
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
// 3. 设置输出格式(必须在编码格式之前)
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
// 4. 设置音频编码格式
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
// 5. 设置视频编码格式
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
// 6. 设置视频分辨率、帧率、比特率
mediaRecorder.setVideoSize(1280, 720); // 需确认设备支持该分辨率
mediaRecorder.setVideoFrameRate(30);
mediaRecorder.setVideoEncodingBitRate(2 * 1024 * 1024);
// 7. 设置输出文件路径
mediaRecorder.setOutputFile(getOutputFilePath());
// 8. 设置预览Surface(如需预览)
mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());
// 9. 准备与启动
mediaRecorder.prepare();
mediaRecorder.start();

2. 验证设备支持的视频参数

不同设备支持的分辨率、帧率组合差异大,硬编码兼容性问题普遍。可通过以下代码获取设备支持的参数:

CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
try {
    String[] cameraIds = manager.getCameraIdList();
    for (String id : cameraIds) {
        CameraCharacteristics characteristics = manager.getCameraCharacteristics(id);
        StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
        Size[] sizes = map.getOutputSizes(MediaRecorder.class);
        // 遍历输出尺寸,选择设备支持的参数
        for (Size size : sizes) {
            Log.d("CameraSupport", "Supported size: " + size.getWidth() + "x" + size.getHeight());
        }
    }
} catch (CameraAccessException e) {
    e.printStackTrace();
}

选择列表中存在的分辨率,避免使用设备不支持的参数。

3. 检查权限配置

确保已申请并获取必要权限:

  • 动态申请:android.permission.RECORD_AUDIO、android.permission.CAMERA、android.permission.WRITE_EXTERNAL_STORAGE(Android 10及以下)
  • AndroidManifest.xml声明:
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="29" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />

4. 确认Surface初始化状态

若使用预览Surface,需确保Surface完全初始化后再传递给MediaRecorder。建议在SurfaceHolder.Callback的surfaceCreated或surfaceChanged回调中初始化MediaRecorder,避免Surface未就绪的情况。

5. 适配Android版本差异

  • Android 10及以上使用MediaStore存储文件,避免直接访问外部存储路径
  • Android 11+需注意分区存储限制,确保输出文件路径合法

完整示例代码片段

private MediaRecorder mediaRecorder;
private SurfaceHolder surfaceHolder;

private void initRecorder() {
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED
            || ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO}, 100);
        return;
    }

    mediaRecorder = new MediaRecorder();
    try {
        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
        mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);

        // 使用设备支持的分辨率,此处以720p为例,可替换为实际支持尺寸
        mediaRecorder.setVideoSize(1280, 720);
        mediaRecorder.setVideoFrameRate(30);
        mediaRecorder.setVideoEncodingBitRate(2 * 1024 * 1024);

        // 设置输出路径(Android 10+推荐使用应用私有目录)
        String outputPath = getExternalFilesDir(Environment.DIRECTORY_MOVIES) + "/record_" + System.currentTimeMillis() + ".mp4";
        mediaRecorder.setOutputFile(outputPath);

        if (surfaceHolder != null) {
            mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());
        }

        mediaRecorder.prepare();
        mediaRecorder.start();
    } catch (IOException e) {
        e.printStackTrace();
        releaseRecorder();
    } catch (RuntimeException e) {
        e.printStackTrace();
        releaseRecorder();
    }
}

private void releaseRecorder() {
    if (mediaRecorder != null) {
        try {
            mediaRecorder.stop();
        } catch (RuntimeException e) {
            // 处理录制未启动时的stop异常
        }
        mediaRecorder.release();
        mediaRecorder = null;
    }
}

额外注意事项

  • 录制完成后必须正确释放MediaRecorder资源,避免内存泄漏
  • 测试时覆盖不同品牌和版本设备,兼容性问题在不同厂商设备上表现不同
  • 若使用CameraX替代原生Camera API,可简化参数适配和兼容性处理

内容的提问来源于stack exchange,提问作者Priyabrata Nayak

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 19:10:53