2014-05-23 5 views
6

내 앱에서 8 초 동안 비디오를 녹화해야합니다. 나는 MediaStore.ACTION_VIDEO_CAPTURE 비디오 레코딩의 의도와이 파라미터를 사용하여 (MediaStore.EXTRA_VIDEO_QUALITY, MediaStore.EXTRA_DURATION_LIMIT) 비디오 레코딩의 품질과 지속 시간 제한을 설정합니다. 하지만 매우 재미있는 버그를 만났습니다. 즉, 지속 시간 제한을 8 초로 설정하고 비디오 품질을 1로 설정하면 작업이 정상적으로 처리되고 8 초 동안 비디오가 레코딩되지만 곧 비디오 품질은 0으로 변경되고 모두 동일하게 유지됩니다. 이제 21 초 동안 기록됩니다. 내가 테스트를 위해 소니 엑스 페리아 전화를 사용하고,하지만 난 HTC으로 이동하는 경우, 기간 제한도 그래서 내가하지 않는 한 비디오 품질 설정에도 0내구성 및 품질이 낮은 안드로이드 비디오 녹화

로 설정에 어떤 경우에 작동하지 않습니다 지금 무슨 일이 일어나고 있는지 알아라. 심한 욕구가 있음. 도와주세요. 미리 감사드립니다. 여기

내가 사용하고있는 코드 .. 난이 질문에 대답하기는 조금 늦게 알고

private void recordVideo() { 
    Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE); 

    File f = null; 

    try { 
     f = setUpVideoFile(); 
     filePath = f.getAbsolutePath(); 
     intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f)); 
    } catch (IOException e) { 
     e.printStackTrace(); 
     f = null; 
     filePath = null; 
    } 
    objectGlobal.setFilepath(filePath); 
    intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); 
    intent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, 8); 
    startActivityForResult(intent, CAMERA_CAPTURE_VIDEO); 
} 
+0

비디오를 캡처하는 코드를 게시 할 수 있습니까? – Manu

+0

@Manu 코드를 추가했습니다. 그것을 확인하십시오 .. !! –

+0

코드가 잘된 것 같아요 ... 버그 같아 – Manu

답변

3

이지만, 나는 다른 사람들이이 문제에 직면하는 경우, 그들은 쉽게 처리 할 수 ​​할 수 있도록 생각 그것으로. 카메라의 의도가 더 이상 비디오 레코더로 작동이

intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0); 

을 통해 비디오 품질을 낮출 때

사실 문제입니다. 품질을 낮추려면 실제로 mms를 만듭니다. 시간에 관한 한, 나는 그것이 안드로이드의 버그인지 또는 메모리 제약이 될지 모른다. 그래서 제가 채택한 해결책은 SurfaceView를 사용하여 맞춤 비디오 녹화 클래스를 만드는 것입니다. 그래서 내 프로젝트 중 하나에서 비디오 레코딩 코드를 붙여 넣습니다. 또한 녹화 된 비디오는 모든 안드로이드/iOS 장치에서 거의 재생할 수 있습니다. 지금까지 테스트를 마쳤습니다.() 함수

당신의 onActivityResult를에서
private boolean isDeviceSupportCamera() { 
     if (getApplicationContext().getPackageManager().hasSystemFeature(
       PackageManager.FEATURE_CAMERA)) { 
      return true; 
     } else { 
      return false; 
     } 
    } 

isDeviceSupportCamera 여기 내 비디오 녹화 클래스

package com.mukesh.videorecordingsample; 

import android.app.Activity; 
import android.app.AlertDialog; 
import android.content.DialogInterface; 
import android.content.Intent; 
import android.hardware.Camera; 
import android.hardware.Camera.Size; 
import android.media.CamcorderProfile; 
import android.media.MediaRecorder; 
import android.os.Build; 
import android.os.Bundle; 
import android.os.Environment; 
import android.os.Handler; 
import android.os.Message; 
import android.util.Log; 
import android.view.KeyEvent; 
import android.view.Surface; 
import android.view.SurfaceHolder; 
import android.view.SurfaceView; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.view.Window; 
import android.widget.ImageView; 
import android.widget.TextView; 
import android.widget.Toast; 


import java.io.File; 
import java.io.IOException; 
import java.util.ArrayList; 
import java.util.Collections; 
import java.util.Comparator; 
import java.util.List; 

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

    protected static final int RESULT_ERROR = 0x00000001; 

    private static final int MAX_VIDEO_DURATION = 8 * 1000; 
    private static final int ID_TIME_COUNT = 0x1006; 

    private SurfaceView mSurfaceView; 
    private ImageView iv_cancel, iv_ok, iv_record; 
    private TextView tv_counter; 

    private SurfaceHolder mSurfaceHolder; 
    private MediaRecorder mMediaRecorder; 
    private Camera mCamera; 

    private List<Size> mSupportVideoSizes; 

    private String filePath; 

    private boolean mIsRecording = false; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     this.requestWindowFeature(Window.FEATURE_NO_TITLE); 
     setContentView(R.layout.activity_recordvideo); 

     initView(); 
    } 

    private void initView() { 

     mSurfaceView = (SurfaceView) findViewById(R.id.surfaceView); 

     iv_record = (ImageView) findViewById(R.id.iv_record); 
     iv_cancel = (ImageView) findViewById(R.id.iv_cancel); 
     iv_ok = (ImageView) findViewById(R.id.iv_ok); 
     iv_record.setImageResource(R.drawable.btn_video_start); 

     tv_counter = (TextView) findViewById(R.id.timer); 
     tv_counter.setVisibility(View.GONE); 

     iv_cancel.setOnClickListener(this); 
     iv_ok.setOnClickListener(this); 
     iv_record.setOnClickListener(this); 

     mSurfaceHolder = mSurfaceView.getHolder(); 
     mSurfaceHolder.addCallback(this); 

    } 

    private void exit(final int resultCode, final Intent data) { 
     if (mIsRecording) { 
      new AlertDialog.Builder(RecordVideoPostsActivity.this) 
        .setTitle("Video Recorder") 
        .setMessage("Do you want to exit?") 
        .setPositiveButton("yes", 
          new DialogInterface.OnClickListener() { 

           @Override 
           public void onClick(DialogInterface dialog, 
                int which) { 
            stopRecord(); 
            if (resultCode == RESULT_CANCELED) { 
             if (filePath != null) 
              deleteFile(new File(filePath)); 
            } 
            setResult(resultCode, data); 
            finish(); 
           } 
          }) 
        .setNegativeButton("no", 
          new DialogInterface.OnClickListener() { 

           @Override 
           public void onClick(DialogInterface dialog, 
                int which) { 

           } 
          }).show(); 
      return; 
     } 
     if (resultCode == RESULT_CANCELED) { 
      if (filePath != null) 
       deleteFile(new File(filePath)); 
     } 
     setResult(resultCode, data); 
     finish(); 
    } 

    private void deleteFile(File delFile) { 
     if (delFile == null) { 
      return; 
     } 
     final File file = new File(delFile.getAbsolutePath()); 
     delFile = null; 
     new Thread() { 
      @Override 
      public void run() { 
       super.run(); 
       if (file.exists()) { 
        file.delete(); 
       } 
      } 
     }.start(); 
    } 

    private Handler mHandler = new Handler() { 

     @Override 
     public void handleMessage(android.os.Message msg) { 
      switch (msg.what) { 
       case ID_TIME_COUNT: 
        if (mIsRecording) { 
         if (msg.arg1 > msg.arg2) { 
          // mTvTimeCount.setVisibility(View.INVISIBLE); 
          tv_counter.setText("00:00"); 
          stopRecord(); 
         } else { 
          tv_counter.setText("00:0" + (msg.arg2 - msg.arg1)); 
          Message msg2 = mHandler.obtainMessage(ID_TIME_COUNT, 
            msg.arg1 + 1, msg.arg2); 
          mHandler.sendMessageDelayed(msg2, 1000); 
         } 
        } 
        break; 

       default: 
        break; 
      } 
     } 

     ; 

    }; 

    private void openCamera() { 
     try { 
      this.mCamera = Camera.open(); 
      Camera.Parameters parameters = mCamera.getParameters(); 
      parameters.setRotation(90); 
      System.out.println(parameters.flatten()); 
      parameters.set("orientation", "portrait"); 
      mCamera.setParameters(parameters); 
      mCamera.lock(); 
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) { 
       try { 
        mCamera.setDisplayOrientation(90); 
       } catch (NoSuchMethodError e) { 
        e.printStackTrace(); 
       } 
      } 
      mSupportVideoSizes = parameters.getSupportedVideoSizes(); 
      if (mSupportVideoSizes == null || mSupportVideoSizes.isEmpty()) { 
       String videoSize = parameters.get("video-size"); 
       Log.i(EmBazaarConstants.APP_NAME, videoSize); 
       mSupportVideoSizes = new ArrayList<Camera.Size>(); 
       if (!RecordVideoPostsActivity.isEmpty(videoSize)) { 
        String[] size = videoSize.split("x"); 
        if (size.length > 1) { 
         try { 
          int width = Integer.parseInt(size[0]); 
          int height = Integer.parseInt(size[1]); 
          mSupportVideoSizes.add(mCamera.new Size(width, 
            height)); 
         } catch (Exception e) { 
          Log.e(EmBazaarConstants.APP_NAME, e.toString()); 
         } 
        } 
       } 
      } 
      for (Size size : mSupportVideoSizes) { 
       Log.i(EmBazaarConstants.APP_NAME, size.width + "<>" + size.height); 
      } 
     } catch (Exception e) { 
      Log.e(EmBazaarConstants.APP_NAME, "Open Camera error\n" + e.toString()); 
     } 
    } 

    private boolean initVideoRecorder() { 
     if (mCamera == null) { 
      mCamera = Camera.open(); 
      mCamera.unlock(); 
     } else { 
      mCamera.unlock(); 
     } 
     mMediaRecorder = new MediaRecorder(); 

     mMediaRecorder.setCamera(mCamera); 

     try { 
      mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); 
      mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     try { 
      CamcorderProfile lowProfile = CamcorderProfile 
        .get(CamcorderProfile.QUALITY_LOW); 
      CamcorderProfile hightProfile = CamcorderProfile 
        .get(CamcorderProfile.QUALITY_HIGH); 
      if (lowProfile != null && hightProfile != null) { 
       lowProfile.audioCodec = MediaRecorder.AudioEncoder.AAC; 
       lowProfile.duration = hightProfile.duration; 
       lowProfile.videoCodec = MediaRecorder.VideoEncoder.H264; 
       lowProfile.videoFrameRate = hightProfile.videoFrameRate; 
       lowProfile.videoBitRate = 1500000 > hightProfile.videoBitRate ? hightProfile.videoBitRate 
         : 1500000; 
       if (mSupportVideoSizes != null && !mSupportVideoSizes.isEmpty()) { 
        int width = 640; 
        int height = 480; 
        Collections.sort(mSupportVideoSizes, new SizeComparator()); 
        int lwd = mSupportVideoSizes.get(0).width; 
        for (Size size : mSupportVideoSizes) { 
         int wd = Math.abs(size.width - 640); 
         if (wd < lwd) { 
          width = size.width; 
          height = size.height; 
          lwd = wd; 
         } else { 
          break; 
         } 
        } 
        lowProfile.videoFrameWidth = width; 
        lowProfile.videoFrameHeight = height; 
       } 

       mMediaRecorder.setProfile(lowProfile); 
      } 
     } catch (Exception e) { 
      try { 
       mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); 
      } catch (Exception ex) { 
       ex.printStackTrace(); 
      } 
      try { 
       mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); 
      } catch (Exception ex) { 
       ex.printStackTrace(); 
      } 
      if (mSupportVideoSizes != null && !mSupportVideoSizes.isEmpty()) { 
       Collections.sort(mSupportVideoSizes, new SizeComparator()); 
       Size size = mSupportVideoSizes.get(0); 
       try { 
        mMediaRecorder.setVideoSize(size.width, size.height); 
       } catch (Exception ex) { 
        ex.printStackTrace(); 
       } 
      } else { 
       try { 
        mMediaRecorder.setVideoSize(640, 480); 
       } catch (Exception ex) { 
        ex.printStackTrace(); 
       } 
      } 
      e.printStackTrace(); 
     } 

     File f = null; 
     try { 
      f = setUpVideoFile(); 
      filePath = f.getAbsolutePath(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
      f = null; 
      filePath = null; 
     } 
     mMediaRecorder.setOutputFile(filePath); 

     mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface()); 

     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) { 
      try { 
       mMediaRecorder.setOrientationHint(90); 
      } catch (NoSuchMethodError e) { 
       e.printStackTrace(); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 

     try { 
      mMediaRecorder.prepare(); 
     } catch (IllegalStateException e) { 
      Log.d("VideoPreview", 
        "IllegalStateException preparing MediaRecorder: " 
          + e.getMessage()); 
      releaseMediaRecorder(); 
      return false; 
     } catch (IOException e) { 
      Log.d("VideoPreview", 
        "IOException preparing MediaRecorder: " + e.getMessage()); 
      releaseMediaRecorder(); 
      return false; 
     } catch (Exception e) { 
      releaseMediaRecorder(); 
      e.printStackTrace(); 
     } 
     return true; 
    } 

    private void releaseMediaRecorder() { 
     if (mMediaRecorder != null) { 
      mMediaRecorder.reset(); 
      mMediaRecorder.release(); 
      mMediaRecorder = null; 
      mCamera.lock(); 
     } 
    } 

    private void releaseCamera() { 
     if (mCamera != null) { 
      mCamera.release(); 
      mCamera = null; 
     } 
    } 

    private void startRecord() { 
     try { 
      if (initVideoRecorder()) { 
       mMediaRecorder.start(); 
       iv_record.setImageResource(R.drawable.btn_video_stop); 
      } else { 
       releaseMediaRecorder(); 
       iv_record.setImageResource(R.drawable.btn_video_start); 
      } 
      tv_counter.setVisibility(View.VISIBLE); 
      tv_counter.setText("00:0" + (MAX_VIDEO_DURATION/1000)); 
      Message msg = mHandler.obtainMessage(ID_TIME_COUNT, 1, 
        MAX_VIDEO_DURATION/1000); 
      mHandler.sendMessage(msg); 
      mIsRecording = true; 
     } catch (Exception e) { 
      showShortToast("problem while capturing video"); 
      e.printStackTrace(); 
      exit(RESULT_ERROR, null); 
     } 
    } 

    private void stopRecord() { 
     try { 
      mMediaRecorder.stop(); 
     } catch (Exception e) { 
      if (new File(filePath) != null 
        && new File(filePath).exists()) { 
       new File(filePath).delete(); 
      } 
     } 
     releaseMediaRecorder(); 
     mCamera.lock(); 
     iv_record.setImageResource(R.drawable.btn_video_start); 
     mIsRecording = false; 

     iv_record.setVisibility(View.GONE); 
     iv_cancel.setVisibility(View.VISIBLE); 
     iv_ok.setVisibility(View.VISIBLE); 
    } 

    public static void setCameraDisplayOrientation(Activity activity, 
                int cameraId, Camera camera) { 
     Camera.CameraInfo info = new Camera.CameraInfo(); // Since API level 9 
     Camera.getCameraInfo(cameraId, info); 
     int rotation = activity.getWindowManager().getDefaultDisplay() 
       .getRotation(); 
     int degrees = 0; 
     switch (rotation) { 
      case Surface.ROTATION_0: 
       degrees = 0; 
       break; 
      case Surface.ROTATION_90: 
       degrees = 90; 
       break; 
      case Surface.ROTATION_180: 
       degrees = 180; 
       break; 
      case Surface.ROTATION_270: 
       degrees = 270; 
       break; 
     } 

     int result; 
     if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { 
      result = (info.orientation + degrees) % 360; 
      result = (360 - result) % 360; 
     } else { 
      result = (info.orientation - degrees + 360) % 360; 
     } 
     camera.setDisplayOrientation(result); 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 
     openCamera(); 
    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 
     releaseCamera(); 
    } 

    @Override 
    public void surfaceCreated(SurfaceHolder holder) { 
     if (mCamera != null) { 
      try { 
       mCamera.setPreviewDisplay(holder); 
       mCamera.startPreview(); 
      } catch (Exception e) { 
      } 
     } 
    } 

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

    } 

    @Override 
    public void surfaceDestroyed(SurfaceHolder holder) { 
     if (mCamera != null) { 
      try { 
       mCamera.stopPreview(); 
      } catch (Exception e) { 
      } 
     } 
    } 

    @Override 
    public boolean onKeyDown(int keyCode, KeyEvent event) { 
     if (keyCode == KeyEvent.KEYCODE_BACK) { 
      exit(RESULT_CANCELED, null); 
      return true; 
     } 
     return super.onKeyDown(keyCode, event); 
    } 

    @Override 
    public void onClick(View arg0) { 
     switch (arg0.getId()) { 
      case R.id.iv_ok: 
       Intent data = new Intent(); 
       if (filePath != null) { 
        data.putExtra("videopath", filePath); 
       } 
       exit(RESULT_OK, data); 
       break; 
      case R.id.iv_cancel: 
       exit(RESULT_CANCELED, null); 
       break; 
      case R.id.iv_record: 
       if (mIsRecording) { 
        stopRecord(); 
       } else { 
        startRecord(); 
       } 
       break; 
      default: 
       break; 
     } 
    } 

    protected void showShortToast(String text) { 
     Toast.makeText(this, text, Toast.LENGTH_SHORT).show(); 
    } 

    private File setUpVideoFile() throws IOException { 

     File videoFile = null; 

     if (Environment.MEDIA_MOUNTED.equals(Environment 
       .getExternalStorageState())) { 

      File storageDir = new File(
        EmBazaarConstants.LOCAL_STORAGE_BASE_PATH_FOR_POSTED_VIDEOS) 
        .getParentFile(); 

      if (storageDir != null) { 
       if (!storageDir.mkdirs()) { 
        if (!storageDir.exists()) { 
         Log.d("CameraSample", "failed to create directory"); 
         return null; 
        } 
       } 
      } 
      videoFile = File.createTempFile(EmBazaarConstants.MP4_FILE_PREFIX 
          + System.currentTimeMillis() + "_", 
        EmBazaarConstants.MP4_FILE_SUFIX, storageDir); 
     } else { 
      Log.v(getString(R.string.app_name), 
        "External storage is not mounted READ/WRITE."); 
     } 

     return videoFile; 
    } 

    private class SizeComparator implements Comparator<Size> { 

     @Override 
     public int compare(Size lhs, Size rhs) { 
      return rhs.width - lhs.width; 
     } 
    } 

    public static boolean isEmpty(String str) { 
     return str == null || "".equals(str.trim()); 
    } 

} 

이며, 당신은 단순히이

if (isDeviceSupportCamera()) { 
        startActivityForResult(new Intent(PostStatusActivity.this, 
            yourActivity.class), 
          EmBazaarConstants.CAMERA_CAPTURE_VIDEO); 
       } else { 
        Toast.makeText(this, "Your device doesn't support camera", 
          Toast.LENGTH_LONG).show(); 
       } 

처럼 활동이 클래스를 호출 할 수 있으며, 여기에, 이 코드를 작성해야합니다.

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    super.onActivityResult(requestCode, resultCode, data); 

     if (requestCode == EmBazaarConstants.CAMERA_CAPTURE_VIDEO 
       && resultCode == RESULT_OK) { 

      if (data != null && data.getStringExtra("videopath") != null) 
       videoFilePath= data.getStringExtra("videopath"); 
}   

} 

희망이 도움이됩니다.

** 우리는 안드로이드 롤리팝에 새로운 Camera2 API를 가지고 있지만이 코드는 여전히 안드로이드 롤리팝에서 작동합니다.하지만 원하는 경우 새 Camera2 API로 변경할 수 있습니다.

+0

여기 EmBazaarConstants 클래스도 붙여 넣을 수 있습니까? –

+0

그들은 기본적으로 상수입니다. 앱 이름, 요청 코드, 비디오 이름 접두사 및 접미사에 대해 vid_ 및 .mp4 각각 사용할 수 있습니다. –