Taking pictures while recording videos on Android

I wrote the Android program shown below to record the front camera in the background. It works very well. But now I also want to take a picture every 5 seconds while recording. Is it possible? When I try to open the second camera (in another service), I get an error message.

public class RecorderService extends Service implements SurfaceHolder.Callback { private WindowManager windowManager; private SurfaceView surfaceView; private Camera camera = null; private MediaRecorder mediaRecorder = null; @Override public void onCreate() { // Create new SurfaceView, set its size to 1x1, move it to the top left corner and set this service as a callback windowManager = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE); surfaceView = new SurfaceView(this); WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams( 1, 1, WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, PixelFormat.TRANSLUCENT ); layoutParams.gravity = Gravity.LEFT | Gravity.TOP; windowManager.addView(surfaceView, layoutParams); surfaceView.getHolder().addCallback(this); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Intent notificationIntent = new Intent(this, MainActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); Notification notification = new NotificationCompat.Builder(this) //.setSmallIcon(R.mipmap.app_icon) .setContentTitle("Background Video Recorder") .setContentText("") .setContentIntent(pendingIntent).build(); startForeground(MainActivity.NOTIFICATION_ID_RECORDER_SERVICE, notification); return Service.START_NOT_STICKY; } // Method called right after Surface created (initializing and starting MediaRecorder) @Override public void surfaceCreated(SurfaceHolder surfaceHolder) { camera = Camera.open(1); mediaRecorder = new MediaRecorder(); camera.unlock(); mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface()); mediaRecorder.setCamera(camera); mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER); mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_720P)); FileUtil.createDir("/storage/emulated/0/Study/Camera"); mediaRecorder.setOutputFile("/storage/emulated/0/Study/Camera/" + Long.toString(System.currentTimeMillis()) + ".mp4"); try { mediaRecorder.prepare(); } catch (Exception e) {} mediaRecorder.start(); try { camera.setPreviewDisplay(surfaceHolder); } catch (IOException e) { e.printStackTrace(); } Runnable runnable = new PictureThread(camera); Thread thread = new Thread(runnable); thread.start(); } // Stop recording and remove SurfaceView @Override public void onDestroy() { mediaRecorder.stop(); mediaRecorder.reset(); mediaRecorder.release(); camera.lock(); camera.release(); windowManager.removeView(surfaceView); } @Override public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) {} @Override public void surfaceDestroyed(SurfaceHolder surfaceHolder) {} @Override public IBinder onBind(Intent intent) { return null; } } 

Edit : I have now written a PictureThread thread. This thread starts with RecorderService and tries to take a snapshot during video recording.

 public class PictureThread implements Runnable { private final static String TAG = PictureThread.class.getSimpleName(); private Camera camera; PictureThread(Camera camera) { this.camera = camera; } @Override public void run() { camera.startPreview(); camera.takePicture(shutterCallback, rawCallback, jpegCallback); } Camera.ShutterCallback shutterCallback = new Camera.ShutterCallback() { public void onShutter() { } }; Camera.PictureCallback rawCallback = new Camera.PictureCallback() { public void onPictureTaken(byte[] data, Camera camera) { } }; Camera.PictureCallback jpegCallback = new Camera.PictureCallback() { public void onPictureTaken(byte[] data, Camera camera) { Log.i(TAG, "onPictureTaken - jpeg"); } }; } 

Unfortunately, jpegCallback never called (i.e. a log message is never printed). When I open the camera application of my tablet, I can take pictures during video recording, so this should be possible.

I also tried the Camera2 API example suggested by Alex Cohn ( https://github.com/mobapptuts/android_camera2_api_video_app ). Video recording works, and shooting is also performed, but when I try to take a picture while recording, the image is not created (but also without errors). However, I found that this application does not work very reliably (maybe there is another sample application).

Change 2 . shutterCallback and rawCallback of takePicture , but the rawCallback data is null. jpegCallback never called. Any idea why and how this can be resolved? I also tried to wait in the thread for some time to give the callback time for the call, and I tried to make the callbacks static in my main action (so that it was not going to collect garbage). Nothing succeeded.

+5
source share
2 answers

Edit:

With clarification:

The old camera API supports the takePicture () call while the video is being recorded if Camera.Parameters.isVideoSnapshotSupported reports that the truth on the device is an issue.

Just hold on to the same camera instance that you pass to MediaRecorder and call Camera.takePicture () on it.

Camera2 also supports this with greater flexibility by creating a session with preview, recording and JPEG output at the same time.

Original answer:

If you mean shooting with the rear camera, when recording from the front camera - it depends on the device. Some devices have enough hardware resources to run several cameras at the same time, but most of them will not (they exchange equipment for processing data between two cameras).

The only way to find out if you can use multiple cameras at once is to try to open the second camera when it is already open. If this works, you should be good to go; if not, this device does not support multiple cameras at once.

+5
source

No, you cannot open individual instances of the camera to record video and shoot still images. The outdated camera API is not reliable for such tasks (see, for example, the Android camera parameter IsVideoSnapshotSupported is incorrectly set to false about Samsung S4).

You can use the camera2 API (on devices that support this mode) to capture different formats and resolutions from the same camera instance. Here is a video tutorial: https://www.nigeapptuts.com/android-video-app-still-capture-recording/

+1
source

Source: https://habr.com/ru/post/1270227/


All Articles