自定义安卓视频录制功能
2014-06-09 17:57
429 查看
自定义安卓视频录制功能:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1" >
<com.example.camera.MediaRecorderSurface
android:id="@+id/surfaceViewCamera"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<TextView
android:id="@+id/recordTimes"
android:layout_width="fill_parent"
android:layout_height="60dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:background="#50000000"
android:gravity="center"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#cfcfcf"
android:textSize="25sp"
android:text="@string/action_settings" />
</RelativeLayout>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="80dp"
android:background="#FFFFFF"
android:paddingLeft="10dp"
android:paddingRight="10dp" >
<Button
android:id="@+id/btn_back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:background="@drawable/back" />
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true" >
<Button
android:id="@+id/btn_record"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/camera"
android:onClick="capture" />
<Button
android:id="@+id/btn_recorder"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_toRightOf="@id/btn_record"
android:background="@drawable/video" />
</RelativeLayout>
<ImageView
android:id="@+id/img"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:background="@drawable/gallery"
android:scaleType="fitXY" />
</RelativeLayout>
</LinearLayout>
public class MainActivity extends Activity implements OnClickListener {
private MediaRecorderSurface mSurface;
private boolean isStart;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_mediarecord_test);
mSurface = (MediaRecorderSurface) findViewById(R.id.surfaceViewCamera);
mSurface.setOnClickListener(this);
//开始/停止录像
View view = findViewById(R.id.btn_record);
view.setOnClickListener(this);
//返回
view = findViewById(R.id.btn_back);
view.setOnClickListener(this);
//转换摄像机
view = findViewById(R.id.img);
view.setOnClickListener(this);
((TextView)findViewById(R.id.recordTimes)).setText("00:00");
}
private boolean flag;
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_record:
if (!isStart) {
Toast.makeText(this, "开始录像", Toast.LENGTH_SHORT).show();
timer = 0;//清零
mSurface.start();
startTimer();//录制时间
isStart = true;
}else{
Toast.makeText(this, "停止录像", Toast.LENGTH_SHORT).show();
mSurface.stop();
isStart = false;
showDialog();
}
break;
case R.id.img:
if (flag) {
mSurface.swapCamera(2);
}else{
mSurface.swapCamera(1);
}
flag = !flag;
break;
case R.id.btn_back:
if (flag) {
mSurface.openLight();
}else
mSurface.closeLight();
// finish();
break;
}
}
private Handler handler = new Handler(){
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case 1:
String str = (String) msg.obj;
((TextView)findViewById(R.id.recordTimes)).setText(str);
break;
case 2:
isStart = false;//停止播放
mSurface.stop();//停止录音
showDialog();
((TextView)findViewById(R.id.recordTimes)).setText("00:00");
break;
}
};
};
private void showDialog(){
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
dialog.setTitle("提示");
long size = mSurface.getOutFile().length();
size = Math.round(size/1024/1024.0);
dialog.setMessage("录制完毕,保存路径:"+mSurface.getOutFile().getAbsolutePath()+"\n"+size+"M");
dialog.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
Intent intent = new Intent("android.intent.action.VIEW");
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("oneshot", 0);
intent.putExtra("configchange", 0);
Uri uri = Uri.fromFile(mSurface.getOutFile());
intent.setDataAndType(uri, "video/*");
startActivity(intent);
}
});
dialog.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
dialog.show();
}
private long timer = 0;
private void startTimer(){
new Thread(){
public void run() {
while (isStart) {
timer+=1000;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (timer>=30*1000) {//录制完成
isStart = false;//停止
handler.sendEmptyMessage(2);
}else{
Message msg = handler.obtainMessage();
msg.what = 1;
String str = ToolUtils.formatTimer(timer);
Log.i("CAMERA", str);
msg.obj = str;
handler.sendMessage(msg);
}
}
};
}.start();
}
}
/*****************************
* 视频录制
*
*
* @author util_c
*
*/
public class MediaRecorderSurface extends SurfaceView implements
SurfaceHolder.Callback,Camera.AutoFocusCallback, OnInfoListener, OnErrorListener{
private Camera mCamera;
private MediaRecorder mMediaRecorder;
private File outputFile;
private SurfaceHolder holder;
private int camera_id = 0;//相机的ID
private boolean isStart,isOpenLight;//开始录像/是否打开闪光灯
public MediaRecorderSurface(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
init();
}
public MediaRecorderSurface(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public MediaRecorderSurface(Context context) {
super(context);
init();
}
private void init() {
holder = this.getHolder();
holder.addCallback(this);
this.setKeepScreenOn(true);
//获取相机
mCamera = getMyCamera();
// 设置像素/大小
// setmCameraParameters(mCamera);
// 显示水平角度
mCamera.setDisplayOrientation(90);// 90
}
/*********释放摄像机*********/
private void releaseCamera(Camera mCamera){
if (mCamera!=null) {
//停止预览视图
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
}
/**********开始录制视频***************/
public void start(){
if (mCamera!=null) {
//自动距焦
mCamera.autoFocus(this);
//录制的视频路径
outputFile = MediaUtils.getOutputMediaFile(MediaUtils.MEDIA_TYPE_VIDEO);
try {
startRecorder(outputFile);
} catch (IllegalStateException e) {
releaseCamera(mCamera);
e.printStackTrace();
} catch (IOException e) {
releaseCamera(mCamera);
e.printStackTrace();
}
// startVideo();
isStart = true;//开始录制
}else{
logger("start:no camcara");
}
}
/**********停止录制视频***************/
public void stop(){
if (isStart) {
stopRecorder(mCamera);
isStart = false;//可以录制
}
}
/*********打开的灯*********/
public void openLight(){
freshLight(3);//手电筒
}
/*********关闭的灯*********/
public void closeLight(){
freshLight(0);//关
}
/***********
* 转换摄像机
* <只有在,没有开始录像时,才能转换摄像机>
* ********************/
public void swapCamera(int position){
//只有在,没有开始录像时,才能转换摄像机
if (!isStart) {
if (mCamera!=null) {
//转换摄像机
convertCamera(position);
}else{
logger("no camera");
}
}
}
/****************************
* 开始录像
* 创建一个MediaRecorder对象
* @param file
* @throws IllegalStateException
* @throws IOException
*/
private void startRecorder(File file) throws IllegalStateException, IOException{
logger("startRecorder:"+file.getCanonicalPath());
//打开摄像机锁
mCamera.unlock();
mMediaRecorder = new MediaRecorder();
mMediaRecorder.setCamera(mCamera);
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
int sdkVersion = Integer.valueOf(android.os.Build.VERSION.SDK);
logger("sdkVersion="+sdkVersion);
if (sdkVersion<9) {
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
}else{
// mMediaRecorder.setVideoSize(176, 144);
// mMediaRecorder.setOrientationHint(90);
//画面质量为高清0-1
//CamcorderProfile.QUALITY_HIGH高清 1
//CamcorderProfile.QUALITY_LOW 低 0
mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_LOW));
mMediaRecorder.setVideoFrameRate(12);//采样率
}
mMediaRecorder.setPreviewDisplay(holder.getSurface());
mMediaRecorder.setOutputFile(file.getCanonicalPath());
mMediaRecorder.prepare();
mMediaRecorder.setOnInfoListener(this);
mMediaRecorder.setOnErrorListener(this);
mMediaRecorder.start();
mCamera.setPreviewCallback(new PreviewCallback() {
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
// logger("Receive data size:"+data.length);
//处理图片
}
});
}
/**************************
* 闪光灯:0,关,1开,2,自动,3,手电筒
* @param mCamera
* @param count
*/
public void freshLight(int count) {
Parameters parameters = mCamera.getParameters();
switch (count % 3) {
case 0:// 关
parameters.setFlashMode(Parameters.FLASH_MODE_OFF);
break;
case 1:// 开
parameters.setFlashMode(Parameters.FLASH_MODE_ON);
break;
case 2:// 自动
parameters.setFlashMode(Parameters.FLASH_MODE_AUTO);
break;
case 3://手电筒
parameters.setFlashMode(Parameters.FLASH_MODE_TORCH);
break;
}
mCamera.setParameters(parameters);
mCamera.startPreview();
}
/**************************
* 关闭录音,并为摄像机加锁
* @param mCamera
*/
private void stopRecorder(Camera mCamera){
logger("stopRecorder");
if (mMediaRecorder != null) {
mMediaRecorder.stop();
// mMediaRecorder.reset();
mMediaRecorder.release();
mMediaRecorder = null;
//关闭摄像机
if (mCamera!=null) {
mCamera.setPreviewCallback(null);
mCamera.lock();//解除锁
}
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
logger("surfaceChanged");
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
logger("surfaceCreated");
try {
//摄像机所获取的图像显示到指定的视图上
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();//打开预览视图
} catch (IOException e) {
releaseCamera(mCamera);
e.printStackTrace();
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
logger("surfaceDestroyed");
releaseCamera(mCamera);
}
@Override
public void onAutoFocus(boolean success, Camera camera) {
logger("onAutoFocus");
}
public void logger(String msg) {
Log.i("TAG", msg);
}
/*************************
* 设置摄像机的映像图大小像素/照片的大小
*
* @param mCamera
*/
public void setmCameraParameters(Camera mCamera) {
Parameters parameters = mCamera.getParameters();
// 设置照片分辨率
List<Camera.Size> previewSizeList = parameters.getSupportedPreviewSizes();
int previewWidth = 0;
int previewHeight = 0;
// 设置录制像素的宽/高
for (int i = 0; i < previewSizeList.size() - 1; i++) {
// 摄像机的宽/高
previewWidth = previewSizeList.get(i).width;
previewHeight = previewSizeList.get(i).height;
logger("previewWidth=" + previewWidth + ",previewHeight="
+ previewHeight);
//
int nextWidth = previewSizeList.get(i + 1).width;
int nextHeight = previewSizeList.get(i + 1).height;
logger("nextWidth=" + nextWidth + ",nextHeight=" + nextHeight);
if (previewWidth > nextWidth) {
previewWidth = nextWidth;
}
if (previewHeight > nextHeight) {
previewHeight = nextHeight;
}
}
// previewWidth = previewWidth > previewSizeList.get(0).width ? previewWidth
// : previewSizeList.get(0).width;
// previewHeight = previewHeight > previewSizeList.get(0).height ? previewHeight
// : previewSizeList.get(0).height;
// parameters.setPreviewSize(previewWidth, previewHeight);//设置图片的尺寸为最大的
// 设置支持的像素分辨率大小
List<Camera.Size> supportedPictureSizesList = parameters
.getSupportedPictureSizes();
int supportedPictureWidth = 0;
int supportedPictureHeight = 0;
for (int i = 0; i < supportedPictureSizesList.size() - 1; i++) {
supportedPictureWidth = supportedPictureSizesList.get(i).width;
supportedPictureHeight = supportedPictureSizesList.get(i).height;
logger("supportedPictureWidth=" + supportedPictureWidth
+ ",supportedPictureHeight=" + supportedPictureHeight);
int nextWidth = supportedPictureSizesList.get(i + 1).width;
int nextHeight = supportedPictureSizesList.get(i + 1).height;
logger("nextWidth=" + nextWidth + ",nextHeight=" + nextHeight);
//设置所支持的最小尺寸大小
if (supportedPictureWidth > nextWidth) {
supportedPictureWidth = nextWidth;
}
if (supportedPictureHeight > nextHeight) {
supportedPictureHeight = nextHeight;
}
}
// supportedPictureWidth = supportedPictureWidth > supportedPictureSizesList
// .get(0).width ? supportedPictureWidth
// : supportedPictureSizesList.get(0).width;
// supportedPictureHeight = supportedPictureHeight > supportedPictureSizesList
// .get(0).height ? supportedPictureHeight
// : supportedPictureSizesList.get(0).height;
// parameters
// .setPictureSize(supportedPictureWidth, supportedPictureHeight);
logger("____previewWidth=" + previewWidth + ",previewHeight="
+ previewHeight);
logger("___supportedPictureWidth=" + supportedPictureWidth
+ ",supportedPictureHeight=" + supportedPictureHeight);
//画面旋转90度
parameters.setRotation(90);//旋转角度
//打开手电筒
parameters.setFlashMode(Parameters.FLASH_MODE_TORCH);
mCamera.setParameters(parameters);
}
/********获取相机的个数********/
@SuppressLint("NewApi")
private Camera getMyCamera() {
Camera c = null;
//默认的
if (c == null) {
if (MediaUtils.checkCameraHardware(getContext())) {
c = Camera.open();
}
}
return c;
}
/*************************
*
* 转换摄像机
*
* @param cameraPosition
* @param camera
*/
@SuppressLint("NewApi")
private void convertCamera(int cameraPosition){
//切换前后摄像头
int cameraCount = 0;
CameraInfo cameraInfo = new CameraInfo();
cameraCount = Camera.getNumberOfCameras();//得到摄像头的个数
if (cameraPosition>cameraCount) {
Toast.makeText(getContext(), "您只有"+cameraCount+"摄像机", Toast.LENGTH_SHORT).show();
return;
}
for(int i = 0; i < cameraCount; i++) {
Camera.getCameraInfo(i, cameraInfo);//得到每一个摄像头的信息
if(cameraPosition == 1) {
//代表摄像头的方位,CAMERA_FACING_FRONT前置 CAMERA_FACING_BACK后置
//现在是后置,变更为前置
if(cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
try {
releaseCamera(mCamera);//释放当前摄像机
mCamera = openCamera(i, holder, 90);
} catch (IOException e1) {
e1.printStackTrace();
}
break;
}
logger("前置");
} else {
//代表摄像头的方位,CAMERA_FACING_FRONT前置 CAMERA_FACING_BACK后置
//现在是前置, 变更为后置
if(cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
try {
releaseCamera(mCamera);//释放当前摄像机
mCamera = openCamera(i, holder, 90);
} catch (IOException e1) {
e1.printStackTrace();
}
camera_id = 1;
break;
}
logger("后置");
}
}
}
/********获取保存路径************/
public File getOutFile(){
return outputFile;
}
/**********************
* 打开指的一个摄像机
* @param position 那一个摄像机
* @param holder
* @param angle 旋转角色
* @throws IOException
*/
@SuppressLint("NewApi")
private Camera openCamera(int position,SurfaceHolder holder,int angle) throws IOException {
Camera camera = Camera.open(position);// 打开当前选中的摄像头
camera.setPreviewDisplay(holder);// 通过surfaceview显示取景画面
camera.startPreview();// 开始预览
// 设置预览图效果/图片大小
// setmCameraParameters(camera);
// 显示水平角度
camera.setDisplayOrientation(angle);// 90
return camera;
}
@Override
public void onInfo(MediaRecorder mr, int what, int extra) {
}
@Override
public void onError(MediaRecorder mr, int what, int extra) {
}
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1" >
<com.example.camera.MediaRecorderSurface
android:id="@+id/surfaceViewCamera"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<TextView
android:id="@+id/recordTimes"
android:layout_width="fill_parent"
android:layout_height="60dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:background="#50000000"
android:gravity="center"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#cfcfcf"
android:textSize="25sp"
android:text="@string/action_settings" />
</RelativeLayout>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="80dp"
android:background="#FFFFFF"
android:paddingLeft="10dp"
android:paddingRight="10dp" >
<Button
android:id="@+id/btn_back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:background="@drawable/back" />
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true" >
<Button
android:id="@+id/btn_record"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/camera"
android:onClick="capture" />
<Button
android:id="@+id/btn_recorder"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_toRightOf="@id/btn_record"
android:background="@drawable/video" />
</RelativeLayout>
<ImageView
android:id="@+id/img"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:background="@drawable/gallery"
android:scaleType="fitXY" />
</RelativeLayout>
</LinearLayout>
public class MainActivity extends Activity implements OnClickListener {
private MediaRecorderSurface mSurface;
private boolean isStart;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_mediarecord_test);
mSurface = (MediaRecorderSurface) findViewById(R.id.surfaceViewCamera);
mSurface.setOnClickListener(this);
//开始/停止录像
View view = findViewById(R.id.btn_record);
view.setOnClickListener(this);
//返回
view = findViewById(R.id.btn_back);
view.setOnClickListener(this);
//转换摄像机
view = findViewById(R.id.img);
view.setOnClickListener(this);
((TextView)findViewById(R.id.recordTimes)).setText("00:00");
}
private boolean flag;
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_record:
if (!isStart) {
Toast.makeText(this, "开始录像", Toast.LENGTH_SHORT).show();
timer = 0;//清零
mSurface.start();
startTimer();//录制时间
isStart = true;
}else{
Toast.makeText(this, "停止录像", Toast.LENGTH_SHORT).show();
mSurface.stop();
isStart = false;
showDialog();
}
break;
case R.id.img:
if (flag) {
mSurface.swapCamera(2);
}else{
mSurface.swapCamera(1);
}
flag = !flag;
break;
case R.id.btn_back:
if (flag) {
mSurface.openLight();
}else
mSurface.closeLight();
// finish();
break;
}
}
private Handler handler = new Handler(){
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case 1:
String str = (String) msg.obj;
((TextView)findViewById(R.id.recordTimes)).setText(str);
break;
case 2:
isStart = false;//停止播放
mSurface.stop();//停止录音
showDialog();
((TextView)findViewById(R.id.recordTimes)).setText("00:00");
break;
}
};
};
private void showDialog(){
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
dialog.setTitle("提示");
long size = mSurface.getOutFile().length();
size = Math.round(size/1024/1024.0);
dialog.setMessage("录制完毕,保存路径:"+mSurface.getOutFile().getAbsolutePath()+"\n"+size+"M");
dialog.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
Intent intent = new Intent("android.intent.action.VIEW");
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("oneshot", 0);
intent.putExtra("configchange", 0);
Uri uri = Uri.fromFile(mSurface.getOutFile());
intent.setDataAndType(uri, "video/*");
startActivity(intent);
}
});
dialog.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
dialog.show();
}
private long timer = 0;
private void startTimer(){
new Thread(){
public void run() {
while (isStart) {
timer+=1000;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (timer>=30*1000) {//录制完成
isStart = false;//停止
handler.sendEmptyMessage(2);
}else{
Message msg = handler.obtainMessage();
msg.what = 1;
String str = ToolUtils.formatTimer(timer);
Log.i("CAMERA", str);
msg.obj = str;
handler.sendMessage(msg);
}
}
};
}.start();
}
}
/*****************************
* 视频录制
*
*
* @author util_c
*
*/
public class MediaRecorderSurface extends SurfaceView implements
SurfaceHolder.Callback,Camera.AutoFocusCallback, OnInfoListener, OnErrorListener{
private Camera mCamera;
private MediaRecorder mMediaRecorder;
private File outputFile;
private SurfaceHolder holder;
private int camera_id = 0;//相机的ID
private boolean isStart,isOpenLight;//开始录像/是否打开闪光灯
public MediaRecorderSurface(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
init();
}
public MediaRecorderSurface(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public MediaRecorderSurface(Context context) {
super(context);
init();
}
private void init() {
holder = this.getHolder();
holder.addCallback(this);
this.setKeepScreenOn(true);
//获取相机
mCamera = getMyCamera();
// 设置像素/大小
// setmCameraParameters(mCamera);
// 显示水平角度
mCamera.setDisplayOrientation(90);// 90
}
/*********释放摄像机*********/
private void releaseCamera(Camera mCamera){
if (mCamera!=null) {
//停止预览视图
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
}
/**********开始录制视频***************/
public void start(){
if (mCamera!=null) {
//自动距焦
mCamera.autoFocus(this);
//录制的视频路径
outputFile = MediaUtils.getOutputMediaFile(MediaUtils.MEDIA_TYPE_VIDEO);
try {
startRecorder(outputFile);
} catch (IllegalStateException e) {
releaseCamera(mCamera);
e.printStackTrace();
} catch (IOException e) {
releaseCamera(mCamera);
e.printStackTrace();
}
// startVideo();
isStart = true;//开始录制
}else{
logger("start:no camcara");
}
}
/**********停止录制视频***************/
public void stop(){
if (isStart) {
stopRecorder(mCamera);
isStart = false;//可以录制
}
}
/*********打开的灯*********/
public void openLight(){
freshLight(3);//手电筒
}
/*********关闭的灯*********/
public void closeLight(){
freshLight(0);//关
}
/***********
* 转换摄像机
* <只有在,没有开始录像时,才能转换摄像机>
* ********************/
public void swapCamera(int position){
//只有在,没有开始录像时,才能转换摄像机
if (!isStart) {
if (mCamera!=null) {
//转换摄像机
convertCamera(position);
}else{
logger("no camera");
}
}
}
/****************************
* 开始录像
* 创建一个MediaRecorder对象
* @param file
* @throws IllegalStateException
* @throws IOException
*/
private void startRecorder(File file) throws IllegalStateException, IOException{
logger("startRecorder:"+file.getCanonicalPath());
//打开摄像机锁
mCamera.unlock();
mMediaRecorder = new MediaRecorder();
mMediaRecorder.setCamera(mCamera);
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
int sdkVersion = Integer.valueOf(android.os.Build.VERSION.SDK);
logger("sdkVersion="+sdkVersion);
if (sdkVersion<9) {
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
}else{
// mMediaRecorder.setVideoSize(176, 144);
// mMediaRecorder.setOrientationHint(90);
//画面质量为高清0-1
//CamcorderProfile.QUALITY_HIGH高清 1
//CamcorderProfile.QUALITY_LOW 低 0
mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_LOW));
mMediaRecorder.setVideoFrameRate(12);//采样率
}
mMediaRecorder.setPreviewDisplay(holder.getSurface());
mMediaRecorder.setOutputFile(file.getCanonicalPath());
mMediaRecorder.prepare();
mMediaRecorder.setOnInfoListener(this);
mMediaRecorder.setOnErrorListener(this);
mMediaRecorder.start();
mCamera.setPreviewCallback(new PreviewCallback() {
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
// logger("Receive data size:"+data.length);
//处理图片
}
});
}
/**************************
* 闪光灯:0,关,1开,2,自动,3,手电筒
* @param mCamera
* @param count
*/
public void freshLight(int count) {
Parameters parameters = mCamera.getParameters();
switch (count % 3) {
case 0:// 关
parameters.setFlashMode(Parameters.FLASH_MODE_OFF);
break;
case 1:// 开
parameters.setFlashMode(Parameters.FLASH_MODE_ON);
break;
case 2:// 自动
parameters.setFlashMode(Parameters.FLASH_MODE_AUTO);
break;
case 3://手电筒
parameters.setFlashMode(Parameters.FLASH_MODE_TORCH);
break;
}
mCamera.setParameters(parameters);
mCamera.startPreview();
}
/**************************
* 关闭录音,并为摄像机加锁
* @param mCamera
*/
private void stopRecorder(Camera mCamera){
logger("stopRecorder");
if (mMediaRecorder != null) {
mMediaRecorder.stop();
// mMediaRecorder.reset();
mMediaRecorder.release();
mMediaRecorder = null;
//关闭摄像机
if (mCamera!=null) {
mCamera.setPreviewCallback(null);
mCamera.lock();//解除锁
}
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
logger("surfaceChanged");
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
logger("surfaceCreated");
try {
//摄像机所获取的图像显示到指定的视图上
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();//打开预览视图
} catch (IOException e) {
releaseCamera(mCamera);
e.printStackTrace();
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
logger("surfaceDestroyed");
releaseCamera(mCamera);
}
@Override
public void onAutoFocus(boolean success, Camera camera) {
logger("onAutoFocus");
}
public void logger(String msg) {
Log.i("TAG", msg);
}
/*************************
* 设置摄像机的映像图大小像素/照片的大小
*
* @param mCamera
*/
public void setmCameraParameters(Camera mCamera) {
Parameters parameters = mCamera.getParameters();
// 设置照片分辨率
List<Camera.Size> previewSizeList = parameters.getSupportedPreviewSizes();
int previewWidth = 0;
int previewHeight = 0;
// 设置录制像素的宽/高
for (int i = 0; i < previewSizeList.size() - 1; i++) {
// 摄像机的宽/高
previewWidth = previewSizeList.get(i).width;
previewHeight = previewSizeList.get(i).height;
logger("previewWidth=" + previewWidth + ",previewHeight="
+ previewHeight);
//
int nextWidth = previewSizeList.get(i + 1).width;
int nextHeight = previewSizeList.get(i + 1).height;
logger("nextWidth=" + nextWidth + ",nextHeight=" + nextHeight);
if (previewWidth > nextWidth) {
previewWidth = nextWidth;
}
if (previewHeight > nextHeight) {
previewHeight = nextHeight;
}
}
// previewWidth = previewWidth > previewSizeList.get(0).width ? previewWidth
// : previewSizeList.get(0).width;
// previewHeight = previewHeight > previewSizeList.get(0).height ? previewHeight
// : previewSizeList.get(0).height;
// parameters.setPreviewSize(previewWidth, previewHeight);//设置图片的尺寸为最大的
// 设置支持的像素分辨率大小
List<Camera.Size> supportedPictureSizesList = parameters
.getSupportedPictureSizes();
int supportedPictureWidth = 0;
int supportedPictureHeight = 0;
for (int i = 0; i < supportedPictureSizesList.size() - 1; i++) {
supportedPictureWidth = supportedPictureSizesList.get(i).width;
supportedPictureHeight = supportedPictureSizesList.get(i).height;
logger("supportedPictureWidth=" + supportedPictureWidth
+ ",supportedPictureHeight=" + supportedPictureHeight);
int nextWidth = supportedPictureSizesList.get(i + 1).width;
int nextHeight = supportedPictureSizesList.get(i + 1).height;
logger("nextWidth=" + nextWidth + ",nextHeight=" + nextHeight);
//设置所支持的最小尺寸大小
if (supportedPictureWidth > nextWidth) {
supportedPictureWidth = nextWidth;
}
if (supportedPictureHeight > nextHeight) {
supportedPictureHeight = nextHeight;
}
}
// supportedPictureWidth = supportedPictureWidth > supportedPictureSizesList
// .get(0).width ? supportedPictureWidth
// : supportedPictureSizesList.get(0).width;
// supportedPictureHeight = supportedPictureHeight > supportedPictureSizesList
// .get(0).height ? supportedPictureHeight
// : supportedPictureSizesList.get(0).height;
// parameters
// .setPictureSize(supportedPictureWidth, supportedPictureHeight);
logger("____previewWidth=" + previewWidth + ",previewHeight="
+ previewHeight);
logger("___supportedPictureWidth=" + supportedPictureWidth
+ ",supportedPictureHeight=" + supportedPictureHeight);
//画面旋转90度
parameters.setRotation(90);//旋转角度
//打开手电筒
parameters.setFlashMode(Parameters.FLASH_MODE_TORCH);
mCamera.setParameters(parameters);
}
/********获取相机的个数********/
@SuppressLint("NewApi")
private Camera getMyCamera() {
Camera c = null;
//默认的
if (c == null) {
if (MediaUtils.checkCameraHardware(getContext())) {
c = Camera.open();
}
}
return c;
}
/*************************
*
* 转换摄像机
*
* @param cameraPosition
* @param camera
*/
@SuppressLint("NewApi")
private void convertCamera(int cameraPosition){
//切换前后摄像头
int cameraCount = 0;
CameraInfo cameraInfo = new CameraInfo();
cameraCount = Camera.getNumberOfCameras();//得到摄像头的个数
if (cameraPosition>cameraCount) {
Toast.makeText(getContext(), "您只有"+cameraCount+"摄像机", Toast.LENGTH_SHORT).show();
return;
}
for(int i = 0; i < cameraCount; i++) {
Camera.getCameraInfo(i, cameraInfo);//得到每一个摄像头的信息
if(cameraPosition == 1) {
//代表摄像头的方位,CAMERA_FACING_FRONT前置 CAMERA_FACING_BACK后置
//现在是后置,变更为前置
if(cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
try {
releaseCamera(mCamera);//释放当前摄像机
mCamera = openCamera(i, holder, 90);
} catch (IOException e1) {
e1.printStackTrace();
}
break;
}
logger("前置");
} else {
//代表摄像头的方位,CAMERA_FACING_FRONT前置 CAMERA_FACING_BACK后置
//现在是前置, 变更为后置
if(cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
try {
releaseCamera(mCamera);//释放当前摄像机
mCamera = openCamera(i, holder, 90);
} catch (IOException e1) {
e1.printStackTrace();
}
camera_id = 1;
break;
}
logger("后置");
}
}
}
/********获取保存路径************/
public File getOutFile(){
return outputFile;
}
/**********************
* 打开指的一个摄像机
* @param position 那一个摄像机
* @param holder
* @param angle 旋转角色
* @throws IOException
*/
@SuppressLint("NewApi")
private Camera openCamera(int position,SurfaceHolder holder,int angle) throws IOException {
Camera camera = Camera.open(position);// 打开当前选中的摄像头
camera.setPreviewDisplay(holder);// 通过surfaceview显示取景画面
camera.startPreview();// 开始预览
// 设置预览图效果/图片大小
// setmCameraParameters(camera);
// 显示水平角度
camera.setDisplayOrientation(angle);// 90
return camera;
}
@Override
public void onInfo(MediaRecorder mr, int what, int extra) {
}
@Override
public void onError(MediaRecorder mr, int what, int extra) {
}
}
相关文章推荐
- 安卓微信小视频录制功能实现
- Android (系统+自定义)短视频录制(含暂停继续录制功能) 总结
- Android自定义录制视频功能
- iOS开发进阶 - 用AVFoundation自定义视频录制功能
- iOS开发进阶 - 用AVFoundation自定义视频录制功能
- Android (系统+自定义)短视频录制(含暂停继续录制功能) 总结
- iOS 自定义录制视频功能
- iOS开发进阶 - 用AVFoundation自定义视频录制功能
- ios开发技巧之:用AVFoundation自定义视频录制功能
- iOS 自定义录制视频功能
- 模块管理常规功能自定义系统的设计与实现(54--视频讲解更新高清 )
- 安卓实现视频录制
- 音视频录制功能开发
- 音视频录制功能开发
- 模块管理常规功能自定义系统的设计与实现(53--演示程序和视频讲解 )
- vlc android的编译及截图,录制视频等功能
- 用自定义keystore调试安卓应用(如微信分享等功能)
- 安卓开发:弹出自定义对话框自动播放视频(仿视频广告效果,使用mediaplayer和surfaceview做播放器)
- vlc android的编译及截图,录制视频等功能
- 安卓录制视频问题