1

我尝试构建一个自定义视频录制应用程序并按照互联网上的教程进行操作。但是我得到的问题是按下开始按钮后屏幕变黑并且没有其他任何事情发生。按下停止按钮后,我检查了放置输出视频的目录。它在那里,但大小为 0 KB。

我使用了surfaceview,这是xml布局:

<?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>

这是录制视频的简短代码:

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;

        }

}

关于如何解决问题的任何想法?提前非常感谢。

解决问题的更改:

首先我将视频编码器设置为音频编码器,这应该改变;

其次mediaRecorder.setPreviewDisplay(surfaceView.getHolder().getSurface());应该在之前添加mediaRecorder.prepare()

然后它可以正常工作。

4

1 回答 1

0

我在 HTC Incredible 设备上遇到了这个问题,但它在我测试过的其他 8 台设备上运行良好。这是“解决”该问题的帖子:

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

我将实际修复范围缩小到特定行:

recorder.setVideoSize(width, height);

帧率/比特率设置在修复中无关紧要,我不确定是否将默认值用于源、输出格式和编码器会改变任何东西,但如果你考虑一下,它根本不会影响它。

这些是我正在使用的其他设置(确保在任何编码器之前设置大小):

    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())

另请注意,昨天在 ICS 上进行测试时,我们遇到了不支持 setFrameRate 以及不支持 setVideoSize 的问题。因此,在我将要尝试的修复中,我将用 try/catch 块包围 setVideoSize,删除 setFrameRate,并希望上帝能修复它。如果没有,我可能不得不在某些设备上排除它。

于 2012-06-27T15:35:29.630 回答