视频直播开篇之camera+surface预览

落爺英雄遲暮 提交于 2019-12-06 11:28:52

视频直播之开篇

现在各大网络的直播平台可是不少,但是大家知道视频直播是怎么做的吗?不懂的人可能认为应该和视频录制差不多。但是做android上面实现还是有很大的差别的。

在android上录制本地视频可以用MediaRecord传入相关参数,写入录制的地址,基本就ok了。但是对于视频直播就难一些,首先需要取到视频的数据,再经过硬件的编码,最后再上传。下面看看简单的实现步骤:

1.首先要进行视频的预览,一般预览有三个控件:surfaceview,GLSurfaceView,TextureView,这三个虽然使用方式上所有差别,但是最终都是要从surface上取数据的。由于android版本对camera部分的改版,在android21之前使用android.hardware.Camera,之后又加了android.hardware.camera2,实现起来有多种组合:

a.Camera+Surface

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:

   <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。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!