Files
pdlivexp/live/src/main/java/com/yunbao/live/views/LivePushTxViewHolder.java
2023-08-18 17:43:13 +08:00

686 lines
28 KiB
Java

package com.yunbao.live.views;
import android.app.Dialog;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.tencent.liteav.device.TXDeviceManager;
import com.tencent.rtmp.ITXLivePushListener;
import com.tencent.rtmp.TXLiveConstants;
import com.tencent.rtmp.ui.TXCloudVideoView;
import com.tencent.trtc.TRTCCloud;
import com.tencent.trtc.TRTCCloudDef;
import com.tencent.trtc.TRTCCloudListener;
import com.yunbao.common.CommonAppConfig;
import com.yunbao.common.Constants;
import com.yunbao.common.bean.UserBean;
import com.yunbao.common.http.HttpCallback;
import com.yunbao.common.http.HttpClient;
import com.yunbao.common.utils.DialogUitl;
import com.yunbao.common.utils.DpUtil;
import com.yunbao.common.utils.L;
import com.yunbao.common.utils.ToastUtil;
import com.yunbao.live.R;
import com.yunbao.live.activity.LiveActivity;
import com.yunbao.common.http.LiveHttpConsts;
import com.yunbao.common.http.LiveHttpUtil;
import com.yunbao.live.momo.GenerateTestUserSig;
import com.yunbao.live.momo.TencentTRTCBeautyManager;
import com.yunbao.live.presenter.LiveLinkMicPkPresenter;
import com.yunbao.live.socket.SocketSendBean;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import static com.tencent.trtc.TRTCCloudDef.TRTC_APP_SCENE_LIVE;
import static com.tencent.trtc.TRTCCloudDef.TRTC_VIDEO_MIRROR_TYPE_DISABLE;
import static com.tencent.trtc.TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG;
/**
* Created by cxf on 2018/10/7.
* 腾讯云直播推流
*/
public class LivePushTxViewHolder extends AbsLivePushViewHolder implements ITXLivePushListener {
private int mMeiBaiVal;//基础美颜 美白
private int mMoPiVal;//基础美颜 磨皮
private int mHongRunVal;//基础美颜 红润
private String mBgmPath;//背景音乐路径
private Bitmap mFilterBmp;
public static TRTCCloud mTRTCCloud;
private TXDeviceManager mTXDeviceManager;
private TRTCCloudDef.TRTCParams mTRTCParams;
private Handler mMainHandler;
public TencentTRTCBeautyManager tencentTRTCBeautyManager;
public static Context contexts;
public static TextView btn_close;
public static LinearLayout dr_pk_view;
public LivePushTxViewHolder(Context context, ViewGroup parentView) {
super(context, parentView);
this.contexts = context;
}
@Override
protected int getLayoutId() {
return R.layout.view_live_push_tx;
}
@Override
public void init() {
super.init();
mPreView = (TXCloudVideoView) findViewById(R.id.camera_preview);
mPreView1 = (TXCloudVideoView) findViewById(R.id.camera_preview1);
dr1_preview = (TXCloudVideoView) findViewById(R.id.dr1_preview);
dr2_preview = (TXCloudVideoView) findViewById(R.id.dr2_preview);
dr3_preview = (TXCloudVideoView) findViewById(R.id.dr3_preview);
dr4_preview = (TXCloudVideoView) findViewById(R.id.dr4_preview);
leave = (ImageView) findViewById(R.id.leave);
dr_pk_view = (LinearLayout) findViewById(R.id.dr_pk_view);
dr_pk_view.setVisibility(View.GONE);
btn_close = (TextView) findViewById(R.id.btn_close);
mTRTCCloud = TRTCCloud.sharedInstance(mContext);
mMainHandler = new Handler(Looper.getMainLooper());
btn_close.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
DialogUitl.showSimpleDialog(mContext, "是否要斷開連麥?", new DialogUitl.SimpleCallback() {
@Override
public void onConfirmClick(Dialog dialog, String content) {
//断开连麦
HttpClient.getInstance().post("livepk.setliveuserout", "livepk.setliveuserout")
.execute(new HttpCallback() {
@Override
public void onSuccess(int code, String msg, String[] info) {
}
});
HttpClient.getInstance().get("Livepk.endPK", "Livepk.endPK")
.params("addtime", "00:00")
.params("type", "0")
.params("sign", "1")
.execute(new HttpCallback() {
@Override
public void onSuccess(int code, String msg, String[] info) {
if (code == 0) {
JSONObject datas = JSONObject.parseObject(info[0]);
String pkUid = datas.getString("pkuid");
SocketSendBean seed_msg = new SocketSendBean()
.param("_method_", Constants.SOCKET_LINK_MIC_PK)
.param("action", 9)
.param("msgtype", 10)
.param("win_uid", datas.getString("win_uid"))
.param("uid", CommonAppConfig.getInstance().getUid());
seed_msg.create();
Log.i("seed", seed_msg.mResult.toString());
if (LiveLinkMicPkPresenter.mTRTCCloud1 != null && LivePushTxViewHolder.mTRTCCloud != null) {
LiveLinkMicPkPresenter.mTRTCCloud1.stopRemoteView(pkUid);
LivePushTxViewHolder.mTRTCCloud.setMixTranscodingConfig(null);
LiveLinkMicPkPresenter.mTRTCCloud1.exitRoom();
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
params.topMargin = 0;
LivePushTxViewHolder.mPreView.setLayoutParams(params);
}
HttpClient.getInstance().get("Tx.sendmsgzs2", "Tx.sendmsgzs2")
.params("GroupId", "g" + pkUid)
.params("jsonstr", seed_msg.mResult.toString())
.execute(new HttpCallback() {
@Override
public void onSuccess(int code, String msg, String[] info) {
HttpClient.getInstance().get("Tx.sendmsgzs2", "Tx.sendmsgzs2")
.params("GroupId", "g" + CommonAppConfig.getInstance().getUid())
.params("jsonstr", seed_msg.mResult.toString())
.execute(new HttpCallback() {
@Override
public void onSuccess(int code, String msg, String[] info) {
SocketSendBean seed_msgs = new SocketSendBean()
.param("_method_", Constants.SOCKET_LINK_MIC_PK)
.param("action", 5)
.param("msgtype", 10)
.param("uname", "1")
.param("uimg", "1")
.param("pkuid", LiveLinkMicPkPresenter.oldmPkUid)
.param("uid", CommonAppConfig.getInstance().getUid());
seed_msgs.create();
Log.i("seed", seed_msgs.mResult.toString());
HttpClient.getInstance().get("Tx.sendmsgzs2", "Tx.sendmsgzs2")
.params("GroupId", "g" + LiveLinkMicPkPresenter.oldmPkUid)
.params("jsonstr", seed_msgs.mResult.toString())
.execute(new HttpCallback() {
@Override
public void onSuccess(int code, String msg, String[] info) {
HttpClient.getInstance().get("Tx.sendmsgzs2", "Tx.sendmsgzs2")
.params("GroupId", "g" + CommonAppConfig.getInstance().getUid())
.params("jsonstr", seed_msgs.mResult.toString())
.execute(new HttpCallback() {
@Override
public void onSuccess(int code, String msg, String[] info) {
}
});
}
});
}
});
}
});
}
}
});
}
});
}
});
mTXDeviceManager = mTRTCCloud.getDeviceManager();
mTRTCCloud.setListener(new TRTCCloudImplListener(mContext));
mTRTCCloud.setLocalVideoProcessListener(TRTCCloudDef.TRTC_VIDEO_PIXEL_FORMAT_Texture_2D,
TRTCCloudDef.TRTC_VIDEO_BUFFER_TYPE_TEXTURE,
new TRTCCloudListener.TRTCVideoFrameListener() {
@Override
public void onGLContextCreated() {
mMainHandler.post(new Runnable() {
@Override
public void run() {
tencentTRTCBeautyManager = new TencentTRTCBeautyManager(mContext);
}
});
}
@Override
public int onProcessVideoFrame(TRTCCloudDef.TRTCVideoFrame srcFrame, TRTCCloudDef.TRTCVideoFrame dstFrame) {
if (tencentTRTCBeautyManager != null) {
dstFrame.texture.textureId = tencentTRTCBeautyManager.renderWithTexture(srcFrame.texture.textureId, srcFrame.width, srcFrame.height, srcFrame.rotation == 270);
}
return 0;
}
@Override
public void onGLContextDestory() {
tencentTRTCBeautyManager.textureDestoryed();
}
});
enterRoom();
}
@Override
public void changeToLeft() {
if (mPreView != null) {
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) mPreView.getLayoutParams();
params.width = mPreView.getWidth() / 2;
params.height = DpUtil.dp2px(250);
params.topMargin = DpUtil.dp2px(130);
mPreView.setLayoutParams(params);
}
}
@Override
public void changeToBig() {
if (mPreView != null) {
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) mPreView.getLayoutParams();
params.width = ViewGroup.LayoutParams.MATCH_PARENT;
params.height = ViewGroup.LayoutParams.MATCH_PARENT;
params.topMargin = 0;
mPreView.setLayoutParams(params);
}
}
@Override
public void toggleCamera() {
if (mCameraFront) {
mCameraFront = false;
} else {
mCameraFront = true;
}
mTXDeviceManager.switchCamera(mCameraFront);
}
/**
* 打开关闭闪光灯
*/
@Override
public void toggleFlash() {
if (mCameraFront) {
ToastUtil.show(R.string.live_open_flash);
return;
}
// if (mLivePusher != null) {
// boolean open = !mFlashOpen;
// if (mLivePusher.turnOnFlashLight(open)) {
// mFlashOpen = open;
// }
// }
}
/**
* 开始推流
*
* @param pushUrl 推流地址
*/
@Override
public void startPush(String pushUrl) {
mTRTCCloud.enterRoom(mTRTCParams, TRTC_APP_SCENE_LIVE);
mTRTCCloud.startPublishing(getLiveStream(), TRTC_VIDEO_STREAM_TYPE_BIG);
startCountDown();
}
protected class TRTCCloudImplListener extends TRTCCloudListener {
private WeakReference<Context> mContext;
public TRTCCloudImplListener(Context context) {
super();
mContext = new WeakReference<>(context);
}
@Override
public void onRemoteUserEnterRoom(String s) {
TRTCCloudDef.TRTCTranscodingConfig config = new TRTCCloudDef.TRTCTranscodingConfig();
config.videoWidth = 960;
config.videoHeight = 540;
config.videoBitrate = 1500;
config.videoFramerate = 20;
config.videoGOP = 2;
config.audioSampleRate = 48000;
config.audioBitrate = 64;
config.audioChannels = 2;
config.streamId = LivePushTxViewHolder.getLiveStream();
config.mode = TRTCCloudDef.TRTC_TranscodingConfigMode_Manual;
config.mixUsers = new ArrayList<>();
// 主播自己
TRTCCloudDef.TRTCMixUser mixUser = new TRTCCloudDef.TRTCMixUser();
mixUser.userId = CommonAppConfig.getInstance().getUid();
mixUser.zOrder = 0;
mixUser.x = 0;
mixUser.y = 0;
mixUser.width = 480;
mixUser.height = 540;
// mixUser.roomId = CommonAppConfig.getInstance().getUid();
config.mixUsers.add(mixUser);
String uid = s;
String new_uid = uid.replace("pk", "");
Log.e("uid", new_uid);
//连麦者画面位置
TRTCCloudDef.TRTCMixUser remote = new TRTCCloudDef.TRTCMixUser();
remote.userId = new_uid;
remote.streamType = TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG;
remote.zOrder = 1;
remote.x = 480;
remote.y = 0;
remote.width = 480;
remote.height = 540;
remote.roomId = new_uid;
config.mixUsers.add(remote);
LivePushTxViewHolder.mTRTCCloud.setMixTranscodingConfig(config);
}
@Override
public void onRemoteUserLeaveRoom(String s, int i) {
Log.i("uid", "" + s);
}
@Override
public void onDisConnectOtherRoom(int i, String s) {
Log.d(TAG, "onConnectOtherRoom0: s = " + s + " , i = " + i);
}
@Override
public void onError(int errCode, String errMsg, Bundle extraInfo) {
Log.d(TAG, "sdk callback onError");
}
@Override
public void onStartPublishing(int err, String errMsg) {
super.onStartPublishing(err, errMsg);
Log.d(TAG, "1" + errMsg);
}
@Override
public void onStopPublishing(int err, String errMsg) {
super.onStopPublishing(err, errMsg);
Log.d(TAG, "2" + errMsg);
}
@Override
public void onSetMixTranscodingConfig(int err, String errMsg) {
super.onSetMixTranscodingConfig(err, errMsg);
Log.d(TAG, err + "3" + errMsg);
}
}
public void enterRoom() {
CommonAppConfig appConfig = CommonAppConfig.getInstance();
UserBean u = appConfig.getUserBean();
if (u == null) {
return;
}
mTRTCParams = new TRTCCloudDef.TRTCParams();
mTRTCParams.sdkAppId = GenerateTestUserSig.SDKAPPID;
mTRTCParams.userId = u.getId();
mTRTCParams.roomId = Integer.parseInt(u.getId());
mTRTCParams.userSig = GenerateTestUserSig.genTestUserSig(mTRTCParams.userId);
mTRTCParams.role = TRTCCloudDef.TRTCRoleAnchor;
TRTCCloudDef.TRTCRenderParams t = new TRTCCloudDef.TRTCRenderParams();
t.mirrorType = TRTC_VIDEO_MIRROR_TYPE_DISABLE;
mTRTCCloud.setLocalRenderParams(t);
mTRTCCloud.setVideoEncoderMirror(false);
TRTCCloudDef.TRTCVideoEncParam encParam = new TRTCCloudDef.TRTCVideoEncParam();
encParam.videoResolutionMode = TRTCCloudDef.TRTC_VIDEO_RESOLUTION_MODE_PORTRAIT; //设置分辨率模式为竖屏模式
encParam.videoFps = 14;
encParam.videoResolution = 540 * 960;
encParam.minVideoBitrate = 600;
encParam.videoBitrate = 1000;
mTRTCCloud.setVideoEncoderParam(encParam);
mTRTCCloud.startLocalPreview(mCameraFront, mPreView);
// Bitmap bitmap = decodeResource(mContext.getResources(), R.mipmap.bg_live_tx_pause);
mTRTCCloud.startLocalAudio(TRTCCloudDef.TRTC_AUDIO_QUALITY_DEFAULT);
}
@Override
public void onPause() {
mPaused = true;
}
@Override
public void onResume() {
mPaused = false;
}
@Override
public void startBgm(String path) {
mBgmPath = path;
}
@Override
public void pauseBgm() {
// if (mLivePusher != null) {
// mLivePusher.pauseBGM();
// }
}
@Override
public void resumeBgm() {
// if (mLivePusher != null) {
// mLivePusher.resumeBGM();
// }
}
@Override
public void stopBgm() {
// if (mLivePusher != null) {
// mLivePusher.stopBGM();
// }
mBgmPath = null;
}
@Override
protected void onCameraRestart() {
// if (mLivePusher != null && mPreView != null) {
// mLivePusher.startCameraPreview((TXCloudVideoView) mPreView);
// }
}
@Override
public void release() {
super.release();
LiveHttpUtil.cancel(LiveHttpConsts.LINK_MIC_TX_MIX_STREAM);
mTRTCCloud = null;
}
@Override
public void onPushEvent(int e, Bundle bundle) {
if (e == TXLiveConstants.PUSH_ERR_OPEN_CAMERA_FAIL) {
ToastUtil.show(R.string.live_push_failed_1);
} else if (e == TXLiveConstants.PUSH_ERR_OPEN_MIC_FAIL) {
ToastUtil.show(R.string.live_push_failed_2);
} else if (e == TXLiveConstants.PUSH_ERR_NET_DISCONNECT || e == TXLiveConstants.PUSH_ERR_INVALID_ADDRESS) {
L.e(TAG, "网络断开,推流失败------>");
} else if (e == TXLiveConstants.PUSH_WARNING_HW_ACCELERATION_FAIL) {
L.e(TAG, "不支持硬件加速------>");
// if (mLivePushConfig != null && mLivePusher != null) {
// mLivePushConfig.setHardwareAcceleration(TXLiveConstants.ENCODE_VIDEO_SOFTWARE);
// mLivePusher.setConfig(mLivePushConfig);
// }
} else if (e == TXLiveConstants.PUSH_EVT_FIRST_FRAME_AVAILABLE) {//预览成功
L.e(TAG, "mStearm--->初始化完毕");
if (mLivePushListener != null) {
mLivePushListener.onPreviewStart();
}
} else if (e == TXLiveConstants.PUSH_EVT_PUSH_BEGIN) {//推流成功
L.e(TAG, "mStearm--->推流成功");
if (!mStartPush) {
mStartPush = true;
if (mLivePushListener != null) {
mLivePushListener.onPushStart();
}
}
}
}
@Override
public void onNetStatus(Bundle bundle) {
}
private Bitmap decodeResource(Resources resources, int id) {
TypedValue value = new TypedValue();
resources.openRawResource(id, value);
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inTargetDensity = value.density;
return BitmapFactory.decodeResource(resources, id, opts);
}
/**
* 腾讯sdk连麦时候主播混流
*
* @param linkMicType 混流类型 1主播与主播连麦 0 用户与主播连麦
* @param toStream 对方的stream
*/
public void onLinkMicTxMixStreamEvent(int linkMicType, String toStream) {
String txAppId = getTxAppId();
String selfAnchorStream = getLiveStream();
if (TextUtils.isEmpty(txAppId) || TextUtils.isEmpty(selfAnchorStream)) {
return;
}
String mixParams = null;
if (linkMicType == Constants.LINK_MIC_TYPE_NORMAL) {
mixParams = createMixParams(txAppId, selfAnchorStream, toStream);
} else if (linkMicType == Constants.LINK_MIC_TYPE_ANCHOR) {
mixParams = createMixParams2(txAppId, selfAnchorStream, toStream);
}
if (TextUtils.isEmpty(mixParams)) {
return;
}
LiveHttpUtil.linkMicTxMixStream(mixParams);
}
/**
* 计算混流参数 观众与主播连麦
*
* @param txAppId 腾讯云appId
* @param selfAnchorStream 自己主播的stream
* @param toStream 对方的stream
* @return
*/
private String createMixParams(String txAppId, String selfAnchorStream, String toStream) {
JSONObject obj = new JSONObject();
long timestamp = System.currentTimeMillis() / 1000;
Log.d("timestamp3", "" + timestamp);
obj.put("timestamp", timestamp);
obj.put("eventId", timestamp);
JSONObject interFace = new JSONObject();
interFace.put("interfaceName", "Mix_StreamV2");
JSONObject para = new JSONObject();
para.put("app_id", txAppId);
para.put("interface", "mix_streamv2.start_mix_stream_advanced");
para.put("mix_stream_session_id", selfAnchorStream);
para.put("output_stream_id", selfAnchorStream);
JSONArray array = new JSONArray();
JSONObject mainAnchor = new JSONObject();//大主播
mainAnchor.put("input_stream_id", selfAnchorStream);
JSONObject mainLayoutParams = new JSONObject();
mainLayoutParams.put("image_layer", 1);
mainAnchor.put("layout_params", mainLayoutParams);
array.add(mainAnchor);
if (!TextUtils.isEmpty(toStream)) {
JSONObject smallAnchor = new JSONObject();//小主播
smallAnchor.put("input_stream_id", toStream);
JSONObject smallLayoutParams = new JSONObject();
smallLayoutParams.put("image_layer", 2);
smallLayoutParams.put("image_width", 0.25);
smallLayoutParams.put("image_height", 0.21);
smallLayoutParams.put("location_x", 0.75);
smallLayoutParams.put("location_y", 0.6);
smallAnchor.put("layout_params", smallLayoutParams);
array.add(smallAnchor);
}
para.put("input_stream_list", array);
interFace.put("para", para);
obj.put("interface", interFace);
Log.i("age1", obj.toString());
return obj.toString();
}
/**
* 计算混流参数 主播与主播连麦
*
* @param txAppId 腾讯云appId
* @param selfAnchorStream 自己主播的stream
* @param toStream 对方的stream
* @return
*/
private String createMixParams2(String txAppId, String selfAnchorStream, String toStream) {
JSONObject obj = new JSONObject();
long timestamp = System.currentTimeMillis() / 1000;
Log.d("timestamp4", "" + timestamp);
obj.put("timestamp", timestamp);
obj.put("eventId", timestamp);
JSONObject interFace = new JSONObject();
interFace.put("interfaceName", "Mix_StreamV2");
JSONObject para = new JSONObject();
para.put("app_id", txAppId);
para.put("interface", "mix_streamv2.start_mix_stream_advanced");
para.put("mix_stream_session_id", selfAnchorStream);
para.put("output_stream_id", selfAnchorStream);
JSONArray array = new JSONArray();
if (!TextUtils.isEmpty(toStream)) {
JSONObject bg = new JSONObject();//背景
bg.put("input_stream_id", "canvas1");//背景的id,这个字符串随便写
JSONObject bgLayoutParams = new JSONObject();
bgLayoutParams.put("image_layer", 1);
bgLayoutParams.put("input_type", 3);
bg.put("layout_params", bgLayoutParams);
array.add(bg);
JSONObject selfAnchor = new JSONObject();//自己主播
selfAnchor.put("input_stream_id", selfAnchorStream);
JSONObject selfLayoutParams = new JSONObject();
selfLayoutParams.put("image_layer", 2);
selfLayoutParams.put("image_width", 0.5);
selfLayoutParams.put("image_height", 0.5);
selfLayoutParams.put("location_x", 0);
selfLayoutParams.put("location_y", 0.25);
selfAnchor.put("layout_params", selfLayoutParams);
array.add(selfAnchor);
JSONObject toAnchor = new JSONObject();//对方主播
toAnchor.put("input_stream_id", toStream);
JSONObject toLayoutParams = new JSONObject();
toLayoutParams.put("image_layer", 3);
toLayoutParams.put("image_width", 0.5);
toLayoutParams.put("image_height", 0.5);
toLayoutParams.put("location_x", 0.5);
toLayoutParams.put("location_y", 0.25);
toAnchor.put("layout_params", toLayoutParams);
array.add(toAnchor);
} else {
JSONObject mainAnchor = new JSONObject();//大主播
mainAnchor.put("input_stream_id", selfAnchorStream);
JSONObject mainLayoutParams = new JSONObject();
mainLayoutParams.put("image_layer", 1);
mainAnchor.put("layout_params", mainLayoutParams);
array.add(mainAnchor);
}
para.put("input_stream_list", array);
interFace.put("para", para);
obj.put("interface", interFace);
Log.i("age2", obj.toString());
return obj.toString();
}
public static String getLiveStream() {
return ((LiveActivity) contexts).getStream();
}
private String getTxAppId() {
return ((LiveActivity) mContext).getTxAppId();
}
}