You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
194 lines
5.3 KiB
194 lines
5.3 KiB
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());
|
|
}
|
|
}
|
|
|
|
}
|
|
|