如何解决无法通过适用于 Android 11 的 Mediastore API 录制超过 2 分钟的视频
我正在尝试使用适用于 Android 11 的媒体商店 API 的 ScreenRecording 应用程序。
我的问题是,我只能录制 2 分钟以下的屏幕录像。如果屏幕录制超过 2 分钟,则文件已创建,但只有在单击时才为 Kbs 大小,显示“无法播放此视频” 但如果我记录的时间低于 2 分钟,它就可以正常工作。
在 Manifest 中,根据 Google 指南,我没有对 Android 11 使用 WRITE_EXTERNAL_STORAGE 和 requestLegacyExternalStorage 权限
如果我错过了任何步骤,请帮助我。提前致谢!
我在下面通过代码分享,
初始化记录器:
private void recordScreen()
{
if(mediaProjection == null)
{
if(mediaProjectionManager!=null)
{
Intent permissionIntent = mediaProjectionManager.createScreenCaptureIntent();
startActivityForResult(permissionIntent,REQUEST_CODE);
}
return;
}
initRecorder();
virtualDisplay = createVirtualDisplay();
mediaRecorder.start();
}
@Override
protected void onActivityResult(int requestCode,int resultCode,android.content.Intent intent){
super.onActivityResult(requestCode,resultCode,intent);
destroyMediaProjection();
if(intent!=null)
{
createMediaProjection(resultCode,intent);
}
}
public void createMediaProjection(final int resultCode,final android.content.Intent data)
{
destroyMediaProjection();
mediaProjectionCallBack = new MediaProjectionCallBack();
long delay = 0;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
foreGroundServiceIntent = new Intent(this,StartForegroundService.class);
System.out.println("calling ContextCompat.startForegroundService(this,intent)");
ContextCompat.startForegroundService(getApplicationContext(),foreGroundServiceIntent);
delay = 1000;
}
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
//Write whatever to want to do after delay specified (1 sec)
mediaProjection = mediaProjectionManager.getMediaProjection(resultCode,data);
mediaProjection.registerCallback(mediaProjectionCallBack,null);
System.out.println("======createMediaProjection=========11111");
recordScreen();
}
},delay);
}
private VirtualDisplay createVirtualDisplay()
{
return mediaProjection.createVirtualDisplay("Test",DISPLAY_WIDTH,DISPLAY_HEIGHT,mscreendenstity,DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,mediaRecorder.getSurface(),null,null);
}
private class MediaProjectionCallBack extends MediaProjection.Callback
{
@Override
public void onStop()
{
System.out.println("MediaProjectionCallBack onStop() called");
stopRecordScreen();
super.onStop();
}
}
private void initRecorder()
{
if(mediaRecorder!=null)
{
mediaRecorder.release();
mediaRecorder = null;
}
mediaRecorder = new MediaRecorder();
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
String fileName = new StringBuilder("Recor_").append(new SimpleDateFormat("dd-mm-yyyy-hh_mm_ss").format(new java.util.Date())).append(".mp4").toString();
android.content.ContentValues values = new android.content.ContentValues(5);
values.put(MediaStore.Video.Media.DISPLAY_NAME,fileName);
values.put(MediaStore.Video.Media.TITLE,fileName);
values.put(MediaStore.Video.Media.MIME_TYPE,"video/mp4");
values.put(MediaStore.Video.Media.RELATIVE_PATH,Environment.DIRECTORY_MOVIES + "/Test");
ContentResolver resolver = getBaseContext().getContentResolver();
Uri FinalvideoUri = resolver.insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,values);
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,FinalvideoUri));
File file = new File(FinalvideoUri.getPath());
videoUrl = getRealPathFromURI(this.getApplicationContext(),FinalvideoUri);
ParcelFileDescriptor file1 = this.getApplicationContext().getContentResolver().openFileDescriptor(FinalvideoUri,"w");
mediaRecorder.setOutputFile(file1.getFileDescriptor());
mediaRecorder.setVideoSize(DISPLAY_WIDTH,DISPLAY_HEIGHT);
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
mediaRecorder.setVideoEncodingBitRate(512 * 10000);
mediaRecorder.setVideoFrameRate(30);
int rotation = getWindowManager().getDefaultDisplay().getRotation();
int orientation = ORIENTATIONS.get(rotation + 90);
mediaRecorder.setOrientationHint(orientation);
mediaRecorder.prepare();
}
停止录制:
private void stopRecordScreen()
{
if(mediaRecorder!=null)
{
mediaRecorder.release();
mediaRecorder = null;
System.out.println("mediaRecorder released and assigned as null");
}
destroyMediaProjection();
stopTheForeGroundService();
if(virtualDisplay == null){
return;
}
virtualDisplay.release();
virtualDisplay = null;
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,videoUri));
}
private void destroyMediaProjection()
{
if(mediaProjection != null)
{
mediaProjection.unregisterCallback(mediaProjectionCallBack);
mediaProjection.stop();
mediaProjection = null;
System.out.println("mediaProjection stopped and assigned as null");
}
}
private Intent foreGroundServiceIntent;
private void stopTheForeGroundService()
{
final Handler handler = new Handler();
handler.postDelayed((new Runnable() {
@Override
public void run()
{
if(foreGroundServiceIntent!=null)
{
System.out.println("stopTheForeGroundService called");
stopService(foreGroundServiceIntent);
foreGroundServiceIntent = null;
if(StartForegroundService.instance!=null)
{
StartForegroundService.instance.stopForegroundService();
}
}
}
}),1000);
}
解决方法
您好 Nijanthan 我回答了 MediaStore 的改进回答MediaStore.Images.Media.insertImage deprecated
我确实使用了 workManager 和 viewModel 不确定这是否适用于您的用例,我确实在 API 26 和 API 30 上测试了我的答案。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。