Android mediarecorder начинает писать, когда остановлен

Я скопировал программу с этого сайта http://www.truiton.com/2015/05/capture-record-android-screen-using-mediaprojection-apis/, чтобы создать приложение для записи экрана. Когда я останавливаю приложение и пытаюсь просмотреть видео, запись видео еще не завершена. Я вижу это, потому что в моем приложении файлового менеджера размер файла растет очень медленно, около 50 КБ / с. Это точно такой же код, как на веб-странице. В чем может быть проблема?

    private MediaProjectionCallback mMediaProjectionCallback;
private int mScreenDensity;
private MediaRecorder mMediaRecorder;
private MediaProjectionManager mProjectionManager;
private VirtualDisplay mVirtualDisplay;
private static final int DISPLAY_WIDTH = 720;
private static final int DISPLAY_HEIGHT = 1280;
private static final int SCREEN_CAPTURE_REQUEST_CODE = 10; //random number
private static final int WRITE_STORAGE_AND_RECORD_AUDIO_CODE = 11; //random number
private MediaProjection mMediaProjection;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Log.i(TAG, "service is started!");
    DisplayMetrics metrics = getApplicationContext().getResources().getDisplayMetrics();
    mScreenDensity = metrics.densityDpi;

    mMediaRecorder = new MediaRecorder();

    mProjectionManager = (MediaProjectionManager) getSystemService
            (Context.MEDIA_PROJECTION_SERVICE);
    // check permissions
    if (ContextCompat.checkSelfPermission(MainActivity.this,
            Manifest.permission.WRITE_EXTERNAL_STORAGE) + ContextCompat
            .checkSelfPermission(MainActivity.this,
                    Manifest.permission.RECORD_AUDIO)
            != PackageManager.PERMISSION_GRANTED) {
        Log.i(TAG, "Permissions not granted!");
        ActivityCompat.requestPermissions(MainActivity.this,
                new String[]{Manifest.permission
                        .WRITE_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO},
                WRITE_STORAGE_AND_RECORD_AUDIO_CODE);
    }
    else {
        Log.i(TAG, "Permissions is granted!");
        initRecorder();
        shareScreen();
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                Log.i(TAG, "Timer went off!");
                stopScreenSharing();
            }
        }, 10000);
    }
}

//ActivityCompat.requestPermissions callback
    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        if(requestCode == WRITE_STORAGE_AND_RECORD_AUDIO_CODE)
        {
            //relaunch mainactivity
            Intent i = new Intent(getBaseContext(), MainActivity.class);
            i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(i);
            return;
        }
        Log.i(TAG, "ERROR: onRequestPermissionsResult");
    }


private void initRecorder() {
    try {
        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
        mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        mMediaRecorder.setOutputFile(Environment
                .getExternalStoragePublicDirectory(Environment
                        .DIRECTORY_DOWNLOADS) + "/video.mp4");
        mMediaRecorder.setVideoSize(DISPLAY_WIDTH, DISPLAY_HEIGHT);
        mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
        mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        mMediaRecorder.setVideoEncodingBitRate(512 * 1000);
        mMediaRecorder.setVideoFrameRate(10);
        mMediaRecorder.setOrientationHint(0);
        mMediaRecorder.prepare();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

private void shareScreen() {
    if (mMediaProjection == null) {
        startActivityForResult(mProjectionManager.createScreenCaptureIntent(), SCREEN_CAPTURE_REQUEST_CODE);
        return;
    }
    mVirtualDisplay = createVirtualDisplay();
    mMediaRecorder.start();
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode != SCREEN_CAPTURE_REQUEST_CODE) {
        Log.e(TAG, "Unknown request code: " + requestCode);
        return;
    }
    if (resultCode != RESULT_OK) {
        Log.e(TAG, "Screen capture request not granted: " + requestCode);
        shareScreen();
        return;
    }
    mMediaProjectionCallback = new MediaProjectionCallback();
    mMediaProjection = mProjectionManager.getMediaProjection(resultCode, data);
    mMediaProjection.registerCallback(mMediaProjectionCallback, null);
    mVirtualDisplay = createVirtualDisplay();
    mMediaRecorder.start();
}

private class MediaProjectionCallback extends MediaProjection.Callback {
    @Override
    public void onStop() {
        mMediaRecorder.stop();
        mMediaRecorder.reset();
        Log.v(TAG, "Recording Stopped");
        mMediaProjection = null;
        stopScreenSharing();
    }
}

private void stopScreenSharing() {
    Log.v(TAG, "Stop Screen sharing");
    if (mVirtualDisplay == null) {
        return;
    }
    mVirtualDisplay.release();
    //mMediaRecorder.release(); //If used: mMediaRecorder object cannot
    // be reused again
    destroyMediaProjection();
}

private void destroyMediaProjection() {
    if (mMediaProjection != null) {
        mMediaProjection.unregisterCallback(mMediaProjectionCallback);
        mMediaProjection.stop();
        mMediaProjection = null;
    }
    Log.i(TAG, "MediaProjection Stopped");
}

private VirtualDisplay createVirtualDisplay() {
    return mMediaProjection.createVirtualDisplay("MainActivity",
            DISPLAY_WIDTH, DISPLAY_HEIGHT, mScreenDensity,
            DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
            mMediaRecorder.getSurface(), null /*Callbacks*/, null
            /*Handler*/);
}

}

1 ответ

Вы скучаете по if заявление вокруг кода в вашем onStop() функция.

@Override
public void onStop() {
    if (mToggleButton.isChecked()) {
        mToggleButton.setChecked(false);
        mMediaRecorder.stop();
        mMediaRecorder.reset();
        Log.v(TAG, "Recording Stopped");
    }
    mMediaProjection = null;
    stopScreenSharing();
}

Это не проблема, но нужно указать.

Вопрос в вашем run() заявление.

Я не уверен, что вы пытаетесь достичь с помощью этого метода, так как этого нет в руководстве.

@Override
public void run() {
    Log.i(TAG, "Timer went off!");
    stopScreenSharing();
}

Этот метод вызывает stopScreenSharing(). Из-за этого создается впечатление, что ваша запись остановлена, но она не прекращает запись в ваш файл или вызывает onStop() метод. Так что он продолжает заполнять файл.

Другие вопросы по тегам