Android多媒體--通過SurfaceView錄像並存儲

  • 程序的簡單邏輯就是當我們開啓程序的時候,會在相應的surfaceView顯示當前攝像頭所顯示的內容(此刻我們還沒有開始錄製),當我們點擊錄製,程序就開始錄製視頻了,當我們點擊結束的時候,就自動將錄製的視頻保存到提前設定好的目錄中。同時將surfaceView繼續保持攝像頭的預覽的內容。
public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private Button button, button2;
    private SurfaceView surfaceView;
    private MediaRecorder mediaRecorder;
    private String path;
    private Camera camera;
    private SurfaceHolder.Callback callback;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();
        initSurfaceView();
    }

    private void initSurfaceView() {

        surfaceView = (SurfaceView) findViewById(R.id.surfaceView);
        surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        surfaceView.setKeepScreenOn(true);
        callback = new SurfaceHolder.Callback() {

            //在控件創建的時候,進行相應的初始化工作
            public void surfaceCreated(SurfaceHolder holder) {
                //打開相機,同時進行各種控件的初始化mediaRecord等
                camera = Camera.open();
                mediaRecorder = new MediaRecorder();
            }

            //當控件發生變化的時候調用,進行surfaceView和camera進行綁定,可以進行畫面的顯示
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
                doChange(holder);
            }

            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
            }

        };
        //爲SurfaceView設置回調函數
        surfaceView.getHolder().addCallback(callback);
    }

    //當我們的程序開始運行,即使我們沒有開始錄製視頻,我們的surFaceView中也要顯示當前攝像頭顯示的內容
    private void doChange(SurfaceHolder holder) {
        try {
            camera.setPreviewDisplay(holder);
            //設置surfaceView旋轉的角度,系統默認的錄製是橫向的畫面,把這句話註釋掉運行你就會發現這行代碼的作用
            camera.setDisplayOrientation(getDegree());
            camera.startPreview();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public int getDegree() {
        //獲取當前屏幕旋轉的角度
        int rotating = this.getWindowManager().getDefaultDisplay().getRotation();
        int degree = 0;
        //根據手機旋轉的角度,來設置surfaceView的顯示的角度
        switch (rotating) {
            case Surface.ROTATION_0:
                degree = 90;
                break;
            case Surface.ROTATION_90:
                degree = 0;
                break;
            case Surface.ROTATION_180:
                degree = 270;
                break;
            case Surface.ROTATION_270:
                degree = 180;
                break;
        }
        return degree;
    }

    private void init() {
        button = (Button) findViewById(R.id.button);
        button2 = (Button) findViewById(R.id.button2);

        button.setOnClickListener(this);
        button2.setOnClickListener(this);

        path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/hello.3gp";
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.button:
                startRecord();
                break;
            case R.id.button2:
                stopRecord();
                break;
        }
    }

    private void stopRecord() {
        //當結束錄製之後,就將當前的資源都釋放
        mediaRecorder.release();
        camera.release();
        mediaRecorder = null;
        //然後再重新初始化所有的必須的控件和對象
        camera = Camera.open();
        mediaRecorder = new MediaRecorder();
        doChange(surfaceView.getHolder());
    }

    private void startRecord() {
        //先釋放被佔用的camera,在將其設置爲mediaRecorder所用的camera
        camera.unlock();
        mediaRecorder.setCamera(camera);

        mediaRecorder.setPreviewDisplay(surfaceView.getHolder().getSurface());
        //設置音頻的來源  麥克風
        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        //設置視頻的來源
        mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
        //設置視頻的輸出格式  3gp
        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        //設置視頻中的聲音和視頻的編碼格式
        mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
        //設置保存的路徑
        mediaRecorder.setOutputFile(path);
        //開始錄製
        try {
            mediaRecorder.prepare();
            mediaRecorder.start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  • 由於模擬器無法實現錄製視頻的功能,這裏就不再截圖貼出了,請自行嘗試效果。

  • 這是一個簡單的demo,其中會存在一些小bug,比如當我們的程序切換到後臺就會報錯,是因爲我並未處理這些邏輯,僅僅是實現了錄像功能的一個demo,有興趣的再自己完善吧。

  • 如果想錄制完畢後播放剛纔錄製的視頻,請參看Android多媒體–音視頻播放,裏面講解了如何播放音視頻的操作。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章