本人两部手机5.1和6.0系统,亲测可用~~~~花了几个小时踩坑,希望大家少走弯路
先上权限,记住开权限
<!--权限--> <uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-feature android:name="android.hardware.camera" />这里要记得锁死横屏,不然就要设置角度为90度
<activity android:name=".VideoActivity" android:configChanges="layoutDirection|screenSize|screenLayout|keyboard|keyboardHidden" android:screenOrientation="landscape"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>下面是正式的代码
布局:
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <SurfaceView android:id="@+id/video_surface" android:layout_width="match_parent" android:layout_height="match_parent" /> <ToggleButton android:id="@+id/start_btn" android:layout_width="60dp" android:layout_height="60dp" /> </FrameLayout>活动:
/** * 2017/4/28 17:17 * Created by jiangchen * 作用:视频录制Activity */ public class VideoActivity extends Activity{ private SurfaceView videoSurface; //显示 private ToggleButton startBtn; //开始结束按钮 private MediaRecorder mediarecorder; // 录制视频的类 SurfaceHolder mholder; //holder Camera camera; //camera @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //去标题栏 requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_video); //实例化控件 videoSurface = (SurfaceView) findViewById(R.id.video_surface); startBtn = (ToggleButton) findViewById(R.id.start_btn); mholder = videoSurface.getHolder(); // 取得holder mholder.setFixedSize(1280,720); mholder.addCallback(surfaceCallback); // holder加入回调接口 // setType必须设置,要不出错.设置缓冲类型 mholder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); startBtn.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (isChecked){ try { //prepare()必须在start之前 /** *2017/4/29 15:00 *Created by jiangchen *官方API: * A common case of using MediaRecorder to record audio works as follows: MediaRecorder recorder = new MediaRecorder(); recorder.setAudioSource(MediaRecorder.AudioSource.MIC); recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); recorder.setOutputFile(PATH_NAME); recorder.prepare(); recorder.start(); // Recording is now started ... recorder.stop(); recorder.reset(); // You can reuse the object by going back to setAudioSource() step recorder.release(); // Now the object cannot be reused */ /**prepare() * This method must be called after setting up * the desired audio and video sources, encoders, file format, etc., but before start() * 必须在设置资源、编码方式、路径之后,必须在start方法之前 */ mediarecorder.prepare(); mediarecorder.start(); } catch (Exception e) { Log.e("jiangchen", "onCheckedChanged: "+e.toString() ); } }else { mediarecorder.stop(); mediarecorder.release(); mediarecorder=null; mholder.removeCallback(surfaceCallback);finish(); } } }); } /** * SurfaceHolder回调函数。重写SurfaceHolder.Callback接口的surfaceCreated、surfaceChanged、surfaceDestroyed方法。 */ SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() { public void surfaceCreated(SurfaceHolder holder) { mediarecorder = new MediaRecorder(); //这设置之后不容易崩 mediarecorder.setOnErrorListener(null); mediarecorder.setOnInfoListener(null); mediarecorder.setPreviewDisplay(null); camera = Camera.open(); //打开摄像头 Log.e("--------", "surfaceCreated"); try { // camera.setDisplayOrientation(90); //设置camera预览的角度,因为默认图片是倾斜90度的 camera.setPreviewDisplay(holder); //设置holder主要是用于surfaceView的图片的实时预览,以及获取图片等功能 Camera.Parameters parameters = camera.getParameters(); camera.setParameters(parameters); camera.startPreview(); //开始预览 camera.unlock(); } catch (IOException e) { camera.release(); //释放 } mediarecorder.setCamera(camera); mediarecorder.reset(); mediarecorder.setPreviewDisplay(holder.getSurface()); // 设置录制视频源为Camera(相机) mediarecorder.setAudioSource(MediaRecorder.AudioSource.MIC); mediarecorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT); // 设置录制完成后视频的封装格式THREE_GPP为3gp.MPEG_4为mp4 mediarecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); // 设置录制的视频编码 mediarecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP); mediarecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); // 设置视频录制的分辨率。必须放在设置编码和格式的后面,否则报错,而且这个值要适配 //手机,不然也会在后面stop方法报错! mediarecorder.setVideoSize(1280,720); // 设置录制的视频帧率。必须放在设置编码和格式的后面,否则报错,这样设置变清晰 mediarecorder.setVideoEncodingBitRate(5*1024*1024); mediarecorder.setOutputFile(Environment.getExternalStorageDirectory().getAbsolutePath()+ File.separator +"VisitInsData" + File.separator + "video.mp4"); } public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } public void surfaceDestroyed(SurfaceHolder holder) { //释放资源 camera.lock(); camera.stopPreview(); // stop preview camera.release(); // Release camera resources camera = null; mediarecorder.release(); mediarecorder=null; } };@Override protected void onStop() { super.onStop();//退出释放资源 if (camera!=null){ camera.release(); camera=null; } if (mediarecorder!=null){ mediarecorder.release(); mediarecorder=null; } if (mholder!=null){ mholder.removeCallback(surfaceCallback); } }}