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");
这会获取当前系统时间并将其分配到文件名中。现在创建了新文件,我不必每次都重新启动应用程序来记录新文件。
我正在使用 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");
这会获取当前系统时间并将其分配到文件名中。现在创建了新文件,我不必每次都重新启动应用程序来记录新文件。