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

Android10+用Camera2 API+MediaRecorder录像prepare报-2147483648错误

问题根因与解决方案

1. 前台服务配置修正(你猜测的点是核心原因之一)

Android 10(API 29)及以上版本要求,使用前台服务访问相机、麦克风时必须显式声明服务类型:

  • 修改AndroidManifest.xml中服务声明,添加foregroundServiceType属性:
<service android:name="xyz.kumaraswamy.procam.CameraService"
    android:exported="true"
    android:foregroundServiceType="camera|microphone"/>
  • 调用startForeground启动服务时,Android 10及以上版本需要传入对应服务类型参数:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
    startForeground(通知ID, 通知实例, 
        ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA | ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE);
} else {
    startForeground(通知ID, 通知实例);
}

2. MediaRecorder参数设置错误

你当前的参数设置顺序不符合MediaRecorder的要求,且存在冗余调用,是日志中Failed to create video encoder的直接原因:

  • 必须先设置音视频编码器,再设置编码器相关的参数(比特率、分辨率、帧率)
  • 使用VideoSource.SURFACE配合Camera2 API时,不需要调用setPreviewDisplay,该方法是旧Camera1 API的接口,会引发Surface冲突
    修正后的参数配置代码:
mediaRecorder = new MediaRecorder();
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
// 先设置编码器
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
// 再设置编码器相关参数
mediaRecorder.setVideoSize(videoDimension.getWidth(), videoDimension.getHeight());
mediaRecorder.setVideoFrameRate(30);
mediaRecorder.setVideoEncodingBitRate(1000000);
mediaRecorder.setOutputFile(new File(recordingPath).getAbsolutePath());
// 删除下面这行冗余代码
// mediaRecorder.setPreviewDisplay(this.previewSurface);

3. 分区存储适配

如果你的录像文件保存路径是外部公共目录(比如DCIM、Download目录),Android 10及以上版本不能直接用普通File路径写入,会导致输出文件创建失败,触发prepare错误:

  • 保存到公共目录需要使用MediaStore创建文件,传入文件描述符给MediaRecorder:
ContentValues values = new ContentValues();
values.put(MediaStore.Video.Media.RELATIVE_PATH, Environment.DIRECTORY_DCIM + "/你的应用目录名");
values.put(MediaStore.Video.Media.MIME_TYPE, "video/3gpp");
values.put(MediaStore.Video.Media.DISPLAY_NAME, "record_" + System.currentTimeMillis() + ".3gp");
Uri uri = getContentResolver().insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, values);
ParcelFileDescriptor pfd = getContentResolver().openFileDescriptor(uri, "w");
mediaRecorder.setOutputFile(pfd.getFileDescriptor());

如果是保存到应用私有目录(/data/data/包名/xxx)则不需要做该适配。

4. 可选:参数合法性校验

可以调用CamcorderProfile.hasProfile(摄像头ID, CamcorderProfile.QUALITY_XXX)确认当前设备的摄像头支持你设置的分辨率、帧率、编码器组合,避免设置了设备不支持的参数导致编码器创建失败。

内容的提问来源于stack exchange,提问作者Alien tackers

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.13 12:24:03