Question

I try to build a custom video recording app and followed a tutorial on the internet. However I get the problem that the screen goes to black after pressing the start button and nothing else happened. After pressing stop button, I checked the directory where I put the output video. It is there but the size is 0 KB.

I used a surfaceview and here is the xml layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:orientation="vertical"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   >
<TextView 
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:text="@string/hello"
   />
<Button
 android:id="@+id/start" 
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:text="- Start Camera Preview -"
   />
<Button
 android:id="@+id/stop" 
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:text="- Stop Camera Preview -"
   />
<SurfaceView
 android:id="@+id/surfaceview" 
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   />
</LinearLayout>

And here is brief code for recording video:

public class CamTestActivity extends Activity implements SurfaceHolder.Callback{
    private static final String TAG = "Camera-Tutorial";

    private SurfaceView surfaceView;
    private SurfaceHolder surfaceHolder;
    private Camera camera;
    private boolean previewRunning;
    private int VIDEO_TYPE = 3;
    private int intVideoIndex = 1;

    private MediaRecorder mediaRecorder;
    private final int maxDurationInMs = 20000;
    private final int videoFramesPerSecond = 20;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);

        setContentView(R.layout.videopreview);

       // setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

        surfaceView = (SurfaceView) findViewById(R.id.surfaceview);
        surfaceHolder = surfaceView.getHolder();
        surfaceHolder.addCallback(this);      
        Button start_video = (Button) findViewById(R.id.start);
        Button stop_video = (Button) findViewById(R.id.stop);


        stop_video.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                mediaRecorder.stop();
                camera.lock();
            }
        });

        start_video.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {

                try {
                    camera.unlock();                   
                    mediaRecorder = new MediaRecorder();
                    mediaRecorder.setCamera(camera);               
                    mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
                    mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

                    mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
                                                mediaRecorder.setOutputFile(GetOutputMediaFileDir(VIDEO_TYPE,intVideoIndex));
                   mediaRecorder.setVideoFrameRate(1);
                   mediaRecorder.setVideoEncoder(MediaRecorder.AudioEncoder.AAC);
                   mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);

                   mediaRecorder.prepare();
                    mediaRecorder.start();
                } catch (IllegalStateException e) {
                    Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show();
                  //  Log.e(TAG,e.getMessage());
                 //   e.printStackTrace();

                } catch (IOException e) {
                    Log.e(TAG,e.getMessage());
                  //  e.printStackTrace();
                }
            }
        });
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        camera = Camera.open();
        if (camera != null){
            Camera.Parameters params = camera.getParameters();
            camera.setParameters(params);
        }
        else {
            Toast.makeText(getApplicationContext(), "Camera not available!", Toast.LENGTH_LONG).show();
            finish();
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        if (previewRunning){
            camera.stopPreview();
        }
        Camera.Parameters p = camera.getParameters();
        p.setPreviewSize(width, height);
        camera.setParameters(p);

        try {
            camera.setPreviewDisplay(holder);
            camera.startPreview();
            previewRunning = true;
        }
        catch (IOException e) {
            Log.e(TAG,e.getMessage());
            e.printStackTrace();
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        camera.stopPreview();
        previewRunning = false;
        camera.release();
    }
 public static String GetOutputMediaFileDir(int fileType, int index){

        String fileDir=null;

          String strIndex = Integer.toString(index);
          if(fileType == 1)
          {
        File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
                Environment.DIRECTORY_MUSIC), "Audio");

        if (! mediaStorageDir.exists()){
            if (! mediaStorageDir.mkdirs()){

                return null;
            }
        }

          fileDir = mediaStorageDir.getPath() + File.separator +
                  "AUDIO_"+ strIndex + ".mp4";
          }
          if(fileType == 2)
          {
              File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
                        Environment.DIRECTORY_PICTURES), "Image");

                if (! mediaStorageDir.exists()){
                    if (! mediaStorageDir.mkdirs()){

                        return null;
                    }
                }

                  fileDir = mediaStorageDir.getPath() + File.separator +
                          "IMAGE_"+ strIndex + ".jpeg"; 
          }

          if(fileType == 3)
          {
              File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
                        Environment.DIRECTORY_MOVIES), "Video");

                if (! mediaStorageDir.exists()){
                    if (! mediaStorageDir.mkdirs()){

                        return null;
                    }
                }

                  fileDir = mediaStorageDir.getPath() + File.separator +
                          "VIDEO_"+ strIndex + ".mp4"; 
          }


       return fileDir;

        }

}

Any ideas of how to solve the problem? Thanks a lot in advance.

Changes that solve the problem:

Firstly I set the video encoder to an audio encoder, this should be changed;

Secondly mediaRecorder.setPreviewDisplay(surfaceView.getHolder().getSurface()); should be added beforemediaRecorder.prepare()

Then it works properly.

Was it helpful?

Solution

I experienced this issue on an HTC Incredible device, yet it worked perfectly on the 8 others I tested it on. Here is the post the 'solved' that issue:

https://stackoverflow.com/a/9903357/1426565

I narrowed the actual fix down to a specific line:

recorder.setVideoSize(width, height);

The framerate/bitrate settings were irrelevant in the fix, and I'm unsure if using the DEFAULTs for sources, output format, and encoders will change anything, but if you think about it, it shouldn't affect it at all.

These are the other settings I'm using with it (make sure size is set before any Encoder):

    recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
    recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);

    recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
    recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);

    recorder.setPReviewDisplay(surfaceView.getHolder().getSurface())

Also note, in testing yesterday on ICS we encountered an issue where setFrameRate was not supported, as well as setVideoSize was not supported. So, in the fix I'm about to attempt, I'm just going to surround the setVideoSize with a try/catch block, remove setFrameRate, and hope to God that fixes it. If not, I'll probably have to have to just exclude it on certain devices.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top