Android上实现视频录制

    技术2026-04-25  7

    尽管Google的SDK文档写到了相关的,内容但是实在是太短小精悍了,因为需要写个简单的Demo,所以学习了一下。

    现在,我们一起来看看,到底要怎么去写吧:

     

    首先,我们肯定要用到摄像头,因此需要在Manifest文件中声明使用权限:

    <uses-permission android:name="android.permission.CAMERA" />如果还要使用一些硬件属性,那还要做额外的声明,例如:

    <uses-feature android:name="android.hardware.camera"/><uses-feature:name="android.hardware.camera.autofocus"/>当然,你还想要录制音频的话,还得加上:

    <uses-permission android:name="android.permission.RECORD_AUDIO" />

    当我们在录制的时候,通常都想要看到我们正在拍什么,这就需要预览,而预览需要在一个SurfaceView上实现,因此我们要添加一个控件:

    <SurfaceView android:id="@+id/surface_camera" xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="fill_parent"android:layout_height="fill_parent"android:layout_centerInParent="true"android:layout_weight="1"></SurfaceView>然后,我们来实现这个Activity:

    public class CustomVideoCamera extends Activity implements SurfaceHolder.Callback{private static final String TAG = "CAMERA_TUTORIAL";private SurfaceView surfaceView;private SurfaceHolder surfaceHolder;private Camera camera;private boolean previewRunning;    @Override    public void onCreate(Bundle savedInstanceState) {            super.onCreate(savedInstanceState);            setContentView(R.layout.camera_surface);            surfaceView = (SurfaceView) findViewById(R.id.surface_camera);            surfaceHolder = surfaceView.getHolder();            surfaceHolder.addCallback(this);            surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);    }    @Override    public void surfaceCreated(SurfaceHolder holder) {         camera = Camera.open();         if (camera != null){             Camera.Parameters params = camera.getParameters();             camera.setParameters(params);         }         else {             Toast.makeText(getApplicationContext(), "Camera not available!", Toast.LENGTH_LONG).show();             finish();         }    }    @Override    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {    if (previewRunning){         camera.stopPreview();    }    Camera.Parameters p = camera.getParameters();    p.setPreviewSize(width, height);    p.setPreviewFormat(PixelFormat.JPEG);    camera.setParameters(p);    try {        camera.setPreviewDisplay(holder);        camera.startPreview();        previewRunning = true;    }    catch (IOException e) {        Log.e(TAG,e.getMessage());        e.printStackTrace();        }    }    @Override    public void surfaceDestroyed(SurfaceHolder holder) {          camera.stopPreview();          previewRunning = false;          camera.release();    }}接着,我们就可以录制了:

    private MediaRecorder mediaRecorder; private final int maxDurationInMs = 20000; private final long maxFileSizeInBytes = 500000; private final int videoFramesPerSecond = 20; public boolean startRecording(){      try {           camera.unlock();           mediaRecorder = new MediaRecorder();          mediaRecorder.setCamera(camera);           mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);           mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);           mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);           mediaRecorder.setMaxDuration(maxDurationInMs);           tempFile = new File(getCacheDir(),cacheFileName);           mediaRecorder.setOutputFile(tempFile.getPath());           mediaRecorder.setVideoFrameRate(videoFramesPerSecond);           mediaRecorder.setVideoSize(surfaceView.getWidth(), surfaceView.getHeight());           mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);           mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);          mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());           mediaRecorder.setMaxFileSize(maxFileSizeInBytes);          mediaRecorder.prepare();

              mediaRecorder.start();           return true;      } catch (IllegalStateException e) {           Log.e(TAG,e.getMessage());           e.printStackTrace();           return false;     } catch (IOException e) {           Log.e(TAG,e.getMessage());           e.printStackTrace();           return false;      } }停止拍摄,则:

    public void stopRecording(){    mediaRecorder.stop();    camera.lock();}

     

    这样的话,通过编译之后,在Android OS 2.1 和 2.2上都能实现了,但在部分机器上会有些小问题,主要是预览上,看到app内的预览是另开线程做的,不知道是否会有改善?

    最新回复(0)