I'm trying to implement a background video recording feature within my Android application using MediaRecorder. However, I'm consistently encountering an issue with error -22 whenever I attempt to start the recording.
Here's a brief overview of my scenario:
I'm aiming to record a video in the background without utilizing a Surface. I've used standard configurations for MediaRecorder as outlined in the Android documentation and various online tutorials. Here's a snippet of the code I've employed:
public class VideoRecordingService extends Service {
private static final int NOTIFICATION_ID = 1;
private static final String TAG = "VideoRecordingService";
private MediaRecorder mediaRecorder;
private String outputFile;
private boolean isRecording = false;
private BroadcastReceiver stopRecordingReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
stopRecording();
stopSelf();
}
};
@Override
public void onCreate() {
super.onCreate();
IntentFilter filter = new IntentFilter("STOP_VIDEO_RECORDING_ACTION");
registerReceiver(stopRecordingReceiver, filter);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
startForeground(NOTIFICATION_ID, createNotification());
startRecording();
return START_STICKY;
}
private Notification createNotification() {
String channelId = "SMoDS_Channel_ID";
String channelName = "SMoDS Channel";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_DEFAULT);
NotificationManager notificationManager = getSystemService(NotificationManager.class);
if (notificationManager != null) {
notificationManager.createNotificationChannel(channel);
}
}
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(
this,
0,
notificationIntent,
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, channelId)
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle("Registrazione Video Attiva")
.setContentText("L'app sta registrando un video in background.")
.setContentIntent(pendingIntent)
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
return builder.build();
}
@Override
public void onDestroy() {
unregisterReceiver(stopRecordingReceiver);
stopRecording();
super.onDestroy();
}
private void startRecording() {
if (isRecording) {
Log.d(TAG, "Recording is already in progress. Skipping new recording.");
return;
}
if (mediaRecorder != null) {
mediaRecorder.reset();
mediaRecorder.release();
mediaRecorder = null;
}
try {
mediaRecorder = new MediaRecorder();
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
outputFile = getOutputMediaFile();
if (outputFile == null) {
Log.e(TAG, "No valid output file");
return;
}
mediaRecorder.setOutputFile(outputFile);
mediaRecorder.prepare();
mediaRecorder.start();
isRecording = true;
Log.d(TAG, "Start recording");
} catch (IOException e) {
Log.e(TAG, "IOException during recording start: " + e.getMessage());
} catch (IllegalStateException e) {
Log.e(TAG, "IllegalStateException during recording start: " + e.getMessage());
} catch (Exception e) {
Log.e(TAG, "Exception during recording start: " + e.getMessage());
}
}
private void stopRecording() {
if (mediaRecorder != null) {
try {
mediaRecorder.stop();
mediaRecorder.reset();
mediaRecorder.release();
mediaRecorder = null;
File currentVideoFile = new File(outputFile);
Recorder.getInstance().setVideoFile(currentVideoFile);
} catch (RuntimeException e) {
Log.e(TAG, "Errore durante l'arresto della registrazione: " + e.getMessage());
}
}
isRecording = false;
Log.d(TAG, "Fine registrazione");
}
private String getOutputMediaFile() {
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED) && !isRecording) {
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(DIRECTORY_MOVIES), "SMoDS_Videos");
if (!mediaStorageDir.exists() && !mediaStorageDir.mkdirs()) {
Log.e(TAG, "Impossibile creare la directory.");
return null;
}
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
String videoFileName = "VIDEO_" + timeStamp + ".mp4";
return new File(mediaStorageDir.getPath(), videoFileName).getAbsolutePath();
} else {
Log.e(TAG, "Storage esterno non disponibile o registrazione in corso.");
return null;
}
}
}
However, when I execute the code, I receive the E/MediaRecorder: start failed: -22 error and I'm struggling to understand how to resolve it.
I was wondering if anyone has had similar experiences or if there are specific solutions to handle the -22 error when using MediaRecorder in a background video recording context without utilizing a Surface.
I'd greatly appreciate any suggestions or direction on how I might address this issue. Thank you in advance for your assistance!