Nijanthan
Nijanthan

Reputation: 127

Not able to Record Video More than 2mins through Mediastore API for Android 11

I am trying a ScreenRecording application using media store API for Android 11.

My issue is, I am able to record screen recording below 2mins only. If the screen recording exceeds more than 2 mins, the file got created but it is in Kbs size only on clicking it says "Can't play this video" But if I record below 2 mins it works fine.

In Manifest, I am NOT using WRITE_EXTERNAL_STORAGE & requestLegacyExternalStorage permissions for Android 11, as per Google Guidelines

Pls, do help me if I missed any steps. Thanks in Advance!

I am Sharing by Code below,

INIT RECORDER:

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();

}

STOP RECORDING:

 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);
}

Upvotes: 1

Views: 499

Answers (1)

Manav Brar
Manav Brar

Reputation: 51

Hi Nijanthan I answered an improvement on MediaStore answer MediaStore.Images.Media.insertImage deprecated

I did use workManager and viewModel not sure if that would apply to your use-case, I did test my answer on API 26 and on API 30.

Upvotes: 1

Related Questions