2011-11-29 5 views
4

안녕하세요! MediaRecorder로 비디오를 레코딩하는 방법을 배우고 있지만, 비디오를 재생하면 비디오가 손상됩니다. 이 스크린 샷을 참조하십시오 : http://www.4shared.com/photo/QtmJCHRi/corrupted-video.html. 왼쪽 상단 모서리에 빨간색 사각형으로 표시된 그림이 카메라가 볼 수있는 것입니다. 그러나 그것은 너무 작습니다. 반복되고 있으며 많은 녹지가 있습니다. 내가 뭘 잘못하고 있는지 조언 해주세요. HW는 삼성 Galaxy S2 (GT-I9100, Android 2.3.5)입니다. 이 자습서를 따라했습니다. http://developer.android.com/guide/topics/media/camera.html#saving-media삼성 Galaxy S2에서 Android MediaRecorder로 녹화 한 비디오가 손상되었습니다

감사합니다.

CameraRecorderActivity.java

package cz.ryvo.android.camerarecorder; 

import java.io.File; 
import java.io.IOException; 
import java.text.SimpleDateFormat; 
import java.util.Date; 
import android.app.Activity; 
import android.content.Context; 
import android.content.pm.PackageManager; 
import android.hardware.Camera; 
import android.hardware.Camera.CameraInfo; 
import android.media.CamcorderProfile; 
import android.media.MediaRecorder; 
import android.os.Bundle; 
import android.os.Environment; 
import android.util.Log; 
import android.view.SurfaceHolder; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 
import android.widget.FrameLayout; 

public class CameraRecorderActivity extends Activity 
implements SurfaceHolder.Callback, OnClickListener { 

private static final String TAG = "CameraRecorderActivity"; 

public static final int MEDIA_TYPE_IMAGE = 1; 
public static final int MEDIA_TYPE_VIDEO = 2; 

private Camera mCamera; 
private CameraPreview mPreview; 
private MediaRecorder mMediaRecorder; 
private Button captureButton; 
private boolean isRecording = false; 

/** Called when the activity is first created. */ 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 
    // Create an instance of Camera. 
    mCamera = getCameraInstance(); 
    // Create preview view and set it as the content of our activity. 
    mPreview = new CameraPreview(this, mCamera); 
    int i = R.id.camera_preview; 
    Object o = this.findViewById(i); 
    FrameLayout preview = (FrameLayout) o; 
    preview.addView(mPreview); 

// Add a listener to the Capture button 
    captureButton = (Button) findViewById(R.id.button_capture); 
    captureButton.setOnClickListener(
     new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       if (isRecording) { 
        // stop recording and release camera 
        mMediaRecorder.stop(); // stop the recording 
        releaseMediaRecorder(); // release the MediaRecorder object 
        mCamera.lock();   // take camera access back from MediaRecorder 

        // inform the user that recording has stopped 
        setCaptureButtonText("Capture"); 
        isRecording = false; 
       } else { 
        // initialize video camera 
        if (prepareVideoRecorder()) { 
         // Camera is available and unlocked, MediaRecorder is prepared, 
         // now you can start recording 
         mMediaRecorder.start(); 

         // inform the user that recording has started 
         setCaptureButtonText("Stop"); 
         isRecording = true; 
        } else { 
         // prepare didn't work, release the camera 
         releaseMediaRecorder(); 
         // inform user 
        } 
       } 
      } 
     } 
    ); 
} 

public void setCaptureButtonText(String s) { 
    captureButton.setText(s); 
} 

@Override 
public void surfaceCreated(SurfaceHolder holder) { 
    // The Surface has been created, now tell the camera where to draw the preview. 
    try { 
     mCamera.setPreviewDisplay(holder); 
     mCamera.startPreview(); 
    } catch (IOException e) { 
     Log.d(TAG, "Error setting camera preview: " + e.getMessage()); 
    } 
} 

@Override 
public void surfaceChanged(SurfaceHolder holder, int format, int width, 
     int height) { 
    // TODO Auto-generated method stub 
} 

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

/** Create a File for saving an image or video */ 
private static File getOutputMediaFile(int type){ 
    // To be safe, you should check that the SDCard is mounted 
    // using Environment.getExternalStorageState() before doing this. 
    File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
       Environment.DIRECTORY_PICTURES), "MyCameraApp"); 
    // This location works best if you want the created images to be shared 
    // between applications and persist after your app has been uninstalled. 
    // Create the storage directory if it does not exist 
    if (! mediaStorageDir.exists()){ 
     if (! mediaStorageDir.mkdirs()){ 
      Log.d("MyCameraApp", "failed to create directory"); 
      return null; 
     } 
    } 
    // Create a media file name 
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); 
    File mediaFile; 
    if (type == MEDIA_TYPE_IMAGE){ 
     mediaFile = new File(mediaStorageDir.getPath() + File.separator + 
     "IMG_"+ timeStamp + ".jpg"); 
    } else if(type == MEDIA_TYPE_VIDEO) { 
     mediaFile = new File(mediaStorageDir.getPath() + File.separator + 
     "VID_"+ timeStamp + ".mp4"); 
    } else { 
     return null; 
    } 
    return mediaFile; 
} 

private boolean prepareVideoRecorder(){ 
    //mCamera = getCameraInstance(); 
    mMediaRecorder = new MediaRecorder(); 
    // Step 1: Unlock and set camera to MediaRecorder 
    mCamera.unlock(); 
    mMediaRecorder.setCamera(mCamera); 
    // Step 2: Set sources 
    mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER); 
    mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); 
    mMediaRecorder.setVideoSize(720, 480); 
    // Step 3: Set a CamcorderProfile (requires API Level 8 or higher) 
    mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH)); 
    // Step 4: Set output file 
    mMediaRecorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).toString()); 
    // Step 5: Set the preview output 
    mMediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface()); 
    // Step 6: Prepare configured MediaRecorder 
    try { 
     mMediaRecorder.prepare(); 
    } catch (IllegalStateException e) { 
     Log.d(TAG, "IllegalStateException preparing MediaRecorder: " + e.getMessage()); 
     releaseMediaRecorder(); 
     return false; 
    } catch (IOException e) { 
     Log.d(TAG, "IOException preparing MediaRecorder: " + e.getMessage()); 
     releaseMediaRecorder(); 
     return false; 
    } 
    return true; 
} 


@Override 
public void onClick(View v) { 
    /* 
    Log.i("onClick", "BEGIN"); 
    if(!recording) { 
     recording = startRecording(); 
    } else { 
     stopRecording(); 
     recording = false; 
    } 
    Log.i("onClick", "END"); 
    */ 
} 

@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 (mMediaRecorder != null) { 
     mMediaRecorder.reset(); // clear recorder configuration 
     mMediaRecorder.release(); // release the recorder object 
     mMediaRecorder = null; 
     mCamera.lock();   // lock camera for later use 
    } 
} 

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

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

    public Camera open() { 
     int numberOfCameras = Camera.getNumberOfCameras(); 
     CameraInfo cameraInfo = new CameraInfo(); 
     for (int i = 0; i < numberOfCameras; i++) { 
      Camera.getCameraInfo(i, cameraInfo); 
      if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) { 
       return Camera.open(i); 
      } 
     } 
     return null; 
    }  
} 

CameraPreview.java

package cz.ryvo.android.camerarecorder; 

import java.io.IOException; 
import android.content.Context; 
import android.hardware.Camera; 
import android.util.Log; 
import android.view.SurfaceHolder; 
import android.view.SurfaceView; 

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback { 

private static final String TAG = "CameraPreview"; 

private SurfaceHolder mHolder; 
private Camera mCamera; 

public CameraPreview(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); 
} 

public void surfaceCreated(SurfaceHolder holder) { 
    // The Surface has been created, now tell the camera where to draw the preview. 
    try { 
     mCamera.setPreviewDisplay(holder); 
     mCamera.startPreview(); 
    } catch (IOException e) { 
     Log.d(TAG, "Error setting camera preview: " + e.getMessage()); 
    } 
} 

public void surfaceDestroyed(SurfaceHolder holder) { 
    // empty. Take care of releasing the Camera preview in your activity. 
} 

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 
    // 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){ 
     Log.d(TAG, "Error starting camera preview: " + e.getMessage()); 
    } 
    } 
} 
+0

와 문제를 발견했다. 내 대답을 확인하십시오. http://stackoverflow.com/questions/7225571/camcorderprofile-quality-high-resolution-produces-green-flickering-video/10995975#10995975 – Tvaroh

답변

5

내가 어딘가에 읽어은 (나는 SO에 생각). 문제는 분명히 삼성 갤럭시가 고화질 (CamcorderProfile.QUALITY_HIGH)로 녹화하는 것을 지원하지 않는다는 것입니다.

CamcorderProfile.QUALITY_LOW로 시도해보십시오. 그것이 효과가 있는지보기 위해서.

편집 : 나는 같은 문제는 HD 해상도로 녹화 할 수있는 사실 here

+2

SeRPRo에게 조언 해 주셔서 감사합니다. 나는 QUALITY_LOW로 시도했다. 불행하게도 최대 해상도 720x480만으로 작동합니다. 삼성의 카메라 앱은 1920x1080 해상도로 비디오를 녹화 할 수있다. 특별한 클래스 인 SecCamera와 SecMediaRecorder (/ system/android에 위치)가 캡처에 사용되어야한다는 [이 스레드] (http://forum.xda-developers.com/showthread.php?t=1104970)의 빨간색입니다. 비디오를 제공하며, Camera 및 MediaRecorder가 제공하지 않는 표준 클래스와 다른 특수 기능을 제공합니다. 성공하도록 만들면 여기서 코드를 게시 할 것입니다. – Vojtech

+0

@ user1071282 도움이 되었기 때문에 기쁩니다. 코드가 곧 작동되기를 바랍니다. – SERPRO

+0

이 행운이 있었습니까 –

관련 문제