MediaRecorder 没有第二次录制

MediaRecorder not recording the second time

我正在使用 MediaRecorder 来录制用户屏幕。首次打开应用程序并且用户单击 fab 按钮录制屏幕时一切正常。但是,如果应用程序 运行ning,用户再次单击记录按钮,我所需的文件路径中不会生成新文件,因此我的列表视图不会更新。

如果我关闭该应用程序并再次 运行 该应用程序,它的 mediarecorder 仅在第一次运行。我尝试了很多不同的方法,并在整个 Stack Overflow 上寻找解决方案,但都是徒劳的。第二次单击录制按钮时,我无法录制屏幕。我也没有收到任何错误。这是我的代码:

public class MainActivity extends AppCompatActivity {

private static final String TAG = "MainActivity";
private static final int DISPLAY_WIDTH = 720;
private static final int DISPLAY_HEIGHT = 1280;
Button btn;
private int screenDensity;
private MediaProjectionManager mediaProjectionManager;
private MediaProjection mediaProjection;
private VirtualDisplay virtualDisplay;
private MediaProjection.Callback mediaProjectionCallback;
private MediaRecorder mediaRecorder;
private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
private boolean isRecording = false;
static SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MMM-yyyy hh:mm:ss");
static String todayDate = dateFormat.format(new Date());

static {
    ORIENTATIONS.append(Surface.ROTATION_0, 90);
    ORIENTATIONS.append(Surface.ROTATION_90, 0);
    ORIENTATIONS.append(Surface.ROTATION_180, 270);
    ORIENTATIONS.append(Surface.ROTATION_270, 180);
}

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

    String[] PERMISSIONS = {Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO};

    if (!hasPermissions(this, PERMISSIONS)) {
        ActivityCompat.requestPermissions(this, PERMISSIONS, 1);
    }

    DisplayMetrics displayMetrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
    screenDensity = displayMetrics.densityDpi;

    mediaProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);

    btn = findViewById(R.id.fab);
    btn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            toggleScreenShare();
        }
    });
}

public static boolean hasPermissions(Context context, String... permissions) {
    if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context != null && permissions != null) {
        for (String permission : permissions) {
            if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
                return false;
            }
        }
    }
    return true;
}

public void recordBtnReload() {
    if (isRecording) {
        btn.setText("Stop");
    } else {
        btn.setText("Record");
    }
}

private void toggleScreenShare() {
    if (!isRecording) {
        initRecorder();
        shareScreen();
    } else {
        mediaRecorder.stop();
        mediaRecorder.reset();
        mediaRecorder.release();
        mediaRecorder = null;
        stopScreenSharing();
    }
}

private void stopScreenSharing() {
    if (virtualDisplay == null) {
        return;
    }
    virtualDisplay.release();
    destroyMediaProjection();
    isRecording = false;
    recordBtnReload();
}

private void destroyMediaProjection() {
    if (mediaProjection != null) {
        mediaProjection.unregisterCallback(mediaProjectionCallback);
        mediaProjection.stop();
        mediaProjection = null;
    }
    Log.i(TAG, "MediaProjection is stopped for now");
}

private void shareScreen() {
    if (mediaProjection == null) {
        startActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), 1000);
        return;
    }
    virtualDisplay = createVirtualDisplay();
    mediaRecorder.start();
    isRecording = true;
    recordBtnReload();
    Log.i(TAG, "ShareScreen started for now");
}

private void initRecorder() {
    try {
        mediaRecorder = new MediaRecorder();
        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);

        mediaRecorder.setVideoSize(DISPLAY_WIDTH, DISPLAY_HEIGHT);
        mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
        mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        mediaRecorder.setVideoEncodingBitRate(512 * 1000);
        mediaRecorder.setVideoFrameRate(16);
        mediaRecorder.setVideoEncodingBitRate(3000000);
        String directory = Environment.getExternalStorageDirectory() + File.separator + "NewCapture";
        File folder = new File(directory);
        boolean success = true;
        if (!folder.exists()) {
            success = folder.mkdir();
        }
        String filepath;
        if (success) {
            String videoName = ("Video_" + todayDate + ".mp4");
            filepath = directory + File.separator + videoName;
            Log.i(TAG, "File created");
        } else {
            Toast.makeText(this, "Failed to create Recordings directory", Toast.LENGTH_SHORT).show();
            return;
        }
        mediaRecorder.setOutputFile(filepath);
        int rotation = getWindowManager().getDefaultDisplay().getRotation();
        int orientation = ORIENTATIONS.get(rotation + 90);
        mediaRecorder.setOrientationHint(orientation);
        mediaRecorder.prepare();
        Log.i(TAG, "initRecorder");
    } catch (IOException e) {
        e.printStackTrace();
    }
}

private VirtualDisplay createVirtualDisplay() {
    Log.i(TAG, "Created Virtual Display");
    return mediaProjection.createVirtualDisplay(TAG, DISPLAY_WIDTH, DISPLAY_HEIGHT, screenDensity,
            DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mediaRecorder.getSurface(), null, null);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode != 1000) {
        Log.e(TAG, "Unknown request code:" + requestCode);
        return;
    }
    if (resultCode != RESULT_OK) {
        Toast.makeText(this, "Permission for screen recording is denied", Toast.LENGTH_LONG).show();
        isRecording = false;
        recordBtnReload();
        return;
    }
    mediaProjectionCallback = new MediaProjection.Callback() {
        @Override
        public void onStop() {
            if (isRecording) {
                isRecording = false;
                recordBtnReload();
                mediaRecorder.stop();
                mediaRecorder.reset();
                mediaRecorder.release();
                mediaRecorder = null;
            }
            mediaProjection = null;
            stopScreenSharing();
        }
    };

    mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, data);
    mediaProjection.registerCallback(mediaProjectionCallback, null);
    virtualDisplay = createVirtualDisplay();
    mediaRecorder.start();
    isRecording = true;
    recordBtnReload();
}

@Override
protected void onDestroy() {
    super.onDestroy();
    destroyMediaProjection();
}

}

我不知道我做错了什么。我仍在学习应用程序开发。

我的代码中的问题出在 initRecorder() 函数中。而不是使用以下代码创建文件名:

String videoName = ("Video_" + todayDate + ".mp4");

其中,todayDate 是一个日期格式化程序。我用以下代码替换了代码:

String videoName = ("Video_" + System.currentTimeMillis() + ".mp4");

这会获取当前系统时间并将其分配到文件名中。现在创建了新文件,我不必每次都重新启动应用程序来记录新文件。