I'm currently developing an app which need to record video in background and process it.
(It needs to get camera preview data real-time in background and have to image process the preview data)
However, to achieve it, I need to use Camera and OpenCV as Service, and it seems that it is impossible to use JavaCameraView in OpenCV and Android.Hardware.Camera without using any preview.
Here are my questions.
I heard that NativeCamera in OpenCV can be used for this purpose. Is it possible? (Possibly with examples?)
Is there any method that I can use JavaCameraView(or similar stuff) for this purpose? I currently use Galaxy S4.
Is there any possible workarounds if android doesn't support such method?(Using Camera Preview without any surface view, or Process camera data without using preview)
(OPTIONAL)Why the android doesn't support such operation? It is very annoying!
Thank you for answering the question.
Yes it is possible with following steps..
Create one activity which will start your background service on some event or you can also use alarm manager to start and stop the service as per your requirement.
See the below code that'll help you.
public boolean starMediaRecording(){
Camera.Parameters params = mServiceCamera.getParameters();
mServiceCamera.setParameters(params);
Camera.Parameters p = mServiceCamera.getParameters();
final List<Size> listSize = p.getSupportedPreviewSizes();
Size mPreviewSize = listSize.get(2);
p.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
p.setPreviewFormat(PixelFormat.YCbCr_420_SP);
mServiceCamera.setParameters(p);
try {
mServiceCamera.setPreviewDisplay(mSurfaceHolder);
mServiceCamera.startPreview();
}
catch (IOException e) {
Log.e(TAG, e.getMessage());
e.printStackTrace();
}
mServiceCamera.unlock();
mMediaRecorder = new MediaRecorder();
mMediaRecorder.setCamera(mServiceCamera);
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
mMediaRecorder.setOutputFile("/sdcard/filenamevideo.mp4");
mMediaRecorder.setVideoFrameRate(30);
mMediaRecorder.setVideoSize(mPreviewSize.width, mPreviewSize.height);
mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
mMediaRecorder.prepare();
mMediaRecorder.start();
mRecordingStatus = true;
return true;
}
public void stopMediaRecorder() {
mServiceCamera.reconnect();
mMediaRecorder.stop();
mMediaRecorder.reset();
mServiceCamera.stopPreview();
mMediaRecorder.release();
mServiceCamera.release();
mServiceCamera = null;
}
}
You can use a service to start your camera in background. You can refer to this . Hope this will helps you.
Related
I am using tokbox for video chat and I want to take pictures of printed documents. When I am trying this on a Samsung s7edge my captured image is so unfocused I cannot read it. When I am trying this on a Nexus 6p the image is fine.
It is not a resolution problem, I am always using CameraCaptureResolution.HIGH
any thoughts?
I fixed it:
I used this class:
https://github.com/opentok/opentok-android-sdk-samples/blob/master/Custom-Video-Driver/app/src/main/java/com/tokbox/android/tutorials/customvideodriver/CustomVideoCapturer.java
Changed the init function:
#Override
public void init() {
mCamera = Camera.open(mCameraIndex);
mCurrentDeviceInfo = new Camera.CameraInfo();
Camera.getCameraInfo(mCameraIndex, mCurrentDeviceInfo);
try{
//set camera to continually auto-focus
Camera.Parameters params = mCamera.getParameters();
params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
mCamera.setParameters(params);
}catch (Exception e) {
e.printStackTrace();
}
}
and the swapCamera as well, so every time the back camera comes into play It must have autofocus.
And in my Activity, onConnected:
CustomVideoCapturer mCapturer = new CustomVideoCapturer(a) ;
mPublisher = new Publisher.Builder(this)
.capturer(mCapturer)
.resolution(Publisher.CameraCaptureResolution.HIGH).build();
Want to build an app which keeps recording in background, is it possible ?
yes its very well possible.
Create an activity which will start your background service on some event or you can also use alarm manager to start and stop the service as per your requirement.
Check some rough code which will start & stop recording using camera, this you can call from your background service and will work smoothly.
public boolean starMediaRecording(){
Camera.Parameters params = mServiceCamera.getParameters();
mServiceCamera.setParameters(params);
Camera.Parameters p = mServiceCamera.getParameters();
final List<Size> listSize = p.getSupportedPreviewSizes();
Size mPreviewSize = listSize.get(2);
p.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
p.setPreviewFormat(PixelFormat.YCbCr_420_SP);
mServiceCamera.setParameters(p);
try {
mServiceCamera.setPreviewDisplay(mSurfaceHolder);
mServiceCamera.startPreview();
}
catch (IOException e) {
Log.e(TAG, e.getMessage());
e.printStackTrace();
}
mServiceCamera.unlock();
mMediaRecorder = new MediaRecorder();
mMediaRecorder.setCamera(mServiceCamera);
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
mMediaRecorder.setOutputFile("/sdcard/filenamevideo.mp4");
mMediaRecorder.setVideoFrameRate(30);
mMediaRecorder.setVideoSize(mPreviewSize.width, mPreviewSize.height);
mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
mMediaRecorder.prepare();
mMediaRecorder.start();
mRecordingStatus = true;
return true;
}
public void stopMediaRecorder() {
mServiceCamera.reconnect();
mMediaRecorder.stop();
mMediaRecorder.reset();
mServiceCamera.stopPreview();
mMediaRecorder.release();
mServiceCamera.release();
mServiceCamera = null;
}
}
This is sample code, you need to add your own logic around and also handle exceptions accordingly.
I'm developing an image recognition app and would like the camera to focus automatically all the time. The folks at ZXing have solved this problem by calling autofocus() every few seconds, but on some cameras this doesn't focus smoothly, but zips to one end and refocuses. On my Alcatel 995, gingerbread 2.3.3 API level 10 phone, it actually makes an alarming click every time this happens.
This phone doesn't support FOCUS_MODE_CONTINUOUS_PICTURE. I tried using FOCUS_MODE_CONTINUOUS_VIDEO, which is supported, and it didn't work. I wrote a test app that captured every preview frame of the camera normally with a callback, but it didn't focus. I added a video recorder feature to the app, and when video is being recorded, the camera does autofocus all the time. But video recording takes away the ability to get a callback on each frame, I think. It's been discussed at
https://stackoverflow.com/questions/9477042/extract-video-frames-while-recording-the-video-on-android?rq=1
and
How to show real time filtered camera preview while recording videos?
Here is some of that test code:
public void surfaceCreated(SurfaceHolder holder) {
mCamera = Camera.open();
try {
Camera.Parameters parameters = mCamera.getParameters();
mCamera.setDisplayOrientation(90); // just get it right for testing
mCamera.setParameters(parameters);
mCamera.setPreviewDisplay(holder);
mCamera.setPreviewCallback(new PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera arg1) {
Log.d(TAG, String.format("Frame %d", mFrameNumber++)); // see the frames in the logcat
}
});
} catch (IOException exception) {
mCamera.release();
mCamera = null;
Log.d(TAG, "exception setting parameters");
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// Now that the size is known, set up the camera parameters and begin
// the preview.
Camera.Parameters parameters = mCamera.getParameters();
List<Size> previewSizes = parameters.getSupportedPreviewSizes();
Size previewSize = getOptimalPreviewSize(previewSizes, w, h);
parameters.setPreviewSize(previewSize.width, previewSize.height);
parameters.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
mCamera.setParameters(parameters);
mCamera.startPreview();
if (mRecordingVideo)
startVideo(mCamera, holder);
}
// derived from http://developer.android.com/guide/topics/media/camera.html#capture-video
private void startVideo(Camera camera, SurfaceHolder holder) {
camera.stopPreview(); // not specified in documentation but seems to be needed
camera.unlock();
mMediaRecorder = new MediaRecorder();
mMediaRecorder.setCamera(camera);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); // No audio is recorded
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
mMediaRecorder.setOutputFile("/dev/null");
try {
mMediaRecorder.setPreviewDisplay(holder.getSurface());
mMediaRecorder.prepare();
} catch (IOException e) {
camera.release();
Log.d(TAG, "startVideo: Failed.");
e.printStackTrace();
}
mMediaRecorder.start();
}
If I set mRecordingVideo in the above code to start the video recorder, I gain autofocus but lose the per-preview-frame callbacks.
The Camera.Parameters class definition says that FOCUS_MODE_CONTINUOUS_VIDEO is "intended for video recording" but doesn't make plain that it doesn't work otherwise.
Is there anything else I can do to persuade continuous autofocus to work in a gingerbread phone without recording video? Have I missed something out?
Is this phone-specific? Do other phones continuous autofocus in this mode without recording video? I posted the source of a complete test app to Github if anyone would like to try it on their phone.
Someone kindly helped me out by testing this on another phone on another continent. Thanks very much, Colin!
It appears that the code above is correct and should cause the camera to focus properly.
This behaviour is phone-specific. The Alcatel 995 running 2.3.6 definitely does not focus in this mode without the video recorder running. A Samsung Galaxy Nexus (not sure which OS) running the same code does focus without the video recorder running.
try "setRecordingHint(true)" to the camera parameters
I am working on a new android application.In my app i have to add show effects on image preview [like sepia,pinch, mirror, etc] and capture and save image in that particular effect.eg: I f user select pinch effect then he can capture and store the image with pinch effect.
I had read some faq's. But they are telling about some ndk's.But i don't have any idea about ndk's. Please help me friends.
You can set all these kind of effects with camera instance itself. Walk though the below code ...
Camera camera = null;
camera = Camera.open();
if (camera != null) {
try {
Camera.Parameters parameters = camera.getParameters();
// Set all kind of stuffs here..
parameters.setSceneMode(Camera.Parameters.FLASH_MODE_AUTO);
parameters.setColorEffect(Camera.Parameters.EFFECT_SEPIA);
camera.setParameters(parameters);
camera.setPreviewDisplay(surface_holder);
camera.startPreview();
} catch (IOException exception) {
camera.release();
camera = null;
}
}
I'm developing on android, i want to do somethings with camera (process pixels's values), but just in background, is it possible to do it without surface view? just use a buffer to read pixels's values and do processing.
thanks for every one can help me
As of API-Level 11 the SurfaceTexture was added. With it a SurfaceView is no longer needed. I tested the following code with my Samsung Galaxy S3 Neo.
mCamera = Camera.open();
try {
mCamera.setPreviewTexture(new SurfaceTexture(10));
} catch (IOException e1) {
Log.e(Version.APP_ID, e1.getMessage());
}
Parameters params = mCamera.getParameters();
params.setPreviewSize(640, 480);
params.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
params.setPictureFormat(ImageFormat.JPEG);
mCamera.setParameters(params);
mCamera.startPreview();
mCamera.takePicture(null, null, null, new PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
Log.i(Version.APP_ID, "picture-taken");
}
});
I've been looking for an answer to this for a while. I found it there, copied here for convenience.
http://handycodeworks.com/?p=19
Basically, let's just create a dummy SurfaceView (it works even inside a Service), and use it for Camera functions.
SurfaceView view = new SurfaceView(this);
c.setPreviewDisplay(view.getHolder());
c.startPreview();
c.takePicture(shutterCallback, rawPictureCallback, jpegPictureCallback);