1. 程式人生 > >Android 拍照和視訊錄製實現mediaRecorder

Android 拍照和視訊錄製實現mediaRecorder

手機一般都有麥克風和攝像頭,而Android系統就可以利用這些硬體來錄製音視訊了。

為了增加對錄製音視訊的支援,Android系統提供了一個MediaRecorder的類。該類可以實現拍照,視訊,播放錄音,攝像等功能, 該類的使用也非常簡單,下面讓我們來了解一下這個類

構造方法和公有方法:

Public Constructors

   MediaRecorder()

   Default constructor.

Public Methods

final static int getAudioSourceMax() 獲取音訊源的最大值。

int getMaxAmplitude() 獲取在前一次呼叫此方法之後錄音中出現的最大振幅。

void prepare() 準備錄製。

void release() 釋放資源。

void reset() 將MediaRecorder設為空閒狀態,即Initial狀態。

void setAudioChannels(int numChannels) 設定錄製的音訊通道數。

void setAudioEncoder(int audio_encoder) 設定所錄製的聲音的編碼格式。

void setAudioEncodingBitRate(int bitRate) 設定所錄製的聲音的編碼位率。

void setAudioSamplingRate(int samplingRate) 設定所錄製的聲音的取樣率。

void setAudioSource(int audio_source) 設定聲音來源,一般傳入 MediaRecorder. AudioSource.MIC引數指定錄製來自麥克風的聲音。

void setCamera(Camera c) 設定一個攝像頭用於錄製。

void setCaptureRate(double fps) 設定視訊幀捕獲率。

void setLocation(float latitude, float longitude) 設定並存儲在輸出檔案中的地理資料(經度和緯度)。

void setMaxDuration(int max_duration_ms) 設定錄製會話的最長持續時間(以ms為單位)。

void setMaxFileSize(long max_filesize_bytes) 設定錄製檔案的最大檔案大小。

void setOnErrorListener(MediaRecorder.OnErrorListener l) 註冊一個用於記錄錄製時出現的錯誤的監聽器。

void setOnInfoListener(MediaRecorder.OnInfoListener listener) 註冊一個用於記錄錄製時出現的資訊事件。

void setOrientationHint(int degrees) 設定輸出的視訊播放的方向提示。

void setOutputFile(FileDescriptor fd) 設定錄製的音訊檔案的儲存位置。

void setOutputFile(String path) 設定錄製的音訊檔案的儲存位置。

void setOutputFormat(int output_format) 設定所錄製的音視訊檔案的格式。

void setPreviewDisplay(Surface sv) 設定使用哪個SurfaceView來顯示視訊預覽。

void setProfile(CamcorderProfile profile) 指定CamcorderProfile物件。

void setVideoEncoder(int video_encoder) 設定所錄製視訊的編碼格式。

void setVideoEncodingBitRate(int bitRate) 設定所錄製視訊的編碼位率。

void setVideoFrameRate(int rate) 設定錄製視訊的捕獲幀速率。

void setVideoSize(int width, int height) 設定要拍攝的寬度和視訊的高度。

void setVideoSource(int video_source) 設定用於錄製的視訊來源。

void start() 開始錄製。

void stop() 停止錄製。

拍照程式碼實現:

  Manifest檔案增加拍照許可權
 <uses-permission android:name="android.permission.CAMERA" />
  java程式碼:
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class MainActivity extends AppCompatActivity {
    private Camera camera;
    private SurfaceView sfv_main_surface;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        sfv_main_surface = (SurfaceView) findViewById(R.id.sfv_main_surface);

        //接受攝像頭介面變化的資訊
        sfv_main_surface.getHolder().addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                //開啟照相機
                camera = Camera.open();
                // 給攝像頭設定引數
                Camera.Parameters parameters= camera.getParameters();
                //設定照片的格式
                parameters.setPictureFormat(PixelFormat.JPEG);
                parameters.set("jpeg_quality",85);
                // 給照相機設定引數
                camera.setParameters(parameters);
                //將畫面展示到SurfaceView
                try {
                    camera.setPreviewDisplay(sfv_main_surface.getHolder());
                } catch (IOException e) {
                    e.printStackTrace();
                }
                //開啟預覽效果
                camera.startPreview();
            }

            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
       //當預覽介面的格式和大小發生改變時,觸發
            }

            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
              //當拍好一個照之後,要讓camera重新重新整理畫面 不然將一定停留在拍照畫面
//                if(camera!=null){
//                    camera.stopPreview();
//                    camera.release();
//                    camera=null;
//                }
            }
        });

    }



    public void takePhoto(View view){
        camera.takePicture(null, null, new Camera.PictureCallback() {
            @Override
            public void onPictureTaken(byte[] data, Camera camera) {
                //圖片壓縮技術
                Bitmap bitmap= BitmapFactory.decodeByteArray(data,0,data.length);
                try {
                //圖片儲存的位置
                    FileOutputStream fos=new FileOutputStream("/mnt/sdcard/my_"+System.currentTimeMillis()+".png");
                    bitmap.compress(Bitmap.CompressFormat.PNG,85,fos);
                    camera.stopPreview();
                    camera.startPreview();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }


            }
        });

    }

}

xml程式碼:

 SurfaceView是專門放音訊檔案的控制元件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main"
    android:layout_width="match_parent" android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    tools:context="com.mdf_android01.android27_camera.MainActivity">

    <SurfaceView
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:id="@+id/sfv_main_surface"
        />

    <Button
        android:layout_marginTop="30dp"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:onClick="takePhoto"
        android:text="拍照"
        android:gravity="center"
        android:textSize="20sp"
        />
</LinearLayout>

視訊的錄製程式碼實現:

 Manifest檔案增加許可權
  <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
java程式碼:
import android.media.MediaRecorder;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.SurfaceView;
import android.view.View;

import java.io.IOException;

public class mediaRecorder extends AppCompatActivity {

    private SurfaceView sv_media_surface;
    private MediaRecorder mediaRecorder;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_media_recorder);

        sv_media_surface = (SurfaceView)findViewById(R.id.sv_media_surface);

        //例項化媒體錄製器
        mediaRecorder = new MediaRecorder();

    }

    public void start(View view) throws IOException {

        mediaRecorder.reset();
        mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        //設定格式
        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263);
        mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);

        //設定儲存的路徑

        mediaRecorder.setOutputFile("/mnt/sdcard/my_"+System.currentTimeMillis()+".mp4");
        mediaRecorder.setPreviewDisplay(sv_media_surface.getHolder().getSurface());


            mediaRecorder.prepare();
            mediaRecorder.start();
    }
    public void stop(View view){
        if(mediaRecorder!=null){
            mediaRecorder.stop();
            mediaRecorder.release();
            mediaRecorder=null;
        }
    }

}
xml程式碼:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_media_recorder"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    tools:context="com.mdf_android01.android27_camera.mediaRecorder">

    <SurfaceView
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:id="@+id/sv_media_surface"
        />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        >

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="開始"
            android:onClick="start"
            />


        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="停止"
            android:onClick="stop"
            />
    </LinearLayout>


</LinearLayout>