标签:
效果图:
java代码:
/** * RecordActivity.java * 版权所有(C) 2013 * 创建:cuiran 2013-10-15 下午3:20:45 */ package com.app931.oa.activity.video; import java.io.IOException; import java.util.List; import com.app931.oa.R; import com.app931.oa.util.LogsUtil; import com.app931.oa.util.SupportedSizesReflect; import android.app.Activity; import android.content.Context; import android.graphics.PixelFormat; import android.hardware.Camera; import android.hardware.Camera.CameraInfo; import android.hardware.Camera.Size; import android.media.AudioManager; import android.media.MediaPlayer; import android.media.MediaPlayer.OnBufferingUpdateListener; import android.media.MediaPlayer.OnCompletionListener; import android.media.MediaRecorder; import android.os.Bundle; import android.util.DisplayMetrics; import android.view.Display; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.view.WindowManager; import android.view.SurfaceHolder.Callback; import android.widget.Button; import android.widget.ImageView; import android.widget.TextView; /** * TODO * @author cuiran * @version 1.0.0 */ public class RecordActivity extends Activity implements Callback,MediaPlayer.OnPreparedListener, OnBufferingUpdateListener, OnCompletionListener { private static final String TAG="RecordActivity"; private String videoPath="/sdcard/love.3gp"; private MediaRecorder mediarecorder;// 录制视频的类 private MediaPlayer mediaPlayer;//播放视频的类 private SurfaceView surfaceview;// 显示视频的控件 private Camera camera; //实现这个接口的Callback接口 private SurfaceHolder surfaceHolder; /** * 是否正在录制true录制中 false未录制 */ private boolean isRecord=false; public boolean isCameraBack=true; private ImageView recordIv; private ImageView recordPlayIv; private int mVideoWidth; private int mVideoHeight; int cameraCount = 0; private int cameraPosition = 1;//0代表前置摄像头,1代表后置摄像头 public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.layout_video_record1); setTitleStr(""); // 选择支持半透明模式,在有surfaceview的activity中使用。 getWindow().setFormat(PixelFormat.TRANSLUCENT); initView(); } /** * TODO */ private void initView() { // TODO Auto-generated method stub surfaceview = (SurfaceView) this.findViewById(R.id.surfaceview); recordIv=(ImageView)findViewById(R.id.recordIv); recordPlayIv=(ImageView)findViewById(R.id.recordPlayIv); SurfaceHolder holder = surfaceview.getHolder();// 取得holder holder.addCallback(this); // holder加入回调接口 // setType必须设置,要不出错. holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); } /** * 播放视频 * TODO * @param v */ public void playVideo(View v){ recordPlayIv.setVisibility(View.GONE); try { mediaPlayer=new MediaPlayer(); mediaPlayer.setDataSource(videoPath); mediaPlayer.setDisplay(surfaceHolder); mediaPlayer.prepareAsync(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalStateException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } mediaPlayer.setOnBufferingUpdateListener(this); mediaPlayer.setOnCompletionListener(this); mediaPlayer.setOnPreparedListener(this); mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); } /** * 开始录制/停止录制 * TODO * @param v */ public void recordVideo(View v){ if(isRecord){ isRecord=false; recordIv.setImageResource(R.drawable.video_recorder_start_btn_nor); recordPlayIv.setVisibility(View.VISIBLE); if (mediarecorder != null) { // 停止录制 mediarecorder.stop(); // 释放资源 mediarecorder.release(); mediarecorder = null; } if(camera!=null){ camera.release(); } }else{ isRecord=true; recordIv.setImageResource(R.drawable.video_recorder_recording_btn); recordPlayIv.setVisibility(View.GONE); mediarecorder = new MediaRecorder();// 创建mediarecorder对象 // // 从麦克风源进行录音 // mediarecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT); // // 设置输出格式 // mediarecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT); // // 设置编码格式 // mediarecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT); /** * 设置竖着录制 */ if(camera!=null){ camera.release(); } if(cameraPosition==1){ camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);//打开摄像头 // camera = Camera.open(cameraPosition);//打开摄像头 // Camera.Parameters parameters = camera.getParameters(); // camera.setDisplayOrientation(90); // camera.setParameters(parameters); camera=deal(camera); mediarecorder.setOrientationHint(90);//视频旋转90度 }else{ camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);//打开摄像头 Camera.Parameters parameters = camera.getParameters(); camera.setDisplayOrientation(90); camera.setParameters(parameters); mediarecorder.setOrientationHint(270);//视频旋转90度 } camera.unlock(); mediarecorder.setCamera(camera); // 设置录制视频源为Camera(相机) mediarecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); // 设置录制完成后视频的封装格式THREE_GPP为3gp.MPEG_4为mp4 mediarecorder .setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); // 设置录制的视频编码h263 h264 mediarecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); // 设置视频录制的分辨率。必须放在设置编码和格式的后面,否则报错 mediarecorder.setVideoSize(176, 144); // 设置录制的视频帧率。必须放在设置编码和格式的后面,否则报错 mediarecorder.setVideoFrameRate(20); mediarecorder.setPreviewDisplay(surfaceHolder.getSurface()); // 设置视频文件输出的路径 mediarecorder.setOutputFile(videoPath); 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(); } } } protected void setTitleStr(String str) { TextView titleText = (TextView) findViewById(R.id.common_title_text); titleText.setText(str.trim()); Button left_button=(Button)findViewById(R.id.left_button); left_button.setVisibility(View.VISIBLE); left_button.setText("返回"); left_button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub back(); } }); Button right_button=(Button)findViewById(R.id.right_button); right_button.setVisibility(View.VISIBLE); right_button.setText(""); right_button.setBackgroundResource(R.drawable.btn_video_switch_bg); right_button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub cameraCount=Camera.getNumberOfCameras(); if(isCameraBack){ isCameraBack=false; }else{ isCameraBack=true; } // SurfaceHolder holder = surfaceview.getHolder();// 取得holder // holder.addCallback(RecordActivity.this); // holder加入回调接口 // LogsUtil.i(TAG, "cameraCount="+cameraCount); int cameraCount = 0; CameraInfo cameraInfo = new CameraInfo(); cameraCount = Camera.getNumberOfCameras();//得到摄像头的个数 for(int i = 0; i < cameraCount; i++) { Camera.getCameraInfo(i, cameraInfo);//得到每一个摄像头的信息 if(cameraPosition == 1) { //现在是后置,变更为前置 if(cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {//代表摄像头的方位,CAMERA_FACING_FRONT前置 CAMERA_FACING_BACK后置 camera.stopPreview();//停掉原来摄像头的预览 camera.release();//释放资源 camera = null;//取消原来摄像头 camera = Camera.open(i);//打开当前选中的摄像头 try { deal(camera); camera.setPreviewDisplay(surfaceHolder);//通过surfaceview显示取景画面 } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } camera.startPreview();//开始预览 cameraPosition = 0; break; } } else { //现在是前置, 变更为后置 if(cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {//代表摄像头的方位,CAMERA_FACING_FRONT前置 CAMERA_FACING_BACK后置 camera.stopPreview();//停掉原来摄像头的预览 camera.release();//释放资源 camera = null;//取消原来摄像头 camera = Camera.open(i);//打开当前选中的摄像头 try { deal(camera); camera.setPreviewDisplay(surfaceHolder);//通过surfaceview显示取景画面 } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } camera.startPreview();//开始预览 cameraPosition = 1; break; } } } } }); } /** * 返回 *<b>function:</b> *@author cuiran *@createDate 2013-8-20 下午2:22:48 */ public void back(){ finish(); } public Camera deal(Camera camera){ //设置camera预览的角度,因为默认图片是倾斜90度的 camera.setDisplayOrientation(90); Size pictureSize=null; Size previewSize=null; Camera.Parameters parameters = camera.getParameters(); parameters.setPreviewFrameRate(5); //设置旋转代码 parameters.setRotation(90); // parameters.setPictureFormat(PixelFormat.JPEG); List<Size> supportedPictureSizes = SupportedSizesReflect.getSupportedPictureSizes(parameters); List<Size> supportedPreviewSizes = SupportedSizesReflect.getSupportedPreviewSizes(parameters); if ( supportedPictureSizes != null && supportedPreviewSizes != null && supportedPictureSizes.size() > 0 && supportedPreviewSizes.size() > 0) { //2.x pictureSize = supportedPictureSizes.get(0); int maxSize = 1280; if(maxSize > 0){ for(Size size : supportedPictureSizes){ if(maxSize >= Math.max(size.width,size.height)){ pictureSize = size; break; } } } WindowManager windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE); Display display = windowManager.getDefaultDisplay(); DisplayMetrics displayMetrics = new DisplayMetrics(); display.getMetrics(displayMetrics); previewSize = getOptimalPreviewSize( supportedPreviewSizes, display.getWidth(), display.getHeight()); parameters.setPictureSize(pictureSize.width, pictureSize.height); parameters.setPreviewSize(previewSize.width, previewSize.height); } camera.setParameters(parameters); return camera; } /* (non-Javadoc) * @see android.view.SurfaceHolder.Callback#surfaceChanged(android.view.SurfaceHolder, int, int, int) */ @Override public void surfaceChanged(SurfaceHolder holder, int arg1, int arg2, int arg3) { // TODO Auto-generated method stub // 将holder,这个holder为开始在oncreat里面取得的holder,将它赋给surfaceHolder surfaceHolder = holder; } private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) { final double ASPECT_TOLERANCE = 0.1; double targetRatio = (double) w / h; if (sizes == null) return null; Size optimalSize = null; double minDiff = Double.MAX_VALUE; int targetHeight = h; // 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) > ASPECT_TOLERANCE) 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; } /* (non-Javadoc) * @see android.view.SurfaceHolder.Callback#surfaceCreated(android.view.SurfaceHolder) */ @Override public void surfaceCreated(SurfaceHolder holder) { // TODO Auto-generated method stub surfaceHolder = holder; try { if(isCameraBack){ camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);//打开摄像头 }else{ camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);//打开摄像头 } //设置camera预览的角度,因为默认图片是倾斜90度的 camera.setDisplayOrientation(90); Size pictureSize=null; Size previewSize=null; Camera.Parameters parameters = camera.getParameters(); parameters.setPreviewFrameRate(5); //设置旋转代码 parameters.setRotation(90); // parameters.setPictureFormat(PixelFormat.JPEG); List<Size> supportedPictureSizes = SupportedSizesReflect.getSupportedPictureSizes(parameters); List<Size> supportedPreviewSizes = SupportedSizesReflect.getSupportedPreviewSizes(parameters); if ( supportedPictureSizes != null && supportedPreviewSizes != null && supportedPictureSizes.size() > 0 && supportedPreviewSizes.size() > 0) { //2.x pictureSize = supportedPictureSizes.get(0); int maxSize = 1280; if(maxSize > 0){ for(Size size : supportedPictureSizes){ if(maxSize >= Math.max(size.width,size.height)){ pictureSize = size; break; } } } WindowManager windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE); Display display = windowManager.getDefaultDisplay(); DisplayMetrics displayMetrics = new DisplayMetrics(); display.getMetrics(displayMetrics); previewSize = getOptimalPreviewSize( supportedPreviewSizes, display.getWidth(), display.getHeight()); parameters.setPictureSize(pictureSize.width, pictureSize.height); parameters.setPreviewSize(previewSize.width, previewSize.height); } camera.setParameters(parameters); camera.setPreviewDisplay(holder); camera.startPreview(); } catch (Exception e) { e.printStackTrace(); } } /* (non-Javadoc) * @see android.view.SurfaceHolder.Callback#surfaceDestroyed(android.view.SurfaceHolder) */ @Override public void surfaceDestroyed(SurfaceHolder arg0) { // TODO Auto-generated method stub if(camera!=null){ camera.release(); } surfaceview = null; surfaceHolder = null; if (surfaceHolder != null) { surfaceHolder=null; } if (mediarecorder != null) { mediarecorder=null; } if (mediaPlayer != null) { mediaPlayer.release(); mediaPlayer = null; } } /* (non-Javadoc) * @see android.media.MediaPlayer.OnCompletionListener#onCompletion(android.media.MediaPlayer) */ @Override public void onCompletion(MediaPlayer arg0) { // TODO Auto-generated method stub LogsUtil.i(TAG, "onCompletion"); if (mediaPlayer != null) { mediaPlayer.release(); mediaPlayer = null; } recordPlayIv.setVisibility(View.VISIBLE); } /* (non-Javadoc) * @see android.media.MediaPlayer.OnPreparedListener#onPrepared(android.media.MediaPlayer) */ @Override public void onPrepared(MediaPlayer arg0) { // TODO Auto-generated method stub mVideoWidth = mediaPlayer.getVideoWidth(); mVideoHeight = mediaPlayer.getVideoHeight(); if (mVideoWidth != 0 && mVideoHeight != 0) { /* 设置视频的宽度和高度 */ surfaceHolder.setFixedSize(mVideoWidth,mVideoHeight); /* 开始播放 */ mediaPlayer.start(); } } /* (non-Javadoc) * @see android.media.MediaPlayer.OnBufferingUpdateListener#onBufferingUpdate(android.media.MediaPlayer, int) */ @Override public void onBufferingUpdate(MediaPlayer player, int arg1) { // TODO Auto-generated method stub } }
布局文件代码:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout android:orientation="vertical" android:layout_width="fill_parent" android:background="@drawable/login_bj" android:layout_height="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android"> <include android:id="@+id/Title" android:layout_alignParentTop="true" android:layout_width="fill_parent" android:layout_height="wrap_content" layout="@layout/layout_common_title"/> <LinearLayout android:layout_below="@+id/Title" android:layout_above="@+id/recordBtn" android:layout_width="fill_parent" android:layout_height="fill_parent" android:padding="30dp" > <SurfaceView android:id="@+id/surfaceview" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </LinearLayout> <RelativeLayout android:id="@+id/videoPlay" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center" > <ImageView android:src="@drawable/btn_video_play_bg" android:id="@+id/recordPlayIv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:clickable="true" android:onClick="playVideo" android:visibility="gone" /> </RelativeLayout> <RelativeLayout android:id="@+id/recordBtn" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center" android:layout_alignParentBottom="true"> <ImageView android:src="@drawable/video_recorder_start_btn_nor" android:id="@+id/recordIv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:clickable="true" android:onClick="recordVideo" /> </RelativeLayout> </RelativeLayout>
这里还有一些地方需要完善,在录制完成后切换会出现问题。由于时间关系这边还没去处理,在后续会进行处理,
此代码采用的sdk是17,由于在android 2.2上录制视频是横着,所以采用了高点的sdk
代码:这里
标签:
原文地址:http://www.cnblogs.com/zhujiabin/p/4218209.html