【问题标题】:screen goes to black after start video recording--android application开始录像后屏幕变黑--android应用程序
【发布时间】:2012-06-28 13:47:13
【问题描述】:

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

然后它就可以正常工作了。

【问题讨论】:

    标签: java android video video-recording


    【解决方案1】:

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

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

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

    recorder.setVideoSize(width, height);
    

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

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

        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,并希望上帝能修复它。如果没有,我可能不得不在某些设备上排除它。

    【讨论】:

    • 非常感谢您的回答!我注意到我将视频编码器设置为音频编码器。但是,在我将编码器更改为 h264 并将帧速率更改为 24 后,按下开始按钮后应用程序将崩溃。但是,如果我将编码器设置为 H263 并将帧速率设置为 1,那么在按下开始按钮后屏幕将冻结,并且没有其他任何事情发生。视频输出在目录中,但仍为 0 KB。我完全被这个弄糊涂了。任何帮助表示赞赏。
    • 在我们说话时,我实际上仍在测试这个过程中,但我想我找到了解决我们问题的特定行:“recorder.setVideoSize(getMaxSupportedVideoSize().width, getMaxSupportedVideoSize() 。高度);”是绝对必要的。我删除了 setVideoFrameRate (因为设备无论如何都会根据光线来控制它)和 setVideoEncodingBitRate (因为它也会被设备调整),现在它在我正在尝试的所有设备上都能正常工作。如果 setVideoSize 不存在,它会失败并给我们遇到的问题
    • 更新主帖,提供更多信息
    • 非常感谢!我添加了行 recorder.setVideoSize 并删除了 setVideoFrameRate 和 setVideoEncodingBitRate。现在按下开始按钮的响应时间比较长,应用程序没有崩溃!而且输出的视频现在终于不是0KB而是1KB了(虽然设备说因为某些原因不能播放)~(续)
    • 是的,我已经接受了答案。刚才在找怎么接受答案 :P 原来是点了答案旁边的勾号~
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多