+1

MediaRecorder and Camera in Android

Như chúng ta đã biết, ở bài trước chúng ta sử dụng MediaPlayer để chơi nhạc và video trong Android. Bài này, chúng ta sẽ tiếp tục với việc sử dụng MediaRecorder để ghi âm và sử dụng Camera để chụp màn hình, quay video.

I) MediaRecorder

Android cung cấp cho chúng ta lớp MediaRecorder để sử dụng trong việc ghi âm hoặc quay video thông qua mic và camera của thiết bị. Để ghi âm hay quay video thì trước tiên chúng ta phải khởi tạo các giá trị thích hợp cho MediaRecorder rồi sau đó gọi lệnh prepare()start() để chạy. Thông thường đối với việc sử dụng Mic để ghi âm thì ta có các khởi tạo sau

MediaRecorder myAudioRecorder = new MediaRecorder();
myAudioRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
myAudioRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
myAudioRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);
myAudioRecorder.setOutputFile(outputFile);

Như các dòng lệnh trên, ta thấy việc chuẩn bị để ghi âm một file cần phải cài source là mic, format file dưới dạng “3gp” và encode dưới dạng “amr” và cài đặt tên file (bao gồm cả đường dẫn tới thư mục chứa file).

Một số hàm cơ bản của MediaRecorder

  • setAudioSource() cài đặt nguồn để ghi âm (mic)
  • setVideoSource() cài đặt nguồn để quay video (camera)
  • setOutputFormat() cài đặt định dạng đầu ra của file.
  • setAudioEncoder() cài đặt encoder của file đầu ra.
  • setOutputFile() cài đặt tên và vị trí của file đầu ra sau khi ghi xong (vd: "/home/itachi/output.mp4")
  • stop() dừng việc recoding.
  • release() giải phóng bộ nhớ cho đối tượng.

Chỉ với đối tường là MediaRecorder chúng ta có thể dễ dàng tạo một file ghi âm và sử dụng MediaPlayer để mở nó lên. Muốn sử dụng dụng mic để ghi âm và lưu file thì chúng ta cần phải thêm các quyền sau cho ứng dụng (quyền ghi file và quyền ghi âm).

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

Các câu lệnh đầy đủ để ghi âm một file và lưu dưới dạng “3gp” là:

  • Khởi tạo đối tượng MediaRecorder
    String outputFile = Environment.getExternalStorageDirectory().getAbsolutePath() + "/recording.3gp";
    myAudioRecorder=new MediaRecorder();
    myAudioRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    myAudioRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
    myAudioRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);
    myAudioRecorder.setOutputFile(outputFile);
  • Bắt đầu ghi âm
    myAudioRecorder.prepare();
    myAudioRecorder.start();
  • Dừng quay
    myAudioRecorder.stop();
    myAudioRecorder.release();
    myAudioRecorder  = null;
  • Sử dụng MediaPlayer để chơi file ghi âm:
    MediaPlayer m = new MediaPlayer();
    m.setDataSource(outputFile);
    m.prepare();
    m.start();

Như vậy là chúng ta đã xong việc ghi âm và chơi file ghi âm với việc sử dụng MediaRecorder một cách rất đơn giản. Tiếp theo chúng ta sẽ đến với việc sử dụng camera để chụp màn hình và quay video.

II) Camera

Android cung cấp cho chúng ta 2 cách tiếp cận với camera.

  • Sử dụng ứng dụng camera có sẵn
  • Sử dụng trực tiếp Camera api

Đối với 2 cách này thì việc sử dụng camera có sẵn dễ dàng hơn rất nhiều nhưng ta lại khó có thể tùy chình giao diện và các thông số của video. Sử dụng api thì ta có thể linh hoạt hơn có thể tạo giao diện cho riêng mình, cài đặt chất lượng, format …của video.

1. Sử dụng ứng dụng Camera có sẵn

Việc sử dụng Camera có sẵn tương tự như việc gọi một Intent mới lên với các thông số phù hợp, các thông số này được cung cấp bởi lớp MediaStore.

  • ACTION_IMAGE_CAPTURE_SECURE trả về các hình ảnh được chụp từ máy ảnh, khi thiết bị được bảo đảm
  • ACTION_VIDEO_CAPTURE gọi ứng dụng video hiện có trong Android để chụp video
  • EXTRA_SCREEN_ORIENTATION thiết lập các định hướng của màn hình để dọc hay chiều ngang
  • EXTRA_FULL_SCREEN sử dụng để kiểm soát việc hiển thị ảnh với giao diện ngươi dùng
  • INTENT_ACTION_VIDEO_CAMERA khởi động máy ảnh ở chế độ video
  • EXTRA_SIZE_LIMIT giới hạn kích thước của video hoặc chụp ảnh kích thước

Do chúng ta sử dụng ứng dụng có sẵn của Android bằng cách tạo ra các Intent để khởi động chúng, vì vậy mà chúng ta cần phải nhận dữ liệu trả về từ chúng. Do vậy, ta phải sử dụng phương thức startActivityForResult() để khởi chạy chúng. Ví dụ với ứng dụng dùng để chụp ảnh và nhận dữ liệu ảnh trả về rồi hiển thị

  • Gọi ứng dụng camera để chụp ảnh
    Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
    startActivityForResult(intent, 0);
  • Nhận dữ liệu trả về và hiển thị lên
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
      // TODO Auto-generated method stub
      super.onActivityResult(requestCode, resultCode, data);

      Bitmap bp = (Bitmap) data.getExtras().get("data");
      ImageView iv=(ImageView)findViewById(R.id.imageView);
      iv.setImageBitmap(bp);
   }

2. Sử dụng trực tiếp Camera Api

Để sử dụng trực tiếp Camera api thì android cung cấp cho ta 2 đối tượng để thao tác

  • Camera: Dùng để quản lý, điều khiển camera (tắt, bật, âm lượng …)
  • SurfaceView: Dùng đề hiển thị video khi đang quay hay khi quay xong.

CAMERA

    Camera mcamera= Camera.open();
Các hàm cơ bản với đối tượng Camera:
  • getCameraInfo(int cameraId, Camera.CameraInfo cameraInfo) Nó trả về các thông tin về một máy ảnh đặc biệt
  • getNumberOfCameras() trả về một số nguyên số máy ảnh có sẵn trên thiết bị
  • lock() sử dụng để khóa máy ảnh để các ứng dụng khác không có thể sử dụng nó
  • release() giải phóng máy ảnh (các ứng dụng khác có thể sử dụng máy ảnh)
  • open(int cameraId) sử dụng để mở camera với id của nó
  • enableShutterSound(boolean enabled) sử dụng để bật / tắt âm thanh khi chụp

SurfaceView

Dưới dây là cấu trúc cần có của một SurfaceView hiển thị camera khi quay.

public class ShowCamera extends SurfaceView implements SurfaceHolder.Callback {
   private Camera theCamera;

   public void surfaceCreated(SurfaceHolder holder) {
      theCamera.setPreviewDisplay(holder);
      theCamera.startPreview();
   }

   public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3){
   }

   public void surfaceDestroyed(SurfaceHolder arg0) {
   }
}

Các bạn có thể sử dụng class trên để tạo một view cho Camera như trong bài viết sau http://www.tutorialspoint.com/android/android_camera.htm.

Mình thích sử dụng SurfaceView một cách trực tiếp hơn. Tiếp theo mình sẽ trình bày về cách làm của mình để hiển thị và quay video:

Tương tự như khi ghi âm, bạn cũng phải cài đặt và chuẩn bị đầy đủ cho MediaRecord như sau:

  • Khởi tạo MediaRecorder và SurfaceView
    SurfaceView surfaceView = (SurfaceView)findViewById(id.surfaceView);
    SurfaceHolder surfaceHolder = surfaceView.getHolder();
    MediaRecorder myAudioRecorder = new MediaRecorder();
  • Cài đặt các giá trị cho việc quay video.
        // Cài đặt camera
        mCamera = Camera.open();
        mCamera.unlock();
        myAudioRecorder.setCamera(mCamera);
        outputFilemp4 = Environment.getExternalStorageDirectory().getAbsolutePath() + "/recording4.mp4";
        myAudioRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
        myAudioRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
        myAudioRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
        //cài đặt output
        myAudioRecorder.setOutputFile(outputFilemp4);
        //Cài đặt preview
        surfaceView.setBackground(null);
        myAudioRecorder.setPreviewDisplay(surfaceHolder.getSurface());
        try {
           myAudioRecorder.prepare();
        } catch (IOException e) {
           e.printStackTrace();
        }

Việc còn lại ta chỉ cần gọi myAudioRecorder.start(); là xong.

Lưu ý

mCamera = Camera.open(); ở đây bạn có thể truyền tham số vào hàm open() để sử dụng camera mà bạn thích khi thiết bị của bạn có nhiều camera. Thông thường id của camera sẽ bắt đầu từ 1.

surfaceView.setBackground(null); việc cài đặt background của surfaceView về null là để có thể hiển thị hình ảnh trực tiếp của camera.

Như vậy ta đã có một video đang quay và ghi lại những hoạt động trước camera rồi. Việc tiếp theo là dừng lại và lưu lại vào file. Việc lưu lại vào file thì MediaRecorder sẽ tự động ghi vào file mà mình đã cài đặt trước ở trên. Nên ta chỉ cần dừng lại là được.

  • Stop quay video
    myAudioRecorder.stop();
    myAudioRecorder.reset();
    myAudioRecorder.release();
    mCamera.release();

Tại sao lại cần mCamera.release(); ở đây???

Vì: nếu bạn không giải phóng **camera** thì nó sẽ chiến dụng mất **surfaceView** trước đó. Cho dù bạn có sử dụng **surfaceView** vào việc phát lại video cũng không thể được. Trừ khi bạn sử dụng một **surfaceView** khác để phát lại video vừa quay.

Việc còn lại rất đơn giản, như ở bài trước mình đã đề cập là sử dụng surfaceView để phát video mà thôi.

    MediaPlayer m = new MediaPlayer();
    stop_video.setEnabled(false);
    play_video.setEnabled(true);
    surfaceView.setBackground(null);
    surfaceHolder = surfaceView.getHolder();
    m.setDisplay(surfaceHolder);
    try {
        m.setDataSource(outputFilemp4);
        m.setDisplay(surfaceHolder);
        m.prepare();
    }
    catch (IOException e) {
        e.printStackTrace();
    }
    m.start();

Source code:

https://github.com/banlv54/MonthlyReport-07-2015

Video demo

Tài liệu tham khảo

http://developer.android.com/guide/topics/media/camera.html http://www.tutorialspoint.com/android/android_camera.htm http://examples.javacodegeeks.com/android/core/hardware/camera-hardware/android-camera-example/


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí