I am trying to record a video in portrait orientation.
Setting the Camera DisplayOrientation to 90 degrees makes the preview to video be displayed in portrait.
But When calling setOrientationHint() with any given number(0,90,180,270) the video that was created is created always in portrait orientation.
When I have tested it on Jellybean and on ICS, the video orientation was the one I set with the setOrientationHint() method.
Here is the MediaRecorder initialization code:
private void initRecorder() {
Camera camera = Camera.open();
camera.setDisplayOrientation(90);
camera.unlock();
recorder.reset();
recorder.setCamera(camera);
recorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
file = new File("/sdcard/test.mp4");
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
recorder.setOrientationHint(90);//doesn't seem to work on 2.3
recorder.setOutputFile(file.getAbsolutePath());
recorder.setMaxDuration(30000);
recorder.setMaxFileSize(1000000);
}
And this is where I prepare the MediaRecorder:
public void surfaceCreated(SurfaceHolder holder) {
this.holder = holder;
recorder.setPreviewDisplay(holder.getSurface());
try {
recorder.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
finish();
} catch (IOException e) {
e.printStackTrace();
finish();
}
}
EDIT:
Tested on:
Samsung Galaxy S running android 2.2.
Samsung Galaxy W running android 2.3.
Samsung galaxy S2 running ICS - worked.
Samsung galaxy s3 running Jelly Bean - worked.
setOrientationHint() needs to be called before prepare(). Check if this is happening.
Also note that this method only works for 3gpp and mpeg4 formats and some video players choose to ignore this property completely. The video players you are using might be ignoring it.
Related
I have tried to record call with AudioSource.VOICE_CALL in Android. It is working on most of devices like (Samsung S3 ,Samsung S4 , Nexus ) but in redmi xiaomi 1s it is not
Below is snippet of code that I used :
MediaRecorder recorder = new MediaRecorder();
recorder.reset();
recorder.setAudioSource(audiosource);
recorder.setOutputFormat(audioformat);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
recorder.setOutputFile(recording.getAbsolutePath());
recorder.setOnInfoListener(this);
recorder.setOnErrorListener(this);
try {
recorder.prepare();
} catch (java.io.IOException e) {
recorder = null;
return;
}
recorder.start();
I'm trying to write video stream from my Galaxy Tab to server.
according to this manual i should do something like this:
frontCamera = getFrontCamera();
if((socket!= null)&&(frontCamera!=null))
{
try {
frontCamera.setPreviewDisplay(cameraPreview.getHolder());
} catch (IOException e1) {
// TODO Auto-generated catch block
Log.e("","",e1);
}
frontCamera.startPreview();
recorder = new MediaRecorder();
frontCamera.unlock();
recorder.setCamera(frontCamera);
recorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
recorder.setProfile(CamcorderProfile.get( CamcorderProfile.QUALITY_HIGH));
pfd = ParcelFileDescriptor.fromSocket(socket);
recorder.setOutputFile(pfd.getFileDescriptor());
recorder.setPreviewDisplay(cameraPreview.getHolder().getSurface());
try {
recorder.prepare();
recorder.start();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
Log.e("","",e);
} catch (IOException e) {
// TODO Auto-generated catch block
Log.e("","",e);
}
but all fails on step recorder.start(); with strange error
02-01 19:03:39.265: E/MediaRecorder(11922): start failed: -19
what does that mean and what should I do to start recorder?
UPD:
Trouble happens because of my getFrontCamera method. when I replace it with camera.open() all works correct.
protected Camera getFrontCamera()
{
Camera.CameraInfo inf = new Camera.CameraInfo();
for(int i = 0; i< Camera.getNumberOfCameras(); i++)
{
Camera.getCameraInfo(i, inf);
if(inf.facing==Camera.CameraInfo.CAMERA_FACING_FRONT)
{
return Camera.open(i);
}
}
return null;
}
Upd2 - yes, explicit setting of format and encoders solved the trouble -
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
Maybe because of pre-build formats are for back camera... But strange anyway.
I don't see output format setup, so try adding to recorder set up:
recorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
Have a look
And though it is streaming video, so that set -
recorder.setOutputFormat(8);
recorder.setOutputFile(socketFd);
Have fun.
I've a hack here, extending media recorder class and removing super.setVideoFrameRate(rate) solves the problem for me.
If you still want to use CamcorderProfile.QUALITY_HIGH with the front camera, you can use the following:
CamcorderProfile camcorderProfile = CamcorderProfile.get(currentCameraId, CamcorderProfile.QUALITY_HIGH);
recorder.setProfile(camcorderProfile);
where int currentCameraId is Camera.CameraInfo.CAMERA_FACING_BACK or ...FRONT
So the profile is indeed dependent on the camera (for high-end phones it appears to work fine without the distinction, since they all support 1080p by now, but low-end phones may crash otherwise)
I'm working on a custom video recording class, and I'm having some issues getting the camera preview to display when the Activity first appears. I'm calling this function inside the surfaceCreated callback:
private void initRecorder(Surface surface) throws IOException {
// It is very important to unlock the camera before doing setCamera
// or it will results in a black preview
if(camera == null) {
camera = Camera.open();
camera.unlock();
}
if(recorder == null)
recorder = new MediaRecorder();
recorder.setPreviewDisplay(surface);
recorder.setCamera(camera);
camera.startPreview();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setOutputFile("/sdcard/test.mp4");
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
recorder.setVideoEncodingBitRate(15000000);
recorder.setMaxDuration(10000); // length of video in MS
recorder.setVideoSize(720, 480);
recorder.setVideoFrameRate(30);
try {
recorder.prepare();
} catch (IllegalStateException e) {
// This is thrown if the previous calls are not called with the
// proper order
e.printStackTrace();
}
}
When the Activity starts, my app crashes saying:
java.lang.RuntimeException: startPreview failed
Above that error, I noticed a line saying:
attempt to use a locked camera from a different process (old pid 4894, new pid 6405)
When I step through the code, that error is occurring on the camera.startPreview() line. If I remove that line from my code, the preview shows up fine after I call recorder.start(), and prior to that I just have a black screen with my record button. Once I stop recording, the preview continues to show fine (I am calling camera.startPreview() after I stop recording).
Since I'm calling camera.unlock() only a few lines prior to starting the preview, and the two calls occur in the same function, how can I be having this error?
Edit: I tested the same code minus the call to startPreview() on a Droid X2 and a Droid 1, and it works fine. It looks like the EVO 4G is the problem. I will continue to investigate.
I answered a very similar question here: preview display in android media recorder
See if it helps you, it has a whole Activity that works with a preview and records a video.
camera.unlock() must be called from the same thread where camera was locked before. Check your logs for messages like Unlock call from pid 19322; currently locked to pid 17652.
Note that lock can be set by calling Camera.lock() or MediaRecorder.start()
Since API level 14, camera is automatically locked for applications in
MediaRecorder.start(). Applications can use the camera (ex: zoom)
after recording starts. There is no need to call this after recording
starts or stops.
Arrange code like this and decrease video encoding rate. It is very high for your video size. This may not be creating a problem on your device because on some devices it is clipped internally.
private void initRecorder(Surface surface) throws IOException {
// It is very important to unlock the camera before doing setCamera
// or it will results in a black preview
if (camera == null) {
camera = Camera.open();
camera.unlock();
}
if (recorder == null)
recorder = new MediaRecorder();
recorder.setCamera(camera);
camera.startPreview();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
recorder.setVideoEncodingBitRate(2048000);
recorder.setMaxDuration(10000); // length of video in MS
recorder.setVideoSize(720, 480);
recorder.setVideoFrameRate(30);
recorder.setOutputFile("/sdcard/test.mp4");
recorder.setPreviewDisplay(surface);
try {
recorder.prepare();
} catch (IllegalStateException e) {
// This is thrown if the previous calls are not called with the
// proper order
e.printStackTrace();
}
}
I am using the media recorder class for recording video, I initialize the recorder with following properties,
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
But the quality of video is not as same as video I shoot over native android camera, my video recorded using media recorder is of poor quality as compared to the native one, how can I improve the video quality.
If any one knows me help me out.Thanks
Finally I found the code to record high quality video in android 2.1 by setting videEncodingBitRate , AudioEncodingBitRate, AudioSamplingRate ...etc. Using this method you can set the properties for video whatever you want to provide high quality video.
For setting high quality and low quality parameter refer this page,
http://www.andgps.com/20110410/camcorderprofile-predefined-camcorder-profile-settings-for-camcorder-applications
The code i used with base version android 2.1 to produce high quality video is shown below,
recorder = new MediaRecorder();
Method[] methods = recorder.getClass().getMethods();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setVideoFrameRate(24);
recorder.setVideoSize(720, 480);
for (Method method: methods){
try{
if (method.getName().equals("setAudioChannels")){
method.invoke(recorder, String.format("audio-param-number-of-channels=%d", 1));
}
else if(method.getName().equals("setAudioEncodingBitRate")){
method.invoke(recorder,12200);
}
else if(method.getName().equals("setVideoEncodingBitRate")){
method.invoke(recorder, 3000000);
}
else if(method.getName().equals("setAudioSamplingRate")){
method.invoke(recorder,8000);
}
else if(method.getName().equals("setVideoFrameRate")){
method.invoke(recorder,24);
}
}catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
`
use the following settings for Video Recordings:-
private void cameraSettings()
{
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
mediaRecorder.setVideoSize(width, height);
mediaRecorder.setVideoFrameRate(videoFramePerSecond);
}
use videoFramePerSecond = 30 and width = 1280 and height= 720..
This setting you can do by your own as per your requirment.
try this
mrec.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
mrec.setPreviewDisplay(surfaceHolder.getSurface());
Try adding this line
recorder.setVideoSize(640,480);
Or check out the screen resolutions supported by your device and set the best one accordingly.
To enhance the video quality, you should consider setting the video size on your mediaRecorder instance to the max resolution of your device.
This snippet will do the job
WindowManager wm = (WindowManager) getBaseContext().getSystemService(Context.WINDOW_SERVICE);
Point size = new Point();
wm.getDefaultDisplay().getRealSize(size);
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecorder.setOutputFile(file.toString());
mMediaRecorder.setVideoEncodingBitRate(10000000);
mMediaRecorder.setVideoFrameRate(30);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.HEVC);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
mMediaRecorder.setVideoSize(size.y, size.x);
int rotation =getWindowManager().getDefaultDisplay().getRotation();
switch (mSensorOrientation) {
case SENSOR_ORIENTATION_DEFAULT_DEGREES:
mMediaRecorder.setOrientationHint(DEFAULT_ORIENTATIONS.get(rotation));
break;
case SENSOR_ORIENTATION_INVERSE_DEGREES:
mMediaRecorder.setOrientationHint(INVERSE_ORIENTATIONS.get(rotation));
break;
}
mMediaRecorder.prepare();
I'm recording videos with MediaRecorder, but it appears that whatever setting I use, the framerate is appalling (~ 1fps)
This is my code:
recorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
CamcorderProfile cp = CamcorderProfile.get(HIGH_QUALITY ? CamcorderProfile.QUALITY_HIGH : CamcorderProfile.QUALITY_LOW);
System.out.println("RECORDING AT " + cp.videoFrameRate); // Says 30fps
recorder.setProfile(cp);
recordingFilename = tempFileName();
recorder.setOutputFile(recordingFilename);
recorder.setPreviewDisplay(holder.getSurface());
try {
recorder.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
finish();
} catch (IOException e) {
e.printStackTrace();
finish();
}
recorder.start();
It appears that it is the ROM I am using. I didn't realise I get the same crappy frame rate using the standard Camera app when recording video.
Nevermind :)