![](/img/trans.png)
[英]MediaRecorder : IOexception prepare failed error . Help me please
[英]MediaRecorder IOException prepare failed
在升級到 AndroidX 並將目標 SDK 增加到版本 28 后,此 IOException 開始在我的 Android 應用程序中發生。
在此之前,相同的代碼運行良好。
這是一個電容器應用程序,並使用電容器錄像機插件。 在后台,這個插件使用了與android.media.MediaRecorder
交互的fancycamera java 庫。
這是調用 VideoRecorder.startRecording 時拋出的堆棧跟蹤,最終導致調用VideoRecorder.startRecording
:
I/IMediaRecorder: prepare (BpMediaRecorder client) in file frameworks/av/media/libmedia/IMediaRecorder.cpp, function prepare, line 253
E/MediaRecorder: prepare failed: -2147483648
W/System.err: java.io.IOException: prepare failed.
W/System.err: at android.media.MediaRecorder._prepare(Native Method)
W/System.err: at android.media.MediaRecorder.prepare(MediaRecorder.java:1038)
W/System.err: at co.fitcom.fancycamera.Camera2.setUpMediaRecorder(Camera2.java:607)
W/System.err: at co.fitcom.fancycamera.Camera2.startRecording(Camera2.java:837)
W/System.err: at co.fitcom.fancycamera.FancyCamera.startRecording(FancyCamera.java:323)
W/System.err: at com.github.sbannigan.capacitor.VideoRecorder.startRecording(VideoRecorder.java:267)
W/System.err: at java.lang.reflect.Method.invoke(Native Method)
W/System.err: at com.getcapacitor.PluginHandle.invoke(PluginHandle.java:99)
W/System.err: at com.getcapacitor.Bridge$1.run(Bridge.java:515)
W/System.err: at android.os.Handler.handleCallback(Handler.java:907)
W/System.err: at android.os.Handler.dispatchMessage(Handler.java:105)
W/System.err: at android.os.Looper.loop(Looper.java:216)
W/System.err: at android.os.HandlerThread.run(HandlerThread.java:65)
Android 應用程序正在請求 CAMERA 和 RECORD_AUDIO 權限,我可以確認首先提示用戶輸入這些權限。
AndroidManifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
我還可以看到在應用程序的數據目錄中創建了一個 output 文件。 但是該文件仍然是空的。 我也手動嘗試寫入同一個文件,這是可能的,所以文件 IO 似乎不是問題。
崩潰來自本機方法,因此調試器不是很有幫助。 但是,我至少可以確認 MediaRecorder 的mPath
變量在調用_prepare
之前似乎設置正確。
我創建了一個具有相同堆棧的示例應用程序,可以在其中重新創建錯誤: https://github.com/disbelief/video-recorder-test
我也有興趣了解MediaRecorder.prepare
拋出此異常的其他可能原因。
2022 年 6 月
我的錯誤非常簡單。 某些手機默認將相機分辨率作為屏幕尺寸,但其他手機則沒有。 這就是為什么在許多設備上它拋出prepare failed: -2147483648
MediaRecorder 的深度就是那個相機本身。 因此,您需要通過允許的大小。 顯然充其量是最大值(到mMediaRecorder.setVideoSize()
)
CameraPropeties props_ = new CameraPropeties(this);
int width_= = props_.getWidth();
int height_ = props_.getHeight();
...
mMediaRecorder.setVideoSize(width_,height_)
...
和相機屬性 class:
package <my.package>;
import android.content.Context;
import android.content.res.Configuration;
import android.media.CamcorderProfile;
import android.os.Build;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.WindowManager;
import androidx.annotation.RequiresApi;
import static android.content.Context.WINDOW_SERVICE;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
public class CameraPropeties {
private int _width;
private int _hight;
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void _getSupportedSizes() {
CameraInfo recordingInfo = _getRecordingInfo();
_width = recordingInfo.width;
_hight = recordingInfo.height;
Log.e("MaxSupportedSizes --", "WIDTH = " + recordingInfo.width + " HEIGHT = " + recordingInfo.height);
}
private CameraInfo _getRecordingInfo() {
DisplayMetrics displayMetrics = new DisplayMetrics();
WindowManager wm = (WindowManager) _context.getSystemService(WINDOW_SERVICE);
wm.getDefaultDisplay().getRealMetrics(displayMetrics);
int displayWidth = displayMetrics.widthPixels;
int displayHeight = displayMetrics.heightPixels;
int displayDensity = displayMetrics.densityDpi;
Configuration configuration = _context.getResources().getConfiguration();
boolean isLandscape = configuration.orientation == ORIENTATION_LANDSCAPE;
CamcorderProfile camcorderProfile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
int cameraWidth = camcorderProfile != null ? camcorderProfile.videoFrameWidth : -1;
int cameraHeight = camcorderProfile != null ? camcorderProfile.videoFrameHeight : -1;
int cameraFrameRate = camcorderProfile != null ? camcorderProfile.videoFrameRate : 30;
return calculateCameraInfo(displayWidth, displayHeight, displayDensity, isLandscape,
cameraWidth, cameraHeight, cameraFrameRate, 100);
}
private Context _context;
public CameraPropeties(Context c) {
_context = c;
_getSupportedSizes();
}
public int getWidth() {
return _width;
}
public int getHeight() {
return _hight;
}
static final class CameraInfo {
final int width;
final int height;
final int frameRate;
final int density;
CameraInfo(int width$, int height$, int frameRate$, int density$) {
this.width = width$;
this.height = height$;
this.frameRate = frameRate$;
this.density = density$;
}
}
static CameraInfo calculateCameraInfo(int displayWidth$, int displayHeight$, int displayDensity$,
boolean isLandscapeDevice$, int cameraWidth$, int cameraHeight$, int cameraFrameRate$,
int sizePercentage$) {
// Scale the display size before any maximum size calculations.
displayWidth$ = displayWidth$ * sizePercentage$ / 100;
displayHeight$ = displayHeight$ * sizePercentage$ / 100;
if (cameraWidth$ == -1 && cameraHeight$ == -1) {
// No cameras. Fall back to the display size.
return new CameraInfo(displayWidth$, displayHeight$, cameraFrameRate$, displayDensity$);
}
int frameWidth_ = isLandscapeDevice$ ? cameraWidth$ : cameraHeight$;
int frameHeight_ = isLandscapeDevice$ ? cameraHeight$ : cameraWidth$;
if (frameWidth_ >= displayWidth$ && frameHeight_ >= displayHeight$) {
// Frame can hold the entire display. Use exact values.
return new CameraInfo(displayWidth$, displayHeight$, cameraFrameRate$, displayDensity$);
}
// Calculate new width or height to preserve aspect ratio.
if (isLandscapeDevice$) {
frameWidth_ = displayWidth$ * frameHeight_ / displayHeight$;
} else {
frameHeight_ = displayHeight$ * frameWidth_ / displayWidth$;
}
return new CameraInfo(frameWidth_, frameHeight_, cameraFrameRate$, displayDensity$);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.