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.
Related
I have the following method to start a camera preview and prepare a MediaRecorder
private boolean prepareVideoRecorder(){
// BEGIN_INCLUDE (configure_preview)
//mCamera = CameraHelper.getDefaultCameraInstance();
if(Utils.hasFrontCamera())
mCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);
else
mCamera = Camera.open();
// We need to make sure that our preview and recording video size are supported by the
// camera. Query camera to find all the sizes and choose the optimal size given the
// dimensions of our preview surface.
Camera.Parameters parameters = mCamera.getParameters();
List<Camera.Size> mSupportedPreviewSizes = parameters.getSupportedPreviewSizes();
Camera.Size optimalSize = CameraHelper.getOptimalPreviewSize(mSupportedPreviewSizes,
mSurfaceView.getWidth(), mSurfaceView.getHeight());
// Use the same size for recording profile.
CamcorderProfile profile = CamcorderProfile.get(CamcorderProfile.QUALITY_LOW);
profile.audioChannels = 2;
// profile.videoFrameWidth = optimalSize.width;
// profile.videoFrameHeight = optimalSize.height;
Log.e("Resolution ",profile.videoFrameWidth + " - "+profile.videoFrameHeight);
//profile.videoBitRate = 3000000;
//profile.videoFrameRate = 24;
// likewise for the camera object itself.
parameters.setPreviewSize(profile.videoFrameWidth, profile.videoFrameHeight);
mCamera.setParameters(parameters);
try {
// Requires API level 11+, For backward compatibility use {#link setPreviewDisplay}
// with {#link SurfaceView}
mCamera.setPreviewDisplay(mSurfaceView.getHolder());
if (Utils.isModeCameraLandScape(getActivity())) {
mCamera.setDisplayOrientation(ORIENTATIONS_LAND.get(Utils.getRotation(context)));
Log.e("IMAGE", "preCreateCamera land "+Utils.getRotation(context));
} else {
mCamera.setDisplayOrientation(ORIENTATIONS_PORT.get(Utils.getRotation(context)));
Log.e("IMAGE", "preCreateCamera port "+Utils.getRotation(context));
}
//mCamera.setDisplayOrientation(90);
} catch (IOException e) {
Log.e(TAG, "Surface texture is unavailable or unsuitable" + e.getMessage());
return false;
}
// END_INCLUDE (configure_preview)
// BEGIN_INCLUDE (configure_media_recorder)
mMediaRecorder = new MediaRecorder();
// Step 1: Unlock and set camera to MediaRecorder
mCamera.unlock();
mMediaRecorder.setCamera(mCamera);
// Step 2: Set sources
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC );
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
// Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
mMediaRecorder.setProfile(profile);
// Step 4: Set output file
String path = getVideoFile(MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO).getAbsolutePath();
currentFile = path;
mMediaRecorder.setOutputFile(path);
mMediaRecorder.setOrientationHint(270);
// END_INCLUDE (configure_media_recorder)
// Step 5: Prepare configured MediaRecorder
try {
mMediaRecorder.prepare();
} catch (IllegalStateException e) {
Log.d(TAG, "IllegalStateException preparing MediaRecorder: " + e.getMessage());
releaseMediaRecorder();
return false;
} catch (IOException e) {
Log.d(TAG, "IOException preparing MediaRecorder: " + e.getMessage());
releaseMediaRecorder();
return false;
}
return true;
}
i had to comment this because apparently in a specific device i had for tests ( and i assume it happens on others ) i couldnt see the video preview and i got a MediaRecorder - “start failed: -19”
// profile.videoFrameWidth = optimalSize.width;
// profile.videoFrameHeight = optimalSize.height;
My problem
When i set the
CamcorderProfile profile = CamcorderProfile.get(CamcorderProfile.QUALITY_LOW);
to
CamcorderProfile profile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
the camera doesnt seem to start the preview, and on the Log.e i get "E/Resolution: 1280 - 720", but from what i've seen on the specs of the device, it should only go up to 640 - 480
Do i need to set some other parameters?
Before setting the quality you have to check if the camera supports that quality.
I ran into this problem on a nexus 6p device when setting the QUALITY_HIGH on the MediaRecorder.
I found the issue to the setMaxDuration() method call caused MediaRecorder to crash with a value that was too high.
I am having a basic Camera application using MediaRecorder. Application previews the video on TextureView and when button is clicked it starts recording. I works on most mobile phones, but on some specific device, underlying OMX fails:
(40b1df38) hardware/ti/omap4xxx/camera/OMXCameraAdapter/OMXCameraAdapter.cpp:2176 UseBuffersPreview - Exiting function UseBuffersPreview because of ret 0 eError=80001018
and in consequence, preview freezes and recording fails.
I found that this is most likely caused when Camera object is still previewing, while MediaRecorder object start recording. When I call mCamera.stopPreview() before starting recording, it works. Therefore, I have following questions:
1. Why is call to mCamera.stopPreview() necessary on some devices, and not on others?
2. How can the recorded video be still previewed, if stopPreview() on Camera object is called, but MediaRecorder.setPreviewDisplay() was not?
Below I present some code:
public boolean startRecording() throws IllegalStateException, IOException {
if (!mRecordingStarted) {
mMediaRecorder = new MediaRecorder();
try {
mCamera.stopPreview(); // !!! without this recording fails on some devices!
mCamera.unlock();
mMediaRecorder.setCamera(mCamera);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT); mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mMediaRecorder.setProfile(mCamProfile);
//mMediaRecorder.setPreviewDisplay(mSurfaceView.getHolder().getSurface());
mMediaRecorder.setOutputFile(mCaptureFile);
mMediaRecorder.prepare();
mMediaRecorder.start();
mRecordingStarted = true;
} catch (Exception e) {
mMediaRecorder.release();
mCamera.lock();
Log.e("ERROR", e.toString());
}
}
return mRecordingStarted;
}
private void startPreview() throws IllegalStateException, IOException {
if (mCamera == null) {
return;
}
try {
mCamera.stopPreview();
} catch (Exception e) {
}
Camera.Parameters parameters = mCamera.getParameters();
mCamera.setDisplayOrientation(0);
mCamProfile = getConfiguredProfile();
mVideoSize = getBestPreviewSize(mCamProfile, parameters);
parameters.setPreviewSize(mVideoSize.width, mVideoSize.height);
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_INFINITY);
mCamera.setParameters(parameters);
mCamera.setPreviewTexture(mPreview.getSurfaceTexture());
mCamera.startPreview();
}
Has anyone disabled sound in either Intent or MediaRecorder when record video in Google
Glass?
I have removed permissions from AndroidManifest and I am not setting the audio source in MediaRecorder but I still record audio.
I am using XE22.
private boolean prepareVideoRecorder(){
if (mCamera != null){
mCamera.release(); // release the camera for other applications
}
mCamera = getCameraInstance();
if (mCamera == null) return false;
mrec = new MediaRecorder();
mCamera.unlock();
mrec.setCamera(mCamera);
//mrec.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
CamcorderProfile profile = getValidCamcorderProfile();
mrec.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mrec.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mrec.setVideoSize(profile.videoFrameWidth, profile.videoFrameHeight);
mrec.setVideoEncodingBitRate(profile.videoBitRate);
mrec.setVideoEncoder(profile.videoCodec);
mrec.setPreviewDisplay(mPreviewHolder.getSurface());
mOutputFile = getOutputMediaFile(MEDIA_TYPE_VIDEO);
mrec.setOutputFile(mOutputFile.toString());
try {
mrec.prepare();
}
catch (Exception e) {
Log.e(TAG, e.getMessage());
return false;
}
return true;
}
private CamcorderProfile getValidCamcorderProfile(){
CamcorderProfile profile;
if (CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_TIME_LAPSE_720P)){
profile = CamcorderProfile.get(CamcorderProfile.QUALITY_TIME_LAPSE_720P);
return profile;
}
if (CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_720P))
profile = CamcorderProfile.get(CamcorderProfile.QUALITY_720P);
else
profile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
return profile;
}
The code is taken from the book Beginning Google Glass Development.
Any Ideas??
I had a solution that worked before for me few years ago but my code is now crashing due to several API updates. Withing hours of try and fail experiment, I got it to start working again.
Steps:
1) Remove anything about audio such as setVideoSource and setAudioEncoder. From the code you posted above. It looks like you already did that but verify that from the rest of your code.
2) Add try catch to setProfile and you are fine to go.
For example:
Instead of doing mrec.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH))
do:
try {
mrec.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
}catch (Exception e){
}
Furthermore, don't use CamcorderProfile profile = getValidCamcorderProfile();. Use mrec.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH)) and that should work.
Also remove the following from your code
mrec.setVideoSize(profile.videoFrameWidth, profile.videoFrameHeight);, mrec.setVideoEncodingBitRate(profile.videoBitRate);, mrec.setVideoEncoder(profile.videoCodec);.
Inside my prepareVideoRecorder() function, this is what my code looks like:
private boolean prepareVideoRecorder(){
if (mCamera != null){
mCamera.release(); // release the camera for other applications
}
mCamera = getCameraInstance();
if (mCamera == null) return false;
mrec = new MediaRecorder();
mCamera.unlock();
mrec.setCamera(mCamera);
//mrec.setAudioSource(MediaRecorder.AudioSource.CAMCORDER); Remove this
mrec.setVideoSource(MediaRecorder.VideoSource.CAMERA);
//Add try catch to setProfile
try {
mrec.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
}catch (Exception e){
}
mrec.setPreviewDisplay(mPreviewHolder.getSurface());
mOutputFile = getOutputMediaFile(MEDIA_TYPE_VIDEO);
mrec.setOutputFile(mOutputFile.toString());
try {
mrec.prepare();
}
catch (Exception e) {
Log.e(TAG, e.getMessage());
return false;
}
return true;
}
To see the recorded video on Glass from your computer, you have to restart Glass.
EDIT:
Get my whole project from here. Its from the book and was modified to record without audio.
https://github.com/InnoBlast/RecordingVideoWithoutSound
I'm trying to develop a simple video recorder
I initialize Camera, and then on button click I run a Runnable that prepares the MediaRecorder:
public void run() {
mCamera.unlock();
mMediaRecorder = new MediaRecorder();
mMediaRecorder.setCamera(mCamera);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecorder.setVideoSize(320, 240);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mMediaRecorder.setOutputFile(mSomeFile);
mMediaRecorder.setMaxDuration(MAX_DURATION);
mMediaRecorder.setOrientationHint(90);
try {
mMediaRecorder.prepare();
mMediaRecorder.start();
} catch (Exception e) {
e.printStackTrace();
}
}
Every thing runs fine but the actual output video contains some blank frames at the beginning. Could it be a hardware issue or rather it needs some optimization from the code?
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.