調用手機系統進行拍攝視頻

調用手機系統進行拍攝視頻:

拍攝視頻的公共類:

package com.example.shootvideo;

import java.io.File;
import java.io.IOException;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.media.MediaRecorder.OnErrorListener;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
/**
 * 拍攝視頻的公共類
 * @author paul
 *
 */
@SuppressLint("NewApi")
public class CommonShootVideo implements SurfaceHolder.Callback {
	private MediaRecorder mediarecorder;// 錄製視頻的類
	// 用來顯示視頻的一個接口,我靠不用還不行,也就是說用mediarecorder錄製視頻還得給個界面看
	// 想偷偷錄視頻的同學可以考慮別的辦法。。嗯需要實現這個接口的Callback接口
	private SurfaceHolder surfaceHolder;
	private Camera mCamera;
	private File mVideoFile;

	public CommonShootVideo(Context context, SurfaceView surfaceview) {

		init(context, surfaceview);
	}

	// surfaceview 顯示視頻的控件
	private void init(Context context, SurfaceView surfaceview) {
		// 選擇支持半透明模式,在有surfaceview的activity中使用。
		((Activity) context).getWindow().setFormat(PixelFormat.TRANSLUCENT);

		SurfaceHolder holder = surfaceview.getHolder();// 取得holder
		holder.addCallback(this); // holder加入回調接口
		// setType必須設置,要不出錯.
		holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

	}

	public void startVideo(File videoFile) {
		//當videoFile不存在時先創建文件
		initFile(videoFile);
		mVideoFile = videoFile;

		if (mediarecorder == null) {
			mediarecorder = new MediaRecorder();
		} else {
			mediarecorder.reset();
		}

		mCamera = getCameraInstance();
		mediarecorder.setCamera(mCamera);

		// 設置從麥克風採集聲音
		mediarecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
		// 設置錄製視頻源爲Camera(相機)
		mediarecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
		// 設置視頻文件的輸出格式
		// 必須在設置聲音編碼格式、圖像編碼格式之前設置
		// 設置錄製完成後視頻的封裝格式THREE_GPP爲3gp.MPEG_4爲mp4
		mediarecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
		// 設置聲音編碼格式
		mediarecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
		// 設置錄製的視頻編碼h263 h264
		mediarecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
		// 設置視頻錄製的分辨率。必須放在設置編碼和格式的後面,否則報錯
		// after setVideoSource(),after setOutFormat()
		mediarecorder.setVideoSize(640, 480);
		// 設置視頻輸出的格式和編碼
		CamcorderProfile mProfile = CamcorderProfile
				.get(CamcorderProfile.QUALITY_480P);
		mediarecorder.setAudioEncodingBitRate(44100);
		if (mProfile.videoBitRate > 5 * 1024 * 1024) {
			// 很重要,提高視頻清晰度
			mediarecorder.setVideoEncodingBitRate(5 * 1024 * 1024);
		} else {
			mediarecorder.setVideoEncodingBitRate(mProfile.videoBitRate);
		}
		// 設置錄製的視頻幀率。必須放在設置編碼和格式的後面,否則報錯
		// after setVideoSource(),after setOutFormat()
		mediarecorder.setVideoFrameRate(mProfile.videoFrameRate);
		// 指定使用SurfaceView來預覽視頻
		mediarecorder.setPreviewDisplay(surfaceHolder.getSurface());
		// 設置錄製視頻的方向
		// 加了HTC的手機會有問題
		mediarecorder.setOrientationHint(90);
		// 設置視頻文件輸出的路徑
		mediarecorder.setOutputFile(videoFile.getAbsolutePath());

		try {
			// 準備錄製
			mediarecorder.prepare();
			// 開始錄製
			mediarecorder.start();
		} catch (IllegalStateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	/**
	 * 結束拍攝視頻
	 * 
	 * @return 拍攝成功,返回true;拍攝失敗,返回false
	 */
	public boolean stopVideo() {
		// 關閉預覽並釋放資源
		
		if (mediarecorder != null) {
			// 設置後不會崩(不管用)
			// mediarecorder.setOnErrorListener(null);
			// mediarecorder.setPreviewDisplay(null);

			try {
				// 停止錄製
				mediarecorder.stop();
				// 釋放資源
				mediarecorder.release();
				mediarecorder = null;
				return true;
			} catch (Exception e) {
//				LogUtil.i("wpc", "Exception");
				// 當拍攝時間太短時,會報異常,在此刪除不能看的視頻文件
//				FileAccessor.delFile(mVideoFile.getAbsolutePath());
//				ToastUtil.showMessage("拍攝時間太短,請重新拍攝");
				return false;
			}finally{
				if (mCamera != null) {
					mCamera.lock();
					mCamera.stopPreview();
					mCamera.release();
					mCamera = null;
				}
			}

		}

		return false;
	}

	/**
	 * 判斷前置攝像頭是否存在
	 * 
	 * @return
	 */
	@SuppressLint("NewApi")
	private int FindFrontCamera() {
		int cameraCount = 0;
		Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
		cameraCount = Camera.getNumberOfCameras(); // get cameras number

		for (int camIdx = 0; camIdx < cameraCount; camIdx++) {
			Camera.getCameraInfo(camIdx, cameraInfo); // get camerainfo
			if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
				// 代表攝像頭的方位,目前有定義值兩個分別爲CAMERA_FACING_FRONT前置和CAMERA_FACING_BACK後置
				return camIdx;
			}
		}
		return -1;
	}

	/**
	 * 判斷後置攝像頭是否存在
	 * 
	 * @return
	 */
	@SuppressLint("NewApi")
	private int FindBackCamera() {
		int cameraCount = 0;
		Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
		cameraCount = Camera.getNumberOfCameras(); // get cameras number

		for (int camIdx = 0; camIdx < cameraCount; camIdx++) {
			Camera.getCameraInfo(camIdx, cameraInfo); // get camerainfo
			if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
				// 代表攝像頭的方位,目前有定義值兩個分別爲CAMERA_FACING_FRONT前置和CAMERA_FACING_BACK後置
				return camIdx;
			}
		}
		return -1;
	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
		// 將holder,這個holder爲開始在oncreat裏面取得的holder,將它賦給surfaceHolder
		surfaceHolder = holder;
	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		// 將holder,這個holder爲開始在oncreat裏面取得的holder,將它賦給surfaceHolder
		surfaceHolder = holder;
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		// surfaceDestroyed的時候同時對象設置爲null
		surfaceHolder = null;
		mediarecorder = null;
		mCamera = null;
	}

	private Camera getCameraInstance() {
		// 設置攝像頭以及攝像頭的方向
		int CammeraIndex = FindBackCamera();

		Camera mCamera = null;
		try {
			// 獲取Camera實例
			mCamera = Camera.open(CammeraIndex);
			mCamera.setDisplayOrientation(90);
			mCamera.unlock();
		} catch (Exception e) {
			// 攝像頭不可用(正被佔用或不存在)
//			ToastUtil.showMessage("攝像頭不可用");
		}
		// 不可用則返回null
		return mCamera;
	}
	/**
	 * 初始化應用文件夾目錄
	 */
	public static void initDir(File targetDir) {
		if (!targetDir.exists()) {
			targetDir.mkdir();
		}

	}
	/**
	 * 對目標文件進行判斷,不存在,創建(先創建目錄,再創建文件)
	 * @param targetFile
	 */
	public static void initFile(File targetFile){
		if(targetFile.exists()){
			return ;
		}else {
			File dir = targetFile.getParentFile();
			initDir(dir);
			try {
				targetFile.createNewFile();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

我做了一個高仿微信短視頻拍攝功能的demo,圖示:

demo下載地址:http://download.csdn.net/detail/u012604745/9267267點擊打開鏈接


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章