First of all, I've checked stackoverflow again an again about this problem and I'm still not able to find out what's wrong ... I try to record a video, without audio, and I still have this prepared failed -1 issue ... The file is created but stays at 0kb. I tried different output format, check my manifest etc ... Can't find the problem :(
More info => I test my app on a Galaxy S2 android 2.3.5 ...
Any help more than appreciated ...
Thanks !
Here is my CameraView activity, where I display the preview and record the vidéo ( preview works fine ):
package com.guillaimej.testapplication.app;
import java.io.File;
import java.io.FileDescriptor;
import java.io.IOException;
import java.util.List;
import android.graphics.ImageFormat;
import android.media.CamcorderProfile;
import android.util.Log;
import android.content.Context;
import android.graphics.Point;
import android.hardware.Camera;
import android.hardware.Camera.Size;
import android.media.MediaRecorder;
import android.os.Environment;
import android.view.Display;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.WindowManager;
import android.widget.Toast;
public class CameraInputView extends SurfaceView implements SurfaceHolder.Callback {
private static final String TAG = "CameraInputView";
private SurfaceHolder mHolder;
private Camera mCamera;
private Size mPreviewSize;
private List<Size> mSupportedPreviewSizes;
int w, h;
MediaRecorder mediaRecorder;
public CameraInputView(Context context, Camera camera) {
super(context);
// FETCH THE CAMERA INSTANCE
mCamera = camera;
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
Camera.Parameters params = mCamera.getParameters();
// Find screen size
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
if(android.os.Build.VERSION.SDK_INT >= 13){
w = display.getWidth();
h = display.getHeight();
Point point = new Point();
display.getSize(point);
w = point.x;
h = point.y;
}else{
w = display.getWidth();
h = display.getHeight();
}
mPreviewSize = getOptimalPreviewSize(params.getSupportedPreviewSizes(),w,h);
params.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
params.setPreviewFormat(ImageFormat.NV21);
if (params.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_AUTO)) {
params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
}
mCamera.setParameters(params);
try {
mCamera.setPreviewDisplay(mHolder);
} catch (IOException e) {
Log.e(TAG, "Error mCamera.setPreviewDisplay(mHolder); : " + e.getMessage());
e.printStackTrace();
}
// SET PREVIEW DISPLAY
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
// INIT THE MEDIA RECORDER
initMediaRecorder();
}
public boolean startRecording(){
try {
mediaRecorder.start();
return true;
}catch (IllegalStateException e) {
Log.e(TAG, "Error IllegalStateException in startRecording(): " + e.getMessage());
}
return false;
}
public boolean stopRecording(){
try {
mediaRecorder.stop();
return true;
}catch (IllegalStateException e) {
Log.e(TAG, "Error IllegalStateException in stopRecording(): " + e.getMessage());
}
return false;
}
public boolean initMediaRecorder(){
////////////////////////////////////////////////////////////////////////////
// Camera recording
try {
mediaRecorder = new MediaRecorder();
mediaRecorder.setCamera(mCamera);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
String mFileName = Environment.getExternalStorageDirectory().getAbsolutePath();
String outputFile = mFileName + "/default.mp4";
Log.i(TAG, "File Path is: " + outputFile);
mediaRecorder.setOutputFile(outputFile);
mediaRecorder.setMaxDuration(5000);
mediaRecorder.setPreviewDisplay(mHolder.getSurface());
} catch (IllegalStateException e) {
Log.e(TAG, " Error IllegalStateException in initMediaRecorder():" + e.getMessage());
e.printStackTrace();
}
return false;
///////////////////////////////////////////////////////////////////////////
}
public void surfaceCreated(SurfaceHolder holder) {
if (mediaRecorder != null) {
try {
mediaRecorder.prepare();
} catch (IllegalStateException e) {
Log.e(TAG, "Error IllegalStateException in prepareMediaRecorder(): " + e.getMessage());
} catch (IOException e) {
Log.e(TAG, "Error IOException in prepareMediaRecorder(): " + e.getMessage());
}
}
}
public Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h){
final double ASPECT_TOLERANCE = 0.1;
double targetRatio=(double)h / w;
if (sizes == null) return null;
Camera.Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
int targetHeight = h;
for (Camera.Size size : sizes) {
double ratio = (double) size.width / size.height;
if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
if (optimalSize == null) {
minDiff = Double.MAX_VALUE;
for (Camera.Size size : sizes) {
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
}
return optimalSize;
}
public void surfaceDestroyed(SurfaceHolder holder) {
if(mediaRecorder != null){
mediaRecorder.release();
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// If your preview can change or rotate, take care of those events here.
// Make sure to stop the preview before resizing or reformatting it.
if (mHolder.getSurface() == null){
// preview surface does not exist
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e){
}
// set preview size and make any resize, rotate or
// reformatting changes here
// start preview with new settings
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e){
System.out.println("Error starting camera preview: " + e.getMessage());
}
}
}
Here is the layout for this activity :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context="com.guillaimej.testapplication.app.CameraInputActivity">
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/camera_layout"
android:layout_weight="0.2">
</FrameLayout>
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1">
<ProgressBar
style="?android:attr/progressBarStyleHorizontal"
android:id="@+id/record_progress_bar"
android:layout_width="fill_parent"
android:layout_height="5dp"
android:max="5"
/>
</FrameLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:gravity="center_horizontal"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/default_margin"
android:id="@+id/button_layout">
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/record"
android:background="@drawable/record"
android:clickable="true"
android:layout_weight="0.0"/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/domygif"
android:background="@drawable/flask"
android:clickable="true"
android:layout_weight="0.0"/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/swap_cam"
android:background="@drawable/swap"
android:clickable="true"
android:layout_weight="0.0"/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/cancel"
android:background="@drawable/cancel"
android:clickable="true"
android:layout_weight="0.0"/>
</LinearLayout>
</LinearLayout>
And here is my manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.guillaimej.testapplication.app" >
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="10" />
<uses-permission android:name="android.permission.CAMERA" />
<!--<uses-permission android:name="android.permission.RECORD_AUDIO" />-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".ListOfFileActivity"
android:label="@string/title_activity_list_of_file" >
</activity>
<activity
android:name=".VideoActivity"
android:label="@string/title_activity_video" >
</activity>
<activity
android:name=".CameraInputActivity"
android:label="@string/title_activity_camera_input" >
</activity>
<activity
android:name=".CustomImageGallery"
android:label="@string/cutom_gallery_title" >
</activity>
<activity
android:name=".GIFeditActivity"
android:label="@string/title_activity_gifedit" >
</activity>
</application>
</manifest>
And finally, here is what I get in the logcat:
06-29 12:51:03.910 14280-14280/com.guillaimej.testapplication.app D/dalvikvm﹕ GC_EXTERNAL_ALLOC freed 74K, 48% free 2821K/5379K, external 0K/0K, paused 58ms
06-29 12:51:04.015 14280-14280/com.guillaimej.testapplication.app D/CLIPBOARD﹕ Hide Clipboard dialog at Starting input: finished by someone else... !
06-29 12:51:07.735 14280-14280/com.guillaimej.testapplication.app I/dalvikvm﹕ Could not find method android.view.Display.getSize, referenced from method com.guillaimej.testapplication.app.CameraInputView.<init>
06-29 12:51:07.735 14280-14280/com.guillaimej.testapplication.app W/dalvikvm﹕ VFY: unable to resolve virtual method 7585: Landroid/view/Display;.getSize (Landroid/graphics/Point;)V
06-29 12:51:07.735 14280-14280/com.guillaimej.testapplication.app D/dalvikvm﹕ VFY: replacing opcode 0x6e at 0x002e
06-29 12:51:07.735 14280-14280/com.guillaimej.testapplication.app D/dalvikvm﹕ VFY: dead code 0x0031-0038 in Lcom/guillaimej/testapplication/app/CameraInputView;.<init> (Landroid/content/Context;Landroid/hardware/Camera;)V
06-29 12:51:07.820 14280-14280/com.guillaimej.testapplication.app E/Surface﹕ Surface::init token -2 identity 979
06-29 12:51:07.825 14280-14280/com.guillaimej.testapplication.app E/MediaRecorder﹕ prepare failed: -1
06-29 12:51:07.825 14280-14280/com.guillaimej.testapplication.app E/CameraInputView﹕ Error IOException in prepareMediaRecorder(): prepare failed.
06-29 12:51:15.135 14280-14280/com.guillaimej.testapplication.app E/MediaRecorder﹕ start called in an invalid state: 0
06-29 12:51:15.135 14280-14280/com.guillaimej.testapplication.app E/CameraInputView﹕ Error IllegalStateException in startRecording(): null
06-29 12:51:19.695 14280-14280/com.guillaimej.testapplication.app E/MediaRecorder﹕ stop called in an invalid state: 0
06-29 12:51:19.695 14280-14280/com.guillaimej.testapplication.app E/CameraInputView﹕ Error IllegalStateException in stopRecording(): null
06-29 12:51:19.705 14280-14441/com.guillaimej.testapplication.app W/System.err﹕ java.lang.InterruptedException
06-29 12:51:19.705 14280-14441/com.guillaimej.testapplication.app W/System.err﹕ at java.lang.VMThread.sleep(Native Method)
06-29 12:51:19.705 14280-14441/com.guillaimej.testapplication.app W/System.err﹕ at java.lang.Thread.sleep(Thread.java:1213)
06-29 12:51:19.710 14280-14441/com.guillaimej.testapplication.app W/System.err﹕ at java.lang.Thread.sleep(Thread.java:1195)
06-29 12:51:19.710 14280-14441/com.guillaimej.testapplication.app W/System.err﹕ at com.guillaimej.testapplication.app.CameraInputActivity$RecordBarTask.doInBackground(CameraInputActivity.java:188)
06-29 12:51:19.715 14280-14441/com.guillaimej.testapplication.app W/System.err﹕ at com.guillaimej.testapplication.app.CameraInputActivity$RecordBarTask.doInBackground(CameraInputActivity.java:175)
06-29 12:51:19.715 14280-14441/com.guillaimej.testapplication.app W/System.err﹕ at android.os.AsyncTask$2.call(AsyncTask.java:185)
06-29 12:51:19.715 14280-14441/com.guillaimej.testapplication.app W/System.err﹕ at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
06-29 12:51:19.715 14280-14441/com.guillaimej.testapplication.app W/System.err﹕ at java.util.concurrent.FutureTask.run(FutureTask.java:138)
06-29 12:51:19.720 14280-14441/com.guillaimej.testapplication.app W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
06-29 12:51:19.720 14280-14441/com.guillaimej.testapplication.app W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
06-29 12:51:19.720 14280-14441/com.guillaimej.testapplication.app W/System.err﹕ at java.lang.Thread.run(Thread.java:1019)