視頻直播開篇之camera+surface預覽

視頻直播之開篇

如今各大網絡的直播平臺但是很多,可是你們知道視頻直播是怎麼作的嗎?不懂的人可能認爲應該和視頻錄製差很少。可是作android上面實現仍是有很大的差異的。java

在android上錄製本地視頻能夠用MediaRecord傳入相關參數,寫入錄製的地址,基本就ok了。可是對於視頻直播就難一些,首先須要取到視頻的數據,再通過硬件的編碼,最後再上傳。下面看看簡單的實現步驟:android

1.首先要進行視頻的預覽,通常預覽有三個控件:surfaceview,GLSurfaceView,TextureView,這三個雖然使用方式上全部差異,可是最終都是要從surface上取數據的。因爲android版本對camera部分的改版,在android21以前使用android.hardware.Camera,以後又加了android.hardware.camera2,實現起來有多種組合:網絡

a.Camera+Surfaceapp

package com.example.amei.cameraexample;

import android.Manifest;
import android.content.pm.PackageManager;
import android.graphics.ImageFormat;
import android.hardware.Camera;
import android.hardware.Camera.Size;
import android.os.Build;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import java.io.IOException;
import java.util.List;

public class camera_surface_Activity extends AppCompatActivity {
   private static final String TAG = "camera_surface_Activity";
   private SurfaceView mSurfaceView = null;
   private Camera mCamera = null;
   private Camera.Parameters mParameters = null;
   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       checkPermission();
       setContentView(R.layout.activity_camera_surface);
       mSurfaceView = (SurfaceView)findViewById(R.id.surface_id);

       SurfaceHolder surfaceHolder = mSurfaceView.getHolder();
       surfaceHolder.addCallback(new SurfaceHolder.Callback() {
           @Override
           public void surfaceCreated(SurfaceHolder surfaceHolder) {
               Log.i(TAG,"surfaceCreated");
               openCamera();
               try {
                   mCamera.setPreviewDisplay(surfaceHolder);
               } catch (IOException e) {
                   e.printStackTrace();
               }
               mCamera.startPreview();
           }

           @Override
           public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
               Log.i(TAG,"surfaceChanged");


           }

           @Override
           public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
               Log.i(TAG,"surfaceDestroyed");
               if(mCamera != null)
               {
                   mCamera.release();
                   mCamera = null;
               }
           }
       });
   }
   private void openCamera()
   {
       if(mCamera == null){
           mCamera = android.hardware.Camera.open(0);
           mParameters = mCamera.getParameters();
           List<Camera.Size> list = mParameters.getSupportedPreviewSizes();
           mParameters.setPreviewFormat(ImageFormat.NV21);
           int PreviewWidth = list.get(0).width;
           int PreviewHeight = list.get(0).height;
           Log.i(TAG,"PreviewWidth = "+PreviewWidth+"  PreviewHeight = "+PreviewHeight);
           mParameters.setPreviewSize(PreviewWidth, PreviewHeight); // 設置預覽圖片大小



           mCamera.setParameters(mParameters);
       }
   }
   private void checkPermission() {
       if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
           String[] permissions = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA};
           for (String permission : permissions) {
               if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
                   ActivityCompat.requestPermissions(this, permissions, 200);
                   return;
               }
           }
       }
   }
}

layout裏面只有一個surface:ide

<SurfaceView
       android:id="@+id/surface_id"
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       app:layout_constraintBottom_toBottomOf="parent"
       app:layout_constraintLeft_toLeftOf="parent"
       app:layout_constraintRight_toRightOf="parent"
       app:layout_constraintTop_toTopOf="parent" />

首先是獲取相應的surfaceview,而且設置callback,只有在surface準備完成以後才能進行預覽,因此當surface建立成功以後纔去打開camera。ui

相關文章
相關標籤/搜索