布局:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/activity_camera_vodeo" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/btn_start" android:layout_width="wrap_content" android:text="开启" android:layout_height="wrap_content" /> <Button android:id="@+id/btn_stop" android:text="停止" android:layout_below="@+id/btn_start" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <SurfaceView android:id="@+id/sv_view" android:layout_below="@+id/btn_stop" android:layout_width="match_parent" android:layout_height="match_parent" /> <!--<VideoView--> <!--android:layout_width="match_parent"--> <!--android:layout_height="wrap_content"--> <!--android:id="@+id/my_vv"--> <!--/>--> </RelativeLayout>
代码实现:
public class MainActivity extends AppCompatActivity { // private VideoView mVv; private RxPermissions permissions; private Button btn_VideoStart, btn_VideoStop; private SurfaceView sv_view; private boolean isRecording; private MediaRecorder mediaRecorder; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); permissions = new RxPermissions(this); btn_VideoStart = (Button) findViewById(R.id.btn_start); btn_VideoStop = (Button) findViewById(R.id.btn_stop); sv_view = (SurfaceView) findViewById(R.id.sv_view); btn_VideoStop.setEnabled(false); btn_VideoStart.setOnClickListener(click); btn_VideoStop.setOnClickListener(click); requestPermiss(); } private void requestPermiss() { permissions.request(Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO, Manifest.permission.CAMERA) .subscribe(new Consumer<Boolean>() { @Override public void accept(Boolean aBoolean) throws Exception { if (aBoolean) { } else { } } }); } private View.OnClickListener click = new View.OnClickListener() { @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_start: start(); break; case R.id.btn_stop: stop(); break; default: break; } } }; Camera camera; protected void start() { try { File file = new File("/sdcard/video.mp4"); if (file.exists()) { // 如果文件存在,删除它,演示代码保证设备上只有一个录音文件 file.delete(); } mediaRecorder = new MediaRecorder(); // 设置录制视频源为Camera(相机) camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK); if (camera != null) { // camera.setDisplayOrientation(90);//摄像图旋转90度 camera.setDisplayOrientation(90);//摄像图旋转90度 camera.unlock(); mediaRecorder.setCamera(camera); } mediaRecorder.reset(); // 设置音频录入源 mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); // 设置视频图像的录入源 mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); // 设置录入媒体的输出格式 mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); // 设置音频的编码格式 mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT); // 设置视频的编码格式 mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); mediaRecorder.setVideoEncodingBitRate(5 * 1024 * 1024); mediaRecorder.setVideoFrameRate(30); mediaRecorder.setVideoSize(640, 480); // 设置录制视频文件的输出路径 mediaRecorder.setOutputFile(file.getAbsolutePath()); // 设置捕获视频图像的预览界面 mediaRecorder.setPreviewDisplay(sv_view.getHolder().getSurface()); mediaRecorder.setOnErrorListener(new MediaRecorder.OnErrorListener() { @Override public void onError(MediaRecorder mr, int what, int extra) { // 发生错误,停止录制 mediaRecorder.stop(); mediaRecorder.release(); mediaRecorder = null; isRecording = false; btn_VideoStart.setEnabled(true); btn_VideoStop.setEnabled(false); Toast.makeText(MainActivity.this, "录制出错", Toast.LENGTH_SHORT).show(); } }); // 准备、开始 mediaRecorder.prepare(); mediaRecorder.start(); btn_VideoStart.setEnabled(false); btn_VideoStop.setEnabled(true); isRecording = true; Toast.makeText(MainActivity.this, "开始录像", Toast.LENGTH_SHORT).show(); } catch (Exception e) { e.printStackTrace(); } } protected void stop() { if (isRecording) { // 如果正在录制,停止并释放资源 mediaRecorder.stop(); mediaRecorder.release(); mediaRecorder = null; isRecording = false; btn_VideoStart.setEnabled(true); btn_VideoStop.setEnabled(false); Toast.makeText(MainActivity.this, "停止录像,并保存文件", Toast.LENGTH_SHORT).show(); } }
注意的问题:
1,视频录制时预览界面角度问题
这个是在开发过程中实际遇到的问题,我网上找了一下,刚开始以为是哪个参数没有设置导致的,但是看网友也有类似的反应,明明是竖屏录制的,但是界面确实横屏,在给mediarecorder设置mRecorder.setOrientationHint(90);也无济于事,后来,必须得设置Camera的预览角度才行,也就是这行代码:camera.setDisplayOrientation(90);这样再进行测试,摄像机的预览角度终于是竖屏的了,并且保存的文件播放时也是竖屏的
2,java.lang.RuntimeException: start failed
这种情况一般是参数设置的问题,比如mediaRecorder.setVideoFrameRate(4);设置为4就会出问题,设置成mediaRecorder.setVideoFrameRate(30);重新运行就好了
3,视频录制模糊,或者录制清晰播放模糊
mediaRecorder.setVideoEncodingBitRate(5 * 1024 * 1024); mediaRecorder.setVideoFrameRate(30); mediaRecorder.setVideoSize(640, 480);//设置这三个参数就可以了