Surface view Camera not saving video - android

private boolean prepareMediaRecorder(){
myCamera = getCameraInstance();
// set the orientation here to enable portrait recording.
setCameraDisplayOrientation(this,0,myCamera);
mediaRecorder = new MediaRecorder();
myCamera.unlock();
mediaRecorder.setCamera(myCamera);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
String pathh=Environment.getExternalStorageDirectory().getPath();
Toast.makeText(getApplicationContext(), "Path is "+pathh,Toast.LENGTH_LONG).show();
mediaRecorder.setOutputFile("/sdcard/myvideo1.mp4");
//mediaRecorder.setOutputFile("/storage/sdcard0/myvideo1.mp4");
mediaRecorder.setMaxDuration(60000); // Set max duration 60 sec.
mediaRecorder.setMaxFileSize(50000000); // Set max file size 50Mb
mediaRecorder.setPreviewDisplay(myCameraSurfaceView.getHolder().getSurface());
mediaRecorder.setOrientationHint(MainActivity.orientation);
try {
mediaRecorder.prepare();
} catch (IllegalStateException e) {
releaseMediaRecorder();
return false;
} catch (IOException e) {
releaseMediaRecorder();
return false;
}
return true;
}
My task is to capture video using surface view and send that to server. I found 1st solution to capture video in surface and save it in memory using some stack overflow link. One is below.
Switch To Front Camera and Back Camera Android SurfaceView
At first the app starts and worked perfectly saved the video also. Then I deleted the video and then tried video was not saving in memory. I tried with renaming the file also not worked.
"lrwxrwxrwx" what is this code value mean in android. I find this in DDMS

The code is missing MediaScannerConnection.scanFile, which updates gallery. The code may be saving the videos, but the gallery will not show the videos. Restarting the phone will scan the gallery, and if videos were saved they will appear. Also, the files app will probably list the videos.
If the program is saving videos, add code at or near the end of the program, or override onPause:
MediaScannerConnection.scanFile(this, new String[]{videoPathName}, null, null);
videoPathName is a String you need to set to the path and name of the saved video.
If still not working, the following code should work, but you will still need to add the MediaScanner: http://sandyandroidtutorials.blogspot.com/2013/05/android-video-capture-tutorial.html

Related

How to get File path from pdfUri obtained from PDF chooser intent library, in onActivityResult call back?

With reference to the question asked in the same category, and as an extension of this:
How to get the file path from a URI that points to a PDF document?
(How to get the file path from a URI that points to a PDF document?)
My question:
In my HTC 816 Desire phone [Note: this device is upgraded to MarshMallow but still has crashes of KitKat. As a developer, I have experienced that Camera opened by intent to get the image captured by it, never releases its resources. This gives me an internal crash, when I try to take the second picture.], the returned path is starting with "/document/primary:", and it is retained in 'pdfUri.getPath()' resulting in file not found exception. Also when I search in 'MediaStore.Images.Media.DATA', column index returned is -1.
Q1. Should I simply remove "/document/primary:" from the file path, when the column index comes -1. As because in higher phones (23 and above), this (pdfUri.getPath()) works OK, giving me correct path.
Q2. Where should I get the patches for my phone to fix Camera resource not releasing bug, and there are other bugs at Firm-Ware level.
Please guide me, as well, by asking this question correctly, if in case it is not been asked accurately.
In order to resolve the problem, I am trying to do the following:
I am going to make the code generic, that I got as a solution, for many other file formats other than PDF:
private String saveFileFromUri(Uri pdfUri){
try{
InputStream is=
baseActivity.getContentResolver().openInputStream(pdfUri);
byte[]bytesArray=new byte[is.available()];
int read=is.read(bytesArray);
//write to sdcard
File dir=new File(Environment.getExternalStorageDirectory(),"/PRJ");
boolean mkdirs=dir.mkdirs();
File myPdf=new
File(Environment.getExternalStorageDirectory(),"/PRJ/myPdf.pdf");
if(read==-1&&mkdirs){
}
FileOutputStream fos=new FileOutputStream(myPdf.getPath());
fos.write(bytesArray);
fos.close();
// System.out.println(fileString);
return myPdf.getPath();
}catch(FileNotFoundException e){
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
return null;}
In order to be able to release Camera resource, I will use surface view based Camera Activity which allows to do that. Here is a part of the code:
Release camera resource:
#Override
public void onPause()
{
super.onPause();
if (mCamera != null){
// mCamera.setPreviewCallback(null);
mPreview.getHolder().removeCallback(mPreview);
releaseMediaRecorder();
mCamera.release(); // release the camera for other applications
mCamera = null;
}
}
#Override
public void onResume() {
super.onResume();
if (mCamera == null) {
mCamera=getCameraInstance();
mPreview = new CameraPreview(this.getActivity(), mCamera);
preview.addView(mPreview);
}
}
Happy Coding :-)

Recording videos with overlay images without using third party library on android

Iam trying to develop an android based camera application which requires recording videos on live camera preview with overlay images. Is there any way on android using which we can record videos with overlay images without using any third party library .
Currently iam using an additional Surfaceview as an overlay on live camera screen and MediaRecorder class for recording videos.Here is my code :
recorder = new MediaRecorder();
recorder.setCamera(mCam);
String filename="";
String path="";
path= Environment.getExternalStorageDirectory().getAbsolutePath().toString();
Date date=new Date();
filename="/rec"+date.toString().replace(" ", "_").replace(":", "_")+".mp4";
File file=new File(path,filename);
recorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
recorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setVideoSize(mPreviewSize.width, mPreviewSize.height);
recorder.setVideoEncodingBitRate(10000000);
recorder.setVideoFrameRate(30);
try {
recorder.prepare();
} catch (IllegalStateException e) {
releaseMediaRecorder();
return false;
} catch (IOException e) {
releaseMediaRecorder();
return false;
}
The above code crashes the application during the start of recording process.
Is there any other way in OpenGL ES 2.0 apart from MediaRecorder for recording videos with overlay.
Please advice.

Android Media Recorder preview before saving

I am recording video with audio using MediaRecorder, however when you take pictures with Camera you can save the image into a Bitmap and display it before saving, I want to do the same with the video - like Snapchat does, is there a way? I don't want to save the video, display it, and then have the option to delete or keep it.
I am using this code in order to record videos:
String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/SelfieLightCamera/";
File dir = new File(path);
if (!dir.exists())
dir.mkdirs();
String myFile = path + "Video_" + System.currentTimeMillis() + ".mp4";
mediaRecorder = new MediaRecorder();
mCamera.unlock();
mediaRecorder.setCamera(mCamera);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
mediaRecorder.setOutputFile(myFile);
try {
mediaRecorder.prepare();
} catch (IllegalStateException e) {
releaseMediaRecorder();
e.printStackTrace();
} catch (IOException e) {
releaseMediaRecorder();
e.printStackTrace();
}
mediaRecorder.start();
The cool thing about Android apps is that you can extract the APK from your phone and decompile the package to see the actual Java code. Although it's usually obfuscated (as is the case with Snapchat), you can still get quite a good view into the inner workings of the application.
When looking into how Snapchat does it, I found out that they also use MediaRecorder just like you but save the file into internal storage. Internal storage means that the file is only accessible by the app that holds it.
Here's a few lines of code that gives you a general idea of Snapchat does behind the scenes:
mediaRecorder.setCamera(ay$b.b());
mediaRecorder.setAudioSource(5);
if (z) {
mediaRecorder.setVideoSource(2);
} else {
mediaRecorder.setVideoSource(1);
}
mediaRecorder.setProfile(camcorderProfile);
mediaRecorder.setVideoSize(i, i2);
mediaRecorder.setMaxFileSize(bm.a());
mediaRecorder.setVideoEncodingBitRate(bm.a(camcorderProfile));
// Removed some code here…
mediaRecorder.setOrientationHint(this.f);
mediaRecorder.setMaxDuration(HttpService.DEFAULT_READ_TIMEOUT);
mediaRecorder.setOutputFile(this.a.toString());
if (this.c != null) {
mediaRecorder.setPreviewDisplay(this.c);
What you should do is record the video normally and save it to the internal storage. If you want to "keep" it, you just move it to the external storage where it's publicly available. Discarding it means that you just delete it from the internal storage.

android byte[] data modification

I did my own camera app on Android.
1) Configuring camera and preview :
Camera.Parameters parameters = camera.getParameters();
// My camera takes landscape picture by befault (Samsung GT-9300).
// But my app is only in portrait mode.
camera.setDisplayOrientation(90);
// Here to rotate final pict
parameters.set("rotation", 90);
// Some code to define best preview resolution and best picture resolution
... some code ...
// Apply
camera.setParameters(parameters);
2) StartPreview
// Here I see what i want to see... Is there no problem here.
camera.startPreview();
3) GetOutputMediaFile()
// private function to create empty file which will receive data
private static File getOutputMediaFile(){
String NewFolder = "/TEST";
String StorageDirectory;
StorageDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).toString();
File mediaStorageDir = new File(StorageDirectory + NewFolder);
if (!mediaStorageDir.exists()){
if (!mediaStorageDir.mkdirs()){
Log.d("myApp", "failed to create directory");
return null;
} else {
mediaStorageDir.mkdir();
}
}
String date = new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss", Locale.FRANCE).format(new Date());
File photo = new File(StorageDirectory + NewFolder, "photo_" + date + ".jpg");
return photo;
}
4) Here my problem
// camera.takePicture(null, null, mPicture) called on onCreate function
// Here this callback
private PictureCallback mPicture = new PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
pictureFile = getOutputMediaFile();
if (pictureFile == null){
Log.d(TAG, "Error creating media file, check storage permissions: " + e.getMessage());
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
};
On my phone, if i go on my gallery, or original my files app, i have thumbnail and photo correctly oriented.
Now if I go, with Root File Manager, on this picture folder, thumbnail is oriented by default (real camera orientation), and same as if I look my picture with my computer.
Then I think my data var (byte[] data) on my onPictureTaken function is not good.
I think data is like that :
How I think my var data is
But I would like to have that as my var data :
How I would like to have
I know my var data is only byte[] but these cat pictures is to shows how I see my data var.
Now my questions :
A) Have I right on how my data variable is ?
B) If yes, can you say me how to do 90° rotation on this "array" ?
You should not change the image bits to account for rotation.
Rotation is stored in the JPG EXIF image metadata orientation value, so you just need to set the metadata value to match the camera orientation. Read more about this EXIF value and others here.
To manage the EXIF data you can use framework class ExifInterface.
If the picture shows correctly in your phone's gallery application, it is likely correctly oriented. You can experiment with different values for the Parameters.setRotation and see if they affect what you see in the gallery app.
Some picture viewing programs do not correctly apply the EXIF orientation field, which can lead to them drawing the image incorrectly rotated. If that's the case, changing the orientation field does nothing, since those programs will not work with any orientation value. You'll have to actually rotate the JPEG image, instead of just setting the metadata field, to get them to look correct there.
If you want to do this inside Android, you'll have to decode the byte[] you receive from the camera to a Bitmap (with a BitmapFactory.decodeByteArray, rotate the bitmap, and save the result as a JPEG. You'll lose all the other EXIF metadata (date/time taken, etc) unless you use ExifInterface to write them back. It's also possible to losslessly rotate a JPEG, but I don't know if there are Android libraries for that.

Intent to take video in android

I need to take video from my application using only front camera. I am using intent to perform this action.
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, videoUri);
intent.putExtra("android.intent.extra.durationLimit", 30);
intent.putExtra("android.intent.extras.CAMERA_FACING", 1); //to open front facing camera
startActivityForResult(intent, VIDEO_CAPTURE);
When I run the application, I am able to take video using front camera. But suppose when I click my record video button and the camera view is opened. In that user go and change the camera to rear camera, then always my intent is opening rear camera only after that. Its not taking the line
intent.putExtra("android.intent.extras.CAMERA_FACING", 1);
Could someone please tell me whats the issue and is it able to be solved using intent?
There is no reliable way to use intent to show the front camera all the time at least not on all devices. Only way to reliably do it is to create a SurfaceView and capture the video yourself.
See if this works :
try {
if (Camera.getNumberOfCameras() == 2) {
if (frontCamera) {
frontCamera = false;
prCamera.stopPreview();
prMediaRecorder.release();
prMediaRecorder = null;
prCamera.release();
prCamera = null;
} else {
frontCamera = true;
prCamera.stopPreview();
prMediaRecorder.release();
prMediaRecorder = null;
prCamera.release();
prCamera = null;
}
Intent intent = new Intent(VideoCapture_New.this,
VideoCapture_New.class);
startActivity(intent);
} else {
Toast.makeText(VideoCapture_New.this,
"Your device doesn't contain Front Camera.",
Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(VideoCapture_New.this,
"Your device is not compatible for Front Camera.",
Toast.LENGTH_SHORT).show();
}
source : Front camera in android
Else you could use Android keyEvents to trigger the button press of camera switch if video starts to record on back camera. KeyEvents need to timed perfectly otherwise they end triggering something else! Check : KeyEvent.
Also if you are making use of
mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
This signature for CamcorderProfile.get() defaults to a profile for the back-facing camera.
So instead of using this, use :
public static CamcorderProfile get (int cameraId, int quality)
mediaRecorder.setVideoFrameRate(15);
use any value, 1 - 15 for frame rate.
check this for additional details.
Hope this helps.
Create your custom video taking application that assure to only use the Front camera
i think this is the only way to do this .
Hope that Helps .

Categories

Resources