2012-06-27 202 views
1

我嘗試構建一個自定義視頻錄製應用程序,並在互聯網上遵循教程。不過,我遇到按下啓動按鈕後屏幕變黑的問題,沒有其他事情發生。按下停止按鈕後,我檢查了放置輸出視頻的目錄。它在那裏,但大小是0 KB。開始視頻錄製後屏幕變黑 - android應用程序

我用了一個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.prepare()

然後它工作正常

其次mediaRecorder.setPreviewDisplay(surfaceView.getHolder().getSurface());應予以補充。

回答

0

我在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,並希望修復它的上帝。如果不是,我可能不得不在某些設備上排除它。

+0

非常感謝您的回答!我注意到我將視頻編碼器設置爲音頻編碼器。但是,在我將編碼器更改爲h264並將幀速率更改爲24之後,按下啓動按鈕後,應用程序將崩潰。但是,如果我將編碼器設置爲H263並且幀速率爲1,則在按下開始按鈕後屏幕將凍結,而沒有其他事情發生。視頻輸出位於目錄中,但仍爲0 KB。我完全被這個困惑了。任何幫助表示讚賞。 – Iam619

+0

我在字面上仍然在測試這個過程,因爲我們說話,但我想我找到了修復我們的問題的具體行:「recorder.setVideoSize(getMaxSupportedVideoSize()。width,getMaxSupportedVideoSize()。height);」是絕對必要的。我刪除了setVideoFrameRate(因爲設備基於光來控制它)和setVideoEncodingBitRate(因爲它也被設備調整),現在它在我嘗試使用的所有設備上正常工作。如果setVideoSize不存在,它會失敗,並給我們遇到的問題 – Guardanis

+0

更新後的主要帖子更多信息 – Guardanis