package com.frank.live.stream; import android.app.Activity; import android.content.Context; import android.graphics.Point; import android.graphics.SurfaceTexture; import android.util.Log; import android.util.Size; import android.view.Surface; import android.view.SurfaceHolder; import android.view.TextureView; import android.view.View; import com.frank.live.camera.Camera2Helper; import com.frank.live.camera.Camera2Listener; import com.frank.live.listener.OnFrameDataCallback; import com.frank.live.param.VideoParam; /** * Pushing video stream: using Camera2 * Created by frank on 2020/02/12. */ public class VideoStreamNew extends VideoStreamBase implements TextureView.SurfaceTextureListener, Camera2Listener { private static final String TAG = VideoStreamNew.class.getSimpleName(); private int rotation = 0; private boolean isLiving; private Size previewSize; private final Context mContext; private Camera2Helper camera2Helper; private final VideoParam mVideoParam; private final TextureView mTextureView; private final OnFrameDataCallback mCallback; public VideoStreamNew(OnFrameDataCallback callback, View view, VideoParam videoParam, Context context) { this.mCallback = callback; // just support TextureView now this.mTextureView = (TextureView) view; this.mVideoParam = videoParam; this.mContext = context; mTextureView.setSurfaceTextureListener(this); } /** * start previewing */ private void startPreview() { if (mContext instanceof Activity) { rotation = ((Activity) mContext).getWindowManager().getDefaultDisplay().getRotation(); } camera2Helper = new Camera2Helper.Builder() .cameraListener(this) .specificCameraId(Camera2Helper.CAMERA_ID_BACK) .context(mContext.getApplicationContext()) .previewOn(mTextureView) .previewViewSize(new Point(mVideoParam.getWidth(), mVideoParam.getHeight())) .rotation(rotation) .rotateDegree(getPreviewDegree(rotation)) .build(); camera2Helper.start(); } @Override public void setPreviewDisplay(SurfaceHolder surfaceHolder) { } @Override public void switchCamera() { if (camera2Helper != null) { camera2Helper.switchCamera(); } } @Override public void startLive() { isLiving = true; } @Override public void stopLive() { isLiving = false; } @Override public void release() { if (camera2Helper != null) { camera2Helper.stop(); camera2Helper.release(); camera2Helper = null; } } /** * stop previewing */ private void stopPreview() { if (camera2Helper != null) { camera2Helper.stop(); } } @Override public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { Log.i(TAG, "onSurfaceTextureAvailable..."); startPreview(); } @Override public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { } @Override public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { Log.i(TAG, "onSurfaceTextureDestroyed..."); stopPreview(); return false; } @Override public void onSurfaceTextureUpdated(SurfaceTexture surface) { } /** * Camera2 preview frame data * * @param yuvData data of yuv */ @Override public void onPreviewFrame(byte[] yuvData) { if (isLiving && mCallback != null) { mCallback.onVideoFrame(yuvData, 2); } } private int getPreviewDegree(int rotation) { switch (rotation) { case Surface.ROTATION_0: return 90; case Surface.ROTATION_90: return 0; case Surface.ROTATION_180: return 270; case Surface.ROTATION_270: return 180; default: return -1; } } @Override public void onCameraOpened(Size previewSize, int displayOrientation) { Log.i(TAG, "onCameraOpened previewSize=" + previewSize.toString()); this.previewSize = previewSize; updateVideoCodecInfo(getPreviewDegree(rotation)); } @Override public void onCameraClosed() { Log.i(TAG, "onCameraClosed"); } @Override public void onCameraError(Exception e) { Log.e(TAG, "onCameraError=" + e.toString()); } @Override public void onPreviewDegreeChanged(int degree) { updateVideoCodecInfo(degree); } private void updateVideoCodecInfo(int degree) { camera2Helper.updatePreviewDegree(degree); if (mCallback != null && mVideoParam != null) { int width = previewSize.getWidth(); int height = previewSize.getHeight(); if (degree == 90 || degree == 270) { int temp = width; width = height; height = temp; } mCallback.onVideoCodecInfo(width, height, mVideoParam.getFrameRate(), mVideoParam.getBitRate()); } } }