2013-11-25 100 views
0

嗨我正在開發類似於此鏈接的Android視頻應用程序 http://android-er.blogspot.in/2011/10/video-capture-using-mediarecorder-with.html 其中視頻應用程序以幀佈局顯示。表面視圖顯示黑屏用於視頻預覽

我正在嘗試上面的一個表面視圖和我的xml看起來像下面。

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="fill_parent" 
android:layout_height="fill_parent" 
android:textSize="20sp" > 

<SurfaceView 
    android:id="@+id/CameraView" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:focusable="true" /> 

<ImageView 
    android:id="@+id/mybutton" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_alignParentRight="true" 
    android:layout_alignParentTop="true" 
    android:paddingLeft="2dp" 
    android:paddingRight="2dp" 
    android:src="@drawable/record_video" /> 

</RelativeLayout> 

我不知道爲什麼它顯示黑屏而不是相機視圖。我的ViewActivity.java如下。

public class ViewActivity extends Activity implements OnClickListener, SurfaceHolder.Callback 
{ 
MediaRecorder recorder; 
SurfaceHolder holder; 
boolean recording=false; 
private MediaRecorder mediaRecorder; 
private File file; 
private ImageView recVideo; 
private SurfaceView cameraView; 
private Camera camera; 

@Override 
public void onCreate(Bundle savedInstanceState) 
{ 
    super.onCreate(savedInstanceState); 
    requestWindowFeature(Window.FEATURE_NO_TITLE); 

    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); 

    recorder = new MediaRecorder(); 
    initRecorder(); 

    setContentView(R.layout.view); 

    recVideo = (ImageView)findViewById(R.id.mybutton); 
    cameraView = (SurfaceView) findViewById(R.id.CameraView); 

    holder = cameraView.getHolder(); 
    holder.addCallback(ViewActivity.this); 
    holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 

    recVideo.setClickable(true); 
    recVideo.setOnClickListener(this); 
} 

private void initRecorder() 
{ 
    recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT); 
    recorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT); 
    recorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH)); 
    recorder.setOutputFile(this.initFile().getAbsolutePath()); 
    recorder.setMaxDuration(60000); // Set max duration 60 sec. 
    recorder.setMaxFileSize(5000000); // Set max file size 5M 

} 

private void prepareRecorder() 
{ 
    recorder.setPreviewDisplay(holder.getSurface()); 

    try 
    { 
     recorder.prepare(); 
    } catch (IllegalStateException e) 
    { 
     e.printStackTrace(); 
     finish(); 
    } 
    catch (IOException e) 
    { 
     e.printStackTrace(); 
     finish(); 
    } 
} 

public void onClick(View v) 
{ 
    if (recording) 
    { 
     recorder.stop(); 
     recording = false; 

     initRecorder(); 
     prepareRecorder(); 
     Toast.makeText(ViewActivity.this,"Video Saved!",Toast.LENGTH_SHORT).show(); 
     startActivity(new Intent(ViewActivity.this,ViewActivity.class)); 
     finish(); 

    } 
    else 
    { 
     recorder.start(); 
     recording = true; 
     recVideo.setImageDrawable(getResources().getDrawable(R.drawable.stop_recording)); 
    } 
} 

public void surfaceCreated(SurfaceHolder holder) 
{ 
    prepareRecorder(); 

} 

public void surfaceChanged(SurfaceHolder holder, int format, int width, 
     int height) 
{ 
} 

public void surfaceDestroyed(SurfaceHolder holder) 
{ 
    if (recording) { 
     recorder.stop(); 
     recording = false; 
    } 
    recorder.release(); 
    finish(); 
} 

我不知道我哪裏出錯了。如何使表面視圖顯示相機視圖而不是黑屏。

請幫忙。

謝謝!

+0

我不知道到底,但你可以嘗試recorder.setPreviewDisplay(holder.getSurface());在此之後recorder.prepare(); –

+0

試過!沒有變化。仍然顯示黑屏 – sanjana

回答

1

這樣來做:

public class AndroidVideoCapture extends Activity { 

    private Camera myCamera; 
    private MyCameraSurfaceView myCameraSurfaceView; 
    private MediaRecorder mediaRecorder; 

    Button myButton; 
    RadioButton flashOff, flashTorch; 
    SurfaceHolder surfaceHolder; 
    boolean recording; 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     recording = false; 

     setContentView(R.layout.main); 

     // Get Camera for preview 
     myCamera = getCameraInstance(); 
     if (myCamera == null) { 
      Toast.makeText(AndroidVideoCapture.this, "Fail to get Camera",Toast.LENGTH_LONG).show(); 
     } 

     myCameraSurfaceView = new MyCameraSurfaceView(this, myCamera); 
     FrameLayout myCameraPreview = (FrameLayout) findViewById(R.id.videoview); 
     myCameraPreview.addView(myCameraSurfaceView); 

     myButton = (Button) findViewById(R.id.mybutton); 
     myButton.setOnClickListener(myButtonOnClickListener); 

     flashOff = (RadioButton) findViewById(R.id.flashoff); 
     flashTorch = (RadioButton) findViewById(R.id.flashtorch); 
    } 

    Button.OnTouchListener flashButtonOnTouchListener = new Button.OnTouchListener() { 

     @Override 
     public boolean onTouch(View arg0, MotionEvent arg1) { 
      // TODO Auto-generated method stub 

      if (myCamera != null) { 
       Parameters parameters = myCamera.getParameters(); 

       switch (arg1.getAction()) { 
       case MotionEvent.ACTION_DOWN: 
        parameters.setFlashMode(Parameters.FLASH_MODE_TORCH); 
        myCamera.setParameters(parameters); 
        break; 
       case MotionEvent.ACTION_UP: 
        parameters.setFlashMode(Parameters.FLASH_MODE_OFF); 
        myCamera.setParameters(parameters); 
        break; 
       } 
       ; 
      } 

      return true; 
     } 
    }; 

    Button.OnClickListener flashModeButtonOnClickListener = new Button.OnClickListener() { 

     @Override 
     public void onClick(View v) { 
      // TODO Auto-generated method stub 

     } 
    }; 

    Button.OnClickListener myButtonOnClickListener = new Button.OnClickListener() { 

     @Override 
     public void onClick(View v) { 
      // TODO Auto-generated method stub 
      if (recording) { 
       // stop recording and release camera 
       mediaRecorder.stop(); // stop the recording 
       releaseMediaRecorder(); // release the MediaRecorder object 

       myCamera.lock(); 
       // take camera access back from 
       recording = false; 
       // MediaRecorder 
       // inform the user that recording has stopped 
       // Exit after saved 
       //finish(); 
      } else { 

       // Release Camera before MediaRecorder start 
       releaseCamera(); 

       if (!prepareMediaRecorder()) { 
        Toast.makeText(AndroidVideoCapture.this, 
          "Fail in prepareMediaRecorder()!\n - Ended -", 
          Toast.LENGTH_LONG).show(); 
        finish(); 
       } 

       mediaRecorder.start(); 
       recording = true; 
       myButton.setText("STOP"); 
      } 
     } 
    }; 

    private Camera getCameraInstance() { 
     // TODO Auto-generated method stub 
     Camera c = null; 
     try { 
      c = Camera.open(); // attempt to get a Camera instance 
      c.setDisplayOrientation(90); 
     } catch (Exception e) { 
      // Camera is not available (in use or does not exist) 
     } 
     return c; // returns null if camera is unavailable 
    } 

    private String getFlashModeSetting() { 
     if (flashTorch.isChecked()) { 
      return Parameters.FLASH_MODE_TORCH; 
     } else { 
      return Parameters.FLASH_MODE_OFF; 
     } 
    } 

    private boolean prepareMediaRecorder() { 
     myCamera = getCameraInstance(); 

     Parameters parameters = myCamera.getParameters(); 
     parameters.setFlashMode(getFlashModeSetting()); 
     myCamera.setParameters(parameters); 

     mediaRecorder = new MediaRecorder(); 

     myCamera.unlock(); 
     mediaRecorder.setCamera(myCamera); 

     mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER); 
     mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); 

     mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH)); 

     mediaRecorder.setOutputFile(getOutputMediaFile("movie")); 
     mediaRecorder.setMaxDuration(6000000); // Set max duration 60 sec. 
     mediaRecorder.setMaxFileSize(50000000); // Set max file size 5M 

     mediaRecorder.setPreviewDisplay(myCameraSurfaceView.getHolder().getSurface()); 

     mediaRecorder.setOrientationHint(90); 

     try { 
      mediaRecorder.prepare(); 
     } catch (IllegalStateException e) { 
      releaseMediaRecorder(); 
      return false; 
     } catch (IOException e) { 
      releaseMediaRecorder(); 
      return false; 
     } 
     return true; 

    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 
     releaseMediaRecorder(); // if you are using MediaRecorder, release it 
           // first 
     releaseCamera(); // release the camera immediately on pause event 
    } 

    private void releaseMediaRecorder() { 
     if (mediaRecorder != null) { 
      mediaRecorder.reset(); // clear recorder configuration 
      mediaRecorder.release(); // release the recorder object 
      mediaRecorder = null; 
      myCamera.lock(); // lock camera for later use 
     } 
    } 

    private void releaseCamera() { 
     if (myCamera != null) { 
      myCamera.release(); 
      // release the camera for other applications 
      myCamera = null; 
     } 
    } 

    public class MyCameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback { 

     private SurfaceHolder mHolder; 
     private Camera mCamera; 

     public MyCameraSurfaceView(Context context, Camera camera) { 
      super(context); 
      mCamera = camera; 

      // Install a SurfaceHolder.Callback so we get notified when the 
      // underlying surface is created and destroyed. 
      mHolder = getHolder(); 
      mHolder.addCallback(this); 
      // deprecated setting, but required on Android versions prior to 3.0 
      mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
     } 

     @Override 
     public void surfaceChanged(SurfaceHolder holder, int format,int weight, int height) { 
      // 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) { 
       // ignore: tried to stop a non-existent preview 
      } 

      // make any resize, rotate or reformatting changes here 

      // start preview with new settings 
      try { 
       mCamera.setPreviewDisplay(mHolder); 
       mCamera.startPreview(); 

      } catch (Exception e) { 
      } 
     } 

     @Override 
     public void surfaceCreated(SurfaceHolder holder) { 
      // TODO Auto-generated method stub 
      // The Surface has been created, now tell the camera where to draw 
      // the preview. 
      try { 
       mCamera.setPreviewDisplay(holder); 
       mCamera.startPreview(); 
      } catch (IOException e) { 
      } 
     } 

     @Override 
     public void surfaceDestroyed(SurfaceHolder holder) { 
      // TODO Auto-generated method stub 

     } 
    } 

    private static String getOutputMediaFile(String sufix) { 

     String mediaFile; 
     File mediaStorageDir = new File(Environment.getExternalStorageDirectory(), "/YappBack"); 
     if (!mediaStorageDir.exists()) { 
      if (!mediaStorageDir.mkdirs()) { 
       Log.d("VideoLogger", "failed to create directory"); 
       return null; 
      } 
     } 
     String timeStamp = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss").format(new Date()); 
     if (!sufix.equals("movie")) { 
      mediaFile = mediaStorageDir.getPath() + File.separator + "output_"+ timeStamp + "_" + sufix + ".txt"; 
     } else { 
      mediaFile = mediaStorageDir.getPath() + File.separator + "output_"+ timeStamp + ".mp4"; 

     } 
     //mediaFile = Environment.getExternalStorageDirectory().getPath()+ "/default.mp4"; 
     return mediaFile; 
    } 
} 

XML文件:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:orientation="vertical" > 

    <LinearLayout 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" 
     android:orientation="vertical" > 

     <FrameLayout 
      android:id="@+id/videoview" 
      android:layout_width="match_parent" 
      android:layout_height="600px" /> 

     <LinearLayout 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      android:orientation="vertical" > 

      <Button 
       android:id="@+id/mybutton" 
       android:layout_width="fill_parent" 
       android:layout_height="wrap_content" 
       android:text="REC" 
       android:textSize="12dp" /> 

      <RadioGroup 
       android:layout_width="fill_parent" 
       android:layout_height="wrap_content" 
       android:orientation="vertical" > 

       <RadioButton 
        android:id="@+id/flashoff" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:checked="true" 
        android:text="OFF" 
        android:textSize="8dp" /> 

       <RadioButton 
        android:id="@+id/flashtorch" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:text="Torch" 
        android:textSize="8dp" /> 
      </RadioGroup> 
     </LinearLayout> 
    </LinearLayout> 

</LinearLayout> 
+0

請解釋一下? – deadfish

0

確保您已聲明在manifest文件CAMERA權限。

此外,請檢查您是否已授予設置的相機權限。

+0

這不提供問題的答案,應該是評論。請參閱[我應該何時評論?](https://stackoverflow.com/help/privileges/comment)。 一旦你有足夠的[聲望](https://stackoverflow.com/help/whats-reputation),你將可以在任何帖子上[評論](https://stackoverflow.com/help/privileges/comment);相反,[提供不需要提問者澄清的答案](https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-c​​an- I-DO-代替)。 – Dwhitz

0

確保您camera.setPreviewTexture(surfaceTexture);後調用mediaRecorder.setPreviewDisplay(new Surface(surfaceTexture));,然後訣竅是調用camera.stopPreview()之前mediaRecorder.start();