zoukankan      html  css  js  c++  java
  • Android上实现视频录制

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

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

    如果还要使用一些硬件属性,那还要做额外的声明,例如:

    <uses-feature android:name="android.hardware.camera"/>
    <uses-feature:name="android.hardware.camera.autofocus"/>

    当我们在录制的时候,通常都想要看到我们正在拍什么,这就需要预览,而预览需要在一个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内的预览是另开线程做的,不知道是否会有改善?

  • 相关阅读:
    led呼吸灯
    定时器中断
    npgsql
    中断
    PAT (Advanced Level) 1128~1131:1128N皇后 1129 模拟推荐系统(set<Node>优化) 1130 中缀表达式
    PAT (Advanced Level) 1132~1135:1132 模拟 1133模拟(易超时!) 1134图 1135红黑树
    PAT (Advanced Level) 1136~1139:1136模拟 1137模拟 1138 前序中序求后序 1139模拟
    PAT (Advanced Level) 1140~1143:1140模拟 1141模拟 1142暴力 1143 BST+LCA
    PAT (Advanced Level) 1144~1147:1145Hash二次探查 1146拓扑排序 1147堆
    python实现http接口测试
  • 原文地址:https://www.cnblogs.com/zhujiabin/p/4182995.html
Copyright © 2011-2022 走看看