2012-08-12 32 views
5

Ho lavorato con SOLO VIDEO. Nessuna immagine. Notato, che setDisplayOrientation influisce sull'orientamento destro del display solo durante l'anteprima. Ma se per riprodurre qualsiasi video acquisito in modalità orizzontale o verticale è sempre in modalità orizzontale.Android API8 setDisplayOrientation non ha alcun effetto

ho impostato in AndroidManifest.xml

ma utilizzato per eseguire il debug in 4.0.1 dispositivo. Forse è un problema. Tuttavia ho notato che l'app fotocamera predefinita funziona bene e cattura i film in modalità ritratto.

Cosa mi manca? ...

** CameraRecorder.java

public class CameraRecorder extends Activity { 

private CameraPreview mPreview; 
private Camera mCamera; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.camera_surface); 

    // Create an instance of Camera 
    mCamera = getCameraInstance(); 
    if (mCamera == null) { 
     Log.e(TAG, "Camera is not available"); 
     finish(); 
    } 

    // Create our Preview view and set it as the content of our activity. 
    mPreview = new CameraPreview(this, mCamera); 
    FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview); 
    preview.addView(mPreview); 

    mPreview.setOnClickListener(startStopListener); 
} 
private void changeOrientation(int what) { 
    if (what != orientation) { 
     setRequestedOrientation(orientation = what); 
    } 
} 
OnClickListener startStopListener = new OnClickListener() { 

    @Override 
    public void onClick(View v) { 
     // TODO Auto-generated method stub 
     if (isRecording) { 
        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 
       isRecording = true; 
      } else { 
       // prepare didn't work, release the camera 
       releaseMediaRecorder(); 
      } 
     } 

    } 
}; 

File tempFile; 

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

/** A safe way to get an instance of the Camera object. */ 
public static Camera getCameraInstance() { 
    Camera c = null; 
     try { 
      c = Camera.open(); // attempt to get a Camera instance 

     } catch (Exception e) { 
      // Camera is not available (in use or does not exist) 

      Log.d(TAG, "Fail to connect to camera service. Is it locked?"); 
     } 
    } 
    return c; // returns null if camera is unavailable 
} 

private boolean prepareVideoRecorder() { 
    if (mCamera == null) 
     mCamera = getCameraInstance(); 
    if (mMediaRecorder == null) 
     mMediaRecorder = new MediaRecorder(); 

    Camera.Parameters p = mCamera.getParameters(); 

    // 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); 

    // Step 3: Set a CamcorderProfile (requires API Level 8 or higher) 
    CamcorderProfile profile = mPreview.getProfile();// CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH); 

    Size previewSize = mPreview.getPreviewSize(); 

    if (previewSize != null) { 
     profile.videoFrameWidth = previewSize.width; 
     profile.videoFrameHeight = previewSize.height; 
    } 
    mMediaRecorder.setProfile(profile); 

    // Step 4: Set output file 
    mMediaRecorder.setOutputFile(MediaFile.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; 
} 

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 (mPreview != null) { 
     mPreview.surfaceDestroyed(null); 
    } 
    if (mCamera != null) { 
     mCamera.release(); // release the camera for other applications 
     mCamera = null; 
     Log.d(TAG, "Camera released"); 
    } 
} 
} 

CameraPreview.java

/** A basic Camera preview class */ 
public class CameraPreview extends ViewGroup implements SurfaceHolder.Callback { 
private SurfaceHolder mHolder; 
private Camera mCamera; 
private SurfaceView mSurfaceView; 
private Context mContext; 

private final String TAG = "CameraPreview"; 

public CameraPreview(Context context, Camera camera) { 
    super(context); 
    mContext = context; 

    mCamera = camera; 

    setCamera(mCamera); 

    mSurfaceView = new SurfaceView(context); 
    addView(mSurfaceView, 0); 
    mHolder = mSurfaceView.getHolder(); 
    mHolder.addCallback(this); 
    mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
    mHolder.setKeepScreenOn(true); 

} 

public SurfaceHolder getHolder() { 
    return mSurfaceView.getHolder(); 
} 

private Size mPreviewSize; 
private List<Size> mSupportedPreviewSizes; 
private List<String> mSupportedFlashModes; 

public Camera getCamera() { 
    return mCamera; 
} 

private CamcorderProfile mProfile; 

public CamcorderProfile getProfile() { 
    return mProfile; 
} 

public void setCamera(Camera camera) { 
    mCamera = camera; 
    if (mCamera != null) { 
     mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes(); 
     mSupportedFlashModes = mCamera.getParameters().getSupportedFlashModes(); 

       mProfile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH); 

     // Set the camera to Auto Flash mode. 
     if (mSupportedFlashModes != null && mSupportedFlashModes.contains(Camera.Parameters.FLASH_MODE_AUTO)) { 
      Camera.Parameters parameters = mCamera.getParameters(); 
      parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO); 
      mCamera.setParameters(parameters); 
     } 
    } 
    requestLayout(); 
} 

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

@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec); 
    final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec); 

    if (mSupportedPreviewSizes != null) { 
     mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, mProfile.videoFrameWidth, mProfile.videoFrameHeight); 
    } 
    setMeasuredDimension(width, height); 
} 

@Override 
protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 
    if (changed) { 
     final View cameraView = getChildAt(0); 

     final int width = right - left; 
     final int height = bottom - top; 

     Camera.Parameters p = mCamera.getParameters(); 

     @SuppressWarnings("unused") 
     int previewWidth = width; 
     @SuppressWarnings("unused") 
     int previewHeight = height; 
     if (mPreviewSize != null) { 
      Display display = ((WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); 

      switch (display.getRotation()) { 
      case Surface.ROTATION_0: 
       mCamera.setDisplayOrientation(90); 
       break; 
      case Surface.ROTATION_90: 
      case Surface.ROTATION_180: 
       break; 
      case Surface.ROTATION_270: 
       mCamera.setDisplayOrientation(180); 
       break; 
      } 
     } 

     cameraView.layout(0, 0, width, height); 

    } 
} 

public void setSupportedPreviewSizes(List<Size> supportedPreviewSizes) { 
    mSupportedPreviewSizes = supportedPreviewSizes; 
} 

@Override 
public void surfaceDestroyed(SurfaceHolder holder) { 
    // Surface will be destroyed when we return, so stop the preview. 
    // Because the CameraDevice object is not a shared resource, it's very 
    // important to release it when the activity is paused. 
    try { 
     if (mCamera != null) { 
      mCamera.stopPreview(); 
      mCamera.setPreviewCallback(null); 
      // mCamera.release(); 
      mCamera = null; 

      Log.d(TAG, "Preview destroyed"); 
     } 
    } catch (Exception e) { 
     Log.e(TAG, "Camera release failure."); 
    } 

} 

@Override 
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 
    } 

    // set preview size and make any resize, rotate or 
    // reformatting changes here 

    Camera.Parameters parameters = mCamera.getParameters(); 
    Size previewSize = getPreviewSize(); 
    if (previewSize != null) 
     parameters.setPreviewSize(previewSize.width, previewSize.height); 

    mCamera.setParameters(parameters); 

    // start preview with new settings 
    try { 
     previewCamera(); 

    } catch (Exception e) { 
     Log.d(TAG, "Error starting camera preview: " + e.getMessage()); 
    } 
} 

public Size getPreviewSize() { 
    return mPreviewSize; 
} 

public static Size getOptimalPreviewSize(List<Size> sizes, int width, int height) { 
    double aspectTolerance = 0.05; 
    double targetRatio = (double) width/height; 
    if (sizes == null) { 
     return null; 
    } 
    Size optimalSize = null; 
    double minDiff = Double.MAX_VALUE; 
    int targetHeight = height; 
    // Try to find an size match aspect ratio and size 
    for (Size size : sizes) { 
     double ratio = (double) size.width/size.height; 
     if (Math.abs(ratio - targetRatio) > aspectTolerance) 
      continue; 
     if (Math.abs(size.height - targetHeight) < minDiff) { 
      optimalSize = size; 
      minDiff = Math.abs(size.height - targetHeight); 
     } 
    } 
    // Cannot find the one match the aspect ratio, ignore the requirement 
    if (optimalSize == null) { 
     minDiff = Double.MAX_VALUE; 
     for (Size size : sizes) { 
      if (Math.abs(size.height - targetHeight) < minDiff) { 
       optimalSize = size; 
       minDiff = Math.abs(size.height - targetHeight); 
      } 
     } 
    } 
    return optimalSize; 

} 

public void previewCamera() { 
    try { 
     mCamera.setPreviewDisplay(mHolder); 
     mCamera.startPreview(); 
    } catch (Exception e) { 
     Log.d(TAG, "Cannot start preview.", e); 
    } 
} 

} 

Manifest.xml

<uses-sdk android:minSdkVersion="8" /> 

<uses-permission android:name="android.permission.CAMERA" /> 
<uses-permission android:name="android.permission.RECORD_AUDIO" /> 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 

<uses-feature android:name="android.hardware.camera" /> 
<uses-feature android:name="android.hardware.camera.autofocus" /> 

<application 
    android:name=".client.andi" 
    android:icon="@drawable/ic_launcher" 
    android:label="@string/app_name" > 
    <activity 
     android:name=".activity.CameraRecorder" 
     android:label="@string/title_activity_main" 
     android:screenOrientation="landscape" 
     android:theme="@android:style/Theme.NoTitleBar.Fullscreen" > 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 

      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 
</application> 

** ** layout.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:id="@+id/RelativeLayout1" 
android:layout_width="fill_parent" 
android:layout_height="fill_parent" 
android:gravity="bottom" 
android:orientation="vertical" > 

<FrameLayout 
    android:id="@+id/camera_preview" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:layout_alignParentLeft="true" 
    android:layout_alignParentTop="true" > 
</FrameLayout> 

</RelativeLayout> 
+0

Mostra la tua 'AndroidManifest.xml'? Potrebbe essere necessario specificare l'orientamento nel layout o nel file manifest 'android: orientation =" vertical "' ... – t0mm13b

+0

Modificato. Manifest aggiunto. Hai bisogno di un layout? –

risposta

0

Non sono sicuro se si verifica esattamente lo stesso problema con la mia.

Anch'io ho bloccato questo problema. Ho scoperto che è possibile utilizzare la funzione setOrientationHint (API 9). Chiamare questa funzione prima di chiamare MediaRecorder.prepare(). È possibile impostare il grado di orientamento per il video in uscita.

Spero che ti aiuti, buona fortuna!

1

Si dovrebbe modificare Android: screenOrientation = "paesaggio" in Android: screenOrientation = "ritratto"

Problemi correlati