全栈工程师开发手册 (作者:栾鹏)
安卓录制视频需要使用MediaRecorder来完成。并且在录制中一般还需要SurfaceHolder进行实时预览,所以在布局文件中进行预览的SurfaceView控件
启动和释放相机
private Camera camera;
//重写窗口函数,启动摄像头,并直接设置到录像模式
@Override
protected void onResume() {
super.onResume();
camera = Camera.open(); //启动相机
camera.setDisplayOrientation(90); //设置方向
//使用摄像头录制提示,告诉摄像头你只想录制音频/视频,而不是拍摄静态图片,可以缩短启动时间
Camera.Parameters parameters = camera.getParameters();
parameters.setRecordingHint(true);
camera.setParameters(parameters);
}
//重写窗口函数,释放 mediaRecorder
@Override
protected void onPause() {
super.onPause();
//重置和释放 mediaRecorder
mediaRecorder.reset();
mediaRecorder.release();
camera.lock();
//释放摄像头
camera.release();
}
MediaRecorder准备工作、SurfaceView预览录像
由于MediaRecorder负责接收相机数据源。与拍照预览不同,要实现录像的实时预览,必须将SurfaceView绑定到MediaRecorder的数据流中,而不是绑定到相机。
所以实现SurfaceHolder.Callback接口函数surfaceCreated执行以后才可以创建MediaRecorder,并将其绑定到相机,设置视频源、音频源、画质,输出地址等参数,在设置SurfaceView为预览控件,并准备录制
public class VideoCameraActivity extends Activity implements SurfaceHolder.Callback {
private Camera camera;
private SurfaceHolder holder;
private MediaRecorder mediaRecorder;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.videocamera);
SurfaceView surface = (SurfaceView)findViewById(R.id.video_surfaceView);
SurfaceHolder holder = surface.getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
holder.setFixedSize(400, 300);
}
//创建MediaRecorder绑定到相机,设置视频源、音频源、画质,输出地址等参数,并准备录制
private void prepareVideoCamera() throws IllegalStateException, IOException {
//创建一个新的MediaRecorder
mediaRecorder = new MediaRecorder();
//录制前的准备工作
//解锁摄像头并将其分配给MediaRecorder
camera.unlock();
mediaRecorder.setCamera(camera);
//指定用于录制的输入源
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
//设置配置文件,或者定义输出格式,音频视频编码器,帧速以及输出尺寸
CamcorderProfile profile = null;
if (CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_1080P))
profile = CamcorderProfile.get(CamcorderProfile.QUALITY_1080P);
else if (CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_720P))
profile = CamcorderProfile.get(CamcorderProfile.QUALITY_720P);
else if (CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_480P))
profile = CamcorderProfile.get(CamcorderProfile.QUALITY_480P);
else if (CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_HIGH))
profile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
if (profile != null)
mediaRecorder.setProfile(profile);
//指定一个输出文件
mediaRecorder.setOutputFile("/sdcard/myvideorecording.mp4");
//预览视频流,在指定了录制源和输出文件后,在prepare前设置
mediaRecorder.setPreviewDisplay(holder.getSurface());
//准备录制
mediaRecorder.prepare();
}
//接口函数
public void surfaceCreated(SurfaceHolder holder) {
this.holder = holder;
try {
prepareVideoCamera(); //准备好MediaRecorder接收相机视频音频源
Log.v("相机录像", "启动录制");
} catch (IllegalStateException e) {
Log.e("相机录像", "Illegal State Exception", e);
} catch (IOException e) {
Log.e("相机录像", "I/O Exception", e);
}
}
//接口函数
public void surfaceDestroyed(SurfaceHolder holder) {
this.holder = null;
}
//接口函数
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
}
mediaRecorder开始录制
准备工作做好以后,开始录制就非常简单了。
//开始录制
private void startRecording() {
try {
mediaRecorder.start();
Log.v("相机录像", "开始录制");
} catch (IllegalStateException e) {
mediaRecorder.release();
camera.lock();
Log.d("相机录像", "Illegal State Exception", e);
}
}
mediaRecorder停止录制
//停止录像
private void stopRecording() {
mediaRecorder.stop();
//重置和释放 mediaRecorder
mediaRecorder.reset();
mediaRecorder.release();
camera.lock();
Log.v("相机录像", "停止录制,文件已保存");
}