調用手機系統進行拍攝視頻:
拍攝視頻的公共類:
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點擊打開鏈接