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)
Related
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.
I am getting this error when running start() for mediarecorder.
06-28 18:46:22.570: E/MediaRecorder(9540): start failed: -19
06-28 18:46:22.570: W/System.err(9540): java.lang.RuntimeException: start failed.
I am extending mediarecorder class
My code:
camera = Camera.open(cameraId);
super.setCamera(camera);
super.setVideoSource(MediaRecorder.VideoSource.CAMERA);
super.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
if (mode==MODE_DEFAULT) {
super.setMaxDuration(1000);
super.setMaxFileSize(Integer.MAX_VALUE);
} else {
// On some phones a RuntimeException might be thrown :/
try {
super.setMaxDuration(0);
super.setMaxFileSize(Integer.MAX_VALUE);
} catch (RuntimeException e) {
Log.e(TAG,"setMaxDuration or setMaxFileSize failed !");
}
}
super.setVideoEncoder(videoEncoder);
if(surfaceHolder!=null)
super.setPreviewDisplay(surfaceHolder.getSurface());
//super.setVideoSize(quality.resX,quality.resY);
super.setVideoFrameRate(quality.frameRate);
super.setVideoEncodingBitRate(quality.bitRate);
I saw these pages
Error opening android camera for streaming video
Android MediaRecorder - "start failed: -19"
But non of them worked for me...
Running on archos 80 g9, android 3.2
Any one got any ideas?
Fixed by removing
super.setVideoFrameRate(quality.frameRate);
I was facing the same proble during video recording and i solved it by adding this for video recording
/**
* Start video recording by cleaning the old camera preview
*/
private void startVideoRecorder() {
// THIS IS NEEDED BECAUSE THE GLASS CURRENTLY THROWS AN ERROR OF
// "MediaRecorder start failed: -19"
// THIS WONT BE NEEDED INCASE OF PHONE AND TABLET
// This causes crash in glass kitkat version so remove it
// try {
// mCamera.setPreviewDisplay(null);
// } catch (java.io.IOException ioe) {
// Log.d(TAG,
// "IOException nullifying preview display: "
// + ioe.getMessage());
// }
// mCamera.stopPreview();
// mCamera.unlock();
recorder = new MediaRecorder();
// Let's initRecorder so we can record again
initRecorder();
}
/**
* Initialize video recorder to record video
*/
private void initRecorder() {
try {
File dir = new File(folderPath);
if (!dir.exists()) {
dir.mkdirs();
}
mCamera.stopPreview();
mCamera.unlock();
videofile = new File(dir, fileName + ".mp4");
recorder.setCamera(mCamera);
// Step 2: Set sources
recorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
// Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
recorder.setProfile(CamcorderProfile
.get(CamcorderProfile.QUALITY_HIGH));
// Step 4: Set output file
recorder.setOutputFile(videofile.getAbsolutePath());
// Step 5: Set the preview output
recorder.setPreviewDisplay(mPreview.getHolder().getSurface());
// Step 6: Prepare configured MediaRecorder
recorder.setMaxDuration(video_duration * 1000);
recorder.setOnInfoListener(new OnInfoListener() {
#Override
public void onInfo(MediaRecorder mr, int what, int extra) {
if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) {
mCamera.stopPreview();
releaseMediaRecorder();
/*
* initiate media scan and put the new things into the
* path array to make the scanner aware of the location
* and the files you want to see
*/MediaScannerConnection.scanFile(
CuxtomCamActivity.this,
new String[] { videofile.getPath() }, null,
null);
Intent intent = new Intent();
intent.putExtra(CuxtomIntent.FILE_PATH,
videofile.getPath());
intent.putExtra(CuxtomIntent.FILE_TYPE, FILE_TYPE.VIDEO);
setResult(RESULT_OK, intent);
finish();
}
}
});
recorder.prepare();
recorder.start();
} catch (Exception e) {
Log.e("Error Stating CuXtom Camera", e.getMessage());
}
}
private void releaseMediaRecorder() {
if (recorder != null) {
recorder.reset(); // clear recorder configuration
recorder.release(); // release the recorder object
recorder = null;
}
}
To see detail of how a camera is actually implemented refer to Open Source Cuxtom Cam
I found a subtle hint in documentation for the MediaRecorder.start() method that suggest if it fails to lock() the Camera before attempting to re-record. This worked for me. Implies a Camera state bug was fixed post API level 13 - calling Camera.lock() is the known workaround.
This code worked for me (found here)
mCamera.unlock(); // maybe not for your activity flow
//1st. Initial state
mProfile = CamcorderProfile.get( CamcorderProfile.QUALITY_HIGH );
mMediaRecorder = new MediaRecorder();
mMediaRecorder.setCamera( mCamera );
//2nd. Initialized state
mMediaRecorder.setAudioSource( MediaRecorder.AudioSource.CAMCORDER );
mMediaRecorder.setVideoSource( MediaRecorder.VideoSource.CAMERA );
//3rd. config
mMediaRecorder.setOutputFormat( mProfile.fileFormat );
mMediaRecorder.setAudioEncoder( mProfile.audioCodec );
mMediaRecorder.setVideoEncoder( mProfile.videoCodec );
mMediaRecorder.setOutputFile( "/sdcard/FBVideo.3gp" );
mMediaRecorder.setVideoSize( mProfile.videoFrameWidth, mProfile.videoFrameHeight );
mMediaRecorder.setVideoFrameRate( mProfile.videoFrameRate );
mMediaRecorder.setVideoEncodingBitRate( mProfile.videoBitRate );
mMediaRecorder.setAudioEncodingBitRate( mProfile.audioBitRate );
mMediaRecorder.setAudioChannels( mProfile.audioChannels );
mMediaRecorder.setAudioSamplingRate( mProfile.audioSampleRate );
mMediaRecorder.setPreviewDisplay( mHolder.getSurface() );
try {
mMediaRecorder.prepare();
mMediaRecorder.start();
} catch ( IllegalStateException e ) {
e.printStackTrace();
} catch ( IOException e ) {
e.printStackTrace();
}
The problem here is about the camera. Just use camera.unlock() to allow the media process to access the camera.
This must be done before calling MediaRecorder.setCamera(Camera). This cannot be called after recording starts.
Read more here.
I am trying to record audio from the microphone on the Android emulator with this code:
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(Environment.getExternalStorageDirectory() + "/test/test.3gp");
try {
recorder.prepare();
}
catch (IOException io) {
Log.v(LOG_TAG, "Could not prepare the audio " + io.getMessage());
}
recorder.start();
For stopping the audio, this is the code:
recorder.stop();
recorder.reset();
recorder.release();
The recording process works fine but the resulting audio that is distorted. When I record an audio for 60 seconds duration and play it, it's duration is being shown as 120 seconds. The measurement is not exact but the this is just to give you an idea.
Only the AMR_NB encoder is working on my emulator. I have tried different output formats but the result is always the same.
Is it a limitation of the emulator or am I doing something wrong here?
Edit 1:
I have tried the AudioRecord class too and the result is the same dragging audio.
Thanks.
I have been working for the same and found the solution, Try using the following code:
private void startRecording()
{
this.recorder = new MediaRecorder();
this.recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
this.recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
this.recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
MediaRecorder.getAudioSourceMax();
this.recorder.setOutputFile(this.getFilename());
this.recorder.setOnErrorListener(this.errorListener);
this.recorder.setOnInfoListener(this.infoListener);
try
{
this.recorder.prepare();
this.recorder.start();
} catch (final IllegalStateException e)
{
e.printStackTrace();
} catch (final IOException e)
{
e.printStackTrace();
}
}
This is working perfactly. Hope it helps you :)
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 :)