AliVCSDK  6.0.0
阿里云音视频SDK,为视频开发者提供一站式接入服务
AlivcLivePusherBasicImpl.java
1 package com.alivc.live.pusher;
2 
6 import static com.alivc.live.pusher.AlivcLivePushError.ALIVC_FRAMEWORK_RENDER_FIRST_FRAME_PREVIEWED;
7 import static com.alivc.live.pusher.AlivcLivePushError.ALIVC_LIVE_ERROR_SYSTEM_RTMP_OOM;
8 import static com.alivc.live.pusher.AlivcLivePushError.ALIVC_PUSHER_ERROR_BGM_OPEN_FAILED;
9 import static com.alivc.live.pusher.AlivcLivePushError.ALIVC_PUSHER_ERROR_BGM_TIMEOUT;
10 import static com.alivc.live.pusher.AlivcLivePushError.ALIVC_PUSHER_ERROR_SDK_LIVE_PUSH_LOW_PERFORMANCE;
11 import static com.alivc.live.pusher.AlivcLivePushError.ALIVC_PUSHER_ERROR_SDK_LIVE_PUSH_NETWORK_TOO_POOR;
12 import static com.alivc.live.pusher.AlivcLivePushError.ALIVC_PUSHER_ERROR_SDK_PUSH_CONNECT;
13 import static com.alivc.live.pusher.AlivcLivePushError.ALIVC_PUSHER_ERROR_SDK_PUSH_CONNECT_STREAM;
14 import static com.alivc.live.pusher.AlivcLivePushError.ALIVC_PUSHER_ERROR_SDK_PUSH_RECONNECT_FAIL;
15 import static com.alivc.live.pusher.AlivcLivePushError.ALIVC_PUSHER_ERROR_SDK_PUSH_RTS_DOWN_TO_RTMP;
16 import static com.alivc.live.pusher.AlivcLivePushError.ALIVC_PUSHER_ERROR_SDK_PUSH_SEND_DATA_TIMEOUT;
17 import static com.alivc.live.pusher.AlivcLivePushError.ALIVC_PUSHER_ERROR_SDK_PUSH_SETUPURL;
18 import static com.alivc.live.pusher.AlivcLivePushError.ALIVC_PUSHER_ERROR_SDK_PUSH_START_PUSH_TIMEOUT;
19 import static com.alivc.live.pusher.AlivcLivePushError.getErrorByCode;
20 import static com.alivc.live.pusher.LivePushNotification.ALIVC_PUSHER_EVENT_BGM_COMPLETED;
21 import static com.alivc.live.pusher.LivePushNotification.ALIVC_PUSHER_EVENT_BGM_OPEN_SUCCESS;
22 import static com.alivc.live.pusher.LivePushNotification.ALIVC_PUSHER_EVENT_BGM_PAUSE_SUCCESS;
23 import static com.alivc.live.pusher.LivePushNotification.ALIVC_PUSHER_EVENT_BGM_PROGRESS;
24 import static com.alivc.live.pusher.LivePushNotification.ALIVC_PUSHER_EVENT_BGM_RESUME_SUCCESS;
25 import static com.alivc.live.pusher.LivePushNotification.ALIVC_PUSHER_EVENT_BGM_STOP_SUCCESS;
26 import static com.alivc.live.pusher.LivePushNotification.ALIVC_PUSHER_EVENT_CAPTURE_CLOSE_CAMERA_SUCCESS;
28 import static com.alivc.live.pusher.LivePushNotification.ALIVC_PUSHER_EVENT_CAPTURE_OPEN_CAMERA_SUCCESS;
29 import static com.alivc.live.pusher.LivePushNotification.ALIVC_PUSHER_EVENT_CAPTURE_OPEN_MIC_SUCCESS;
31 import static com.alivc.live.pusher.LivePushNotification.ALIVC_PUSHER_EVENT_GENERAL_MONITOR;
34 import static com.alivc.live.pusher.LivePushNotification.ALIVC_PUSHER_EVENT_NATIVE_LIVE_PUSH_CHANGE_FPS;
38 import static com.alivc.live.pusher.LivePushNotification.ALIVC_PUSHER_EVENT_NATIVE_LIVE_PUSH_INIT_SUCCESS;
42 import static com.alivc.live.pusher.LivePushNotification.ALIVC_PUSHER_EVENT_NATIVE_LIVE_PUSH_PUSH_PAUSED;
44 import static com.alivc.live.pusher.LivePushNotification.ALIVC_PUSHER_EVENT_NATIVE_LIVE_PUSH_PUSH_RESUMED;
45 import static com.alivc.live.pusher.LivePushNotification.ALIVC_PUSHER_EVENT_PUSH_CONNECTION_LOST;
46 import static com.alivc.live.pusher.LivePushNotification.ALIVC_PUSHER_EVENT_PUSH_CRASH;
47 import static com.alivc.live.pusher.LivePushNotification.ALIVC_PUSHER_EVENT_PUSH_DELAY_INFO;
48 import static com.alivc.live.pusher.LivePushNotification.ALIVC_PUSHER_EVENT_PUSH_DROP_FRAME;
49 import static com.alivc.live.pusher.LivePushNotification.ALIVC_PUSHER_EVENT_PUSH_MEDIAINFO;
50 import static com.alivc.live.pusher.LivePushNotification.ALIVC_PUSHER_EVENT_PUSH_NETWORK_RECOVERY;
51 import static com.alivc.live.pusher.LivePushNotification.ALIVC_PUSHER_EVENT_PUSH_RECONNECT_START;
52 import static com.alivc.live.pusher.LivePushNotification.ALIVC_PUSHER_EVENT_PUSH_RECONNECT_SUCCESS;
53 import static com.alivc.live.pusher.LivePushNotification.ALIVC_PUSHER_EVENT_PUSH_SENDED_FIRST_AV;
54 import static com.alivc.live.pusher.LivePushNotification.ALIVC_PUSHER_EVENT_PUSH_SENDED_SEI;
55 import static com.alivc.live.pusher.LivePushNotification.ALIVC_PUSHER_EVENT_PUSH_STARTED;
56 import static com.alivc.live.pusher.LivePushNotification.ALIVC_PUSHER_EVENT_PUSH_STOPED;
57 import static com.alivc.live.utils.ParameterUtil.getInteger;
58 import static com.alivc.live.utils.ParameterUtil.getLong;
59 
60 import android.app.Application;
61 import android.content.BroadcastReceiver;
62 import android.content.Context;
63 import android.content.Intent;
64 import android.content.IntentFilter;
65 import android.graphics.Bitmap;
66 import android.graphics.BitmapFactory;
67 import android.media.AudioManager;
68 import android.os.Handler;
69 import android.os.Looper;
70 import android.os.Message;
71 import android.text.TextUtils;
72 import android.view.Surface;
73 import android.view.SurfaceHolder;
74 import android.view.SurfaceView;
75 import android.widget.FrameLayout;
76 
80 import com.alivc.component.player.BGMPlayerJNI;
81 import com.alivc.live.annotations.AlivcLiveStreamType;
83 import com.alivc.live.pusher.logreport.PusherAdjustFpsEvent;
85 import com.alivc.live.pusher.logreport.PusherDelayInfoEvent;
86 import com.alivc.live.pusher.logreport.PusherDropFrameEvent;
88 import com.alivc.live.pusher.logreport.PusherHeartBeatEvent;
89 import com.alivc.live.pusher.logreport.PusherLicenseEvent;
90 import com.alivc.live.pusher.logreport.PusherMuteOffEvent;
91 import com.alivc.live.pusher.logreport.PusherMuteOnEvent;
92 import com.alivc.live.pusher.logreport.PusherNetworkPoorEvent;
94 import com.alivc.live.pusher.logreport.PusherOnPauseEvent;
95 import com.alivc.live.pusher.logreport.PusherOnRestartEvent;
96 import com.alivc.live.pusher.logreport.PusherOnResumeEvent;
97 import com.alivc.live.pusher.logreport.PusherPauseEvent;
98 import com.alivc.live.pusher.logreport.PusherReconnectEvent;
102 import com.alivc.live.pusher.logreport.PusherRestartPushEvent;
103 import com.alivc.live.pusher.logreport.PusherResumeEvent;
104 import com.alivc.live.pusher.logreport.PusherSDKCrashEvent;
105 import com.alivc.live.pusher.logreport.PusherSdkErrorEvent;
108 import com.alivc.live.pusher.logreport.PusherSetBGMEvent;
109 import com.alivc.live.pusher.logreport.PusherSetBGMLoopEvent;
110 import com.alivc.live.pusher.logreport.PusherSetFlashEvent;
111 import com.alivc.live.pusher.logreport.PusherStartPreviewEvent;
112 import com.alivc.live.pusher.logreport.PusherStartPushEvent;
115 import com.alivc.live.pusher.logreport.PusherStopPreviewEvent;
116 import com.alivc.live.pusher.logreport.PusherStopPushEvent;
118 import com.alivc.live.pusher.logreport.PusherSwitchCameraEvent;
119 import com.alivc.live.pusher.logreport.PusherSystemErrorEvent;
120 import com.alivc.live.pusher.logreport.core.AliLiveInfoUtils;
121 import com.alivc.live.pusher.logreport.core.LiveEventReporter;
124 import com.alivc.live.utils.AlivcLiveURLTools;
125 import com.alivc.live.utils.AppFrontBackHelper;
126 import com.alivc.live.utils.BluetoothHeadsetUtils;
127 import com.alivc.live.utils.ParameterUtil;
128 import com.alivc.live.utils.SntpClient;
129 
130 import org.json.JSONException;
131 import org.json.JSONObject;
132 import org.webrtc.utils.AlivcLog;
133 import org.webrtc.utils.telephony.TelephonyListener;
134 import org.webrtc.utils.telephony.TelephonyUtil;
135 
136 import java.lang.ref.WeakReference;
137 import java.util.ArrayList;
138 import java.util.HashMap;
139 import java.util.Iterator;
140 import java.util.Map;
141 import java.util.StringTokenizer;
142 import java.util.concurrent.Executors;
143 import java.util.concurrent.LinkedBlockingQueue;
144 import java.util.concurrent.ScheduledExecutorService;
145 import java.util.concurrent.ScheduledThreadPoolExecutor;
146 import java.util.concurrent.ThreadFactory;
147 import java.util.concurrent.ThreadPoolExecutor;
148 import java.util.concurrent.TimeUnit;
149 import java.util.concurrent.atomic.AtomicInteger;
150 
151 @CalledByNative
152 class AlivcLivePusherBasicImpl implements ILivePusher {
153  private static final String TAG = "AlivcLivePusherBasicImpl";
154 
155  protected enum ScreenRecordStatus {
156  SCREEN_RECORD_NONE,
157  SCREEN_RECORD_NORMAL,
158  SCREEN_RECORD_CAMERA_START,
159  SCREEN_RECORD_CAMERA_MIX_START,
160  }
161 
162  private static LivePusherJNI mNativeAlivcLivePusher = null;
163  private WeakReference<AlivcLivePusher> mWeakAlivcLivePusher = null;
164 
165  private AlivcLivePushStats mPushStatus = AlivcLivePushStats.IDLE;
166  private AlivcLivePlayStats mPlayStats = AlivcLivePlayStats.IDLE;
167  private AlivcLivePushError mLastError = AlivcLivePushError.ALIVC_COMMON_RETURN_SUCCESS;
168 
169  private AlivcLivePushInfoListener mPushInfoListener = null;
170  private AlivcLivePushErrorListener mPushErrorListener = null;
171  private AlivcLivePushNetworkListener mPushNetworkListener = null;
172  private AlivcLivePushBGMListener mPushBGMListener = null;
173  private AlivcLivePusherRenderContextListener mRenderContextListener = null;
174 
175  private SurfaceStatus mSurfaceStatus = SurfaceStatus.UNINITED;
176 
177  private SurfaceView mPreviewView = null;
178 
179  private AudioManager mAudioManager = null;
180 
181  private Context mContext = null;
182  private AlivcLivePushConfig mAlivcLivePushConfig = null;
183  private static final int NTP_TIME_OUT_MILLISECOND = 1000;
184  private static final String AUTH_KEY = "auth_key=";
185  private static final int MAX_CHATS = 4000;
186  private static final float TEXTURE_RANGE_MIN = 0.0f;
187  private static final float TEXTURE_RANGE_MAX = 1.0f;
188  private static final int MAX_DYNAMIC_ADDSON_COUNT = 3;
189  private static final int AlivcLiveMaxWatermarkCount = 3; // 最多输入3个水印
190  private static final long SCHEDULED_EXECUTOR_SERVICE_PERIOD = 2 * 1000L;
191 
192  private Map<Integer, AlivcLivePushError> mErrorMap = new HashMap<>();
193  private String mPushUrl = null;
194 
195  private int mBGMVolume = 50;
196  private int mCaptureVolume = 50;
197  private boolean mMute = false;
198 
199  private TelephonyUtil mTelephonyUtil = null;
200 
201  private static final int MESSAGE_RECONNECT_SUCCESS = 0x12;
202  private boolean registeredCallback = false;
203  protected BluetoothHeadsetUtils mBluetoothHelper;
204  private boolean isReconnect = false;
205  private LiveEventReporter mLiveEventReporter = null;
206  private long mTimeStamp = -1;
207  private int mExpiryTime = -1;
208 
209  private int mDynamicAddsonCount = 0;
210 
211  private int mTimeCount = 0;
212 
213  private int mWatermarkCount = 0;
214 
215  private ScheduledExecutorService mScheduledExecutorService = null;
216 
217  private AlivcSnapshotListener mSnapshotListener = null;
218 
219  private ScreenRecordStatus mScreenStatus = ScreenRecordStatus.SCREEN_RECORD_NONE;
220 
221  private AppFrontBackHelper mAppFrontBackHelper;
222 
223  private ThreadPoolExecutor mThreadPoolExecutor = new ThreadPoolExecutor(3, 5, 1, TimeUnit.SECONDS,
224  new LinkedBlockingQueue<Runnable>(100));
225 
226  private Handler mHandler = new Handler(Looper.getMainLooper()) {
227  @Override
228  public void handleMessage(Message msg) {
229  AlivcLog.i(TAG, "[Callback-PushNetwork] onReconnectSucceed");
230  isReconnect = false;
231  if (mPushNetworkListener != null) {
232  mThreadPoolExecutor.execute(new Runnable() {
233  @Override
234  public void run() {
235  mPushNetworkListener.onReconnectSucceed(getLivePusherReference());
236  }
237  });
238  }
239  }
240  };
241 
242  private SurfaceHolder.Callback mPreviewCallback = new SurfaceHolder.Callback() {
243  @Override
244  public void surfaceCreated(SurfaceHolder holder) {
245  AlivcLog.d(TAG, "Preview surface created");
246  if (mPreviewView == null) {
247  return;
248  }
249  //记录Surface的状态
250  if (mSurfaceStatus == SurfaceStatus.UNINITED) {
251  mSurfaceStatus = SurfaceStatus.CREATED;
252  } else if (mSurfaceStatus == SurfaceStatus.DESTROYED) {
253  mSurfaceStatus = SurfaceStatus.RECREATED;
254  if (mNativeAlivcLivePusher != null) {
255  mNativeAlivcLivePusher.notifySurfaceReCreate(mPreviewView.getHolder().getSurface());
256  }
257  }
258  }
259 
260  @Override
261  public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
262  AlivcLog.d(TAG, "Preview surface changed");
263  if (mPreviewView == null) {
264  return;
265  }
266  mSurfaceStatus = SurfaceStatus.CHANGED;
267  if (mNativeAlivcLivePusher != null) {
268  mNativeAlivcLivePusher.notifySurfaceChange(holder.getSurface(), mAlivcLivePushConfig.getPreviewOrientation());
269  }
270  }
271 
272  @Override
273  public void surfaceDestroyed(SurfaceHolder holder) {
274  AlivcLog.d(TAG, "Preview surface destroyed");
275  if (mPreviewView == null) {
276  return;
277  }
278  if (mNativeAlivcLivePusher != null) {
279  mNativeAlivcLivePusher.notifySurfaceDestroy();
280  }
281  mSurfaceStatus = SurfaceStatus.DESTROYED;
282  }
283  };
284 
285  public AlivcLivePusherBasicImpl() {
286 
287  }
288 
289  @Override
290  public void init(final Context context, final AlivcLivePushConfig config) throws IllegalArgumentException, IllegalStateException {
291  AlivcLog.i(TAG, "[API-Pusher] init");
292  AlivcLog.i(TAG, AlivcLivePushInstance.getSdkBuildInfo());
293  mContext = context;
294  mAlivcLivePushConfig = config;
295  mLiveEventReporter = new LiveEventReporter(mContext, this, mAlivcLivePushConfig);
296 
297  if (!AlivcLiveLicenseManager.isLicenseRegistered()) {
298  String errorMessage = "License not registered! Get HELP from https://help.aliyun.com/document_detail/431730.htm";
299  AlivcLog.e(TAG, errorMessage);
300  throw new IllegalStateException(errorMessage);
301  }
302 
303  boolean isLicenseVerified = AlivcLiveLicenseManager.verifyLicense();
304 
305  AlivcLiveLicenseManager.AlivcLiveLicenseResult licenseResult = AlivcLiveLicenseManager.getLatestLicenseResult();
306  if (licenseResult != null) {
307  PusherLicenseEvent.Args args = new PusherLicenseEvent.Args();
308  args.result = licenseResult.result;
309  args.reason = licenseResult.msg;
310  args.key = licenseResult.licenseKey;
311  mLiveEventReporter.sendEvent(PusherLicenseEvent.kTopicType, PusherLicenseEvent.kTopicValue, PusherLicenseEvent.getArgsStr(args));
312  }
313 
314  if (!isLicenseVerified) {
315  String errorMessage = "License not verified! Get HELP from https://help.aliyun.com/document_detail/431730.htm";
316  AlivcLog.e(TAG, errorMessage);
317  throw new IllegalStateException(errorMessage);
318  }
319 
320  if (mPushStatus != AlivcLivePushStats.IDLE && mPushStatus != AlivcLivePushStats.INIT) {
321  throw new IllegalStateException("init state error, current state is " + AlivcLivePushStats.values()[mPushStatus.ordinal()]);
322  }
323  mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
324  mAudioManager.setMode(AudioManager.STREAM_VOICE_CALL);
325  mAudioManager.setSpeakerphoneOn(true);
326 
327  registerHeadsetPlugReceiver();
328  registerTelephony();
329 
330  LogWhenGoBackOrFront((Application) context.getApplicationContext(), true);
331 
332  AliLiveInfoUtils.setSDKContext(mContext);
333 
334  mBluetoothHelper = new BluetoothHeadsetUtils(mContext);
335  mBluetoothHelper.start(new BluetoothHeadsetUtils.BlueToothListener() {
336  @Override
337  public void onBlueTooth(boolean on) {
338  LivePusherJNI.headSetOn = on;
339  if (!on) {
340  mAudioManager.setMode(AudioManager.STREAM_VOICE_CALL);
341  mAudioManager.setSpeakerphoneOn(true);
342  } else {
343  mAudioManager.setSpeakerphoneOn(false);
344  }
345  if (mNativeAlivcLivePusher != null) {
346  mNativeAlivcLivePusher.setHeadSet(on);
347  }
348  }
349  });
350 
351  checkConfig(config);
352 
353  for (AlivcLivePushError error : AlivcLivePushError.values()) {
354  mErrorMap.put(error.getCode(), error);
355  }
356  mLiveEventReporter = new LiveEventReporter(mContext, this, mAlivcLivePushConfig);
357  mNativeAlivcLivePusher = new LivePusherJNI(mContext, config, new LivePusherJNI.LivePusherListener() {
358  @Override
359  public void onNotify(final int what, String msg, final int param1, final int param2, int param3, int param4, int param5, long arg6, String arg7, String arg8) {
360  // 网络监听器
361  if (what == ALIVC_PUSHER_ERROR_SDK_LIVE_PUSH_NETWORK_TOO_POOR.getCode()) {
362  AlivcLog.w(TAG, "[Callback-PushNetwork] onNetworkPoor");
363  if (mPushNetworkListener != null) {
364  mThreadPoolExecutor.execute(new Runnable() {
365  @Override
366  public void run() {
367  mPushNetworkListener.onNetworkPoor(getLivePusherReference());
368  }
369  });
370  }
371 
372  PusherNetworkPoorEvent.Args args = null;
373  mLiveEventReporter.sendEvent(PusherNetworkPoorEvent.kTopicType, PusherNetworkPoorEvent.kTopicValue, PusherNetworkPoorEvent.getArgsStr(args));
374  } else if (what == ALIVC_PUSHER_EVENT_PUSH_NETWORK_RECOVERY.getCode()) {
375  AlivcLog.i(TAG, "[Callback-PushNetwork] onNetworkRecovery");
376  if (mPushNetworkListener != null) {
377  mThreadPoolExecutor.execute(new Runnable() {
378  @Override
379  public void run() {
380  mPushNetworkListener.onNetworkRecovery(getLivePusherReference());
381  }
382  });
383  }
384 
385  PusherNetworkRecoveryEvent.Args args = null;
386  mLiveEventReporter.sendEvent(PusherNetworkRecoveryEvent.kTopicType, PusherNetworkRecoveryEvent.kTopicValue, PusherNetworkRecoveryEvent.getArgsStr(args));
387  } else if (what == ALIVC_PUSHER_EVENT_PUSH_RECONNECT_START.getCode()) {
388  AlivcLog.i(TAG, "[Callback-PushNetwork] onReconnectStart");
389  if (!isReconnect) {
390  isReconnect = true;
391  if (mPushNetworkListener != null) {
392  mThreadPoolExecutor.execute(new Runnable() {
393  @Override
394  public void run() {
395  mPushNetworkListener.onReconnectStart(getLivePusherReference());
396  }
397  });
398  }
399  }
400 
401  PusherReconnectStartEvent.Args args = new PusherReconnectStartEvent.Args();
402  mLiveEventReporter.sendEvent(PusherReconnectStartEvent.kTopicType, PusherReconnectStartEvent.kTopicValue, PusherReconnectStartEvent.getArgsStr(args));
403  } else if (what == ALIVC_PUSHER_EVENT_PUSH_RECONNECT_SUCCESS.getCode()) {
404  AlivcLog.i(TAG, "[Callback-PushNetwork] Reconnect Success");
405  if (mHandler != null) {
406  mHandler.removeMessages(MESSAGE_RECONNECT_SUCCESS);
407  mHandler.sendEmptyMessageDelayed(MESSAGE_RECONNECT_SUCCESS, 500);
408  }
409  //todo ! keep paused status
410  if (mPushStatus != AlivcLivePushStats.PAUSED) {
411  mPushStatus = AlivcLivePushStats.PUSHED;
412  }
413 
414  PusherReconnectSuccessEvent.Args args = null;
415  mLiveEventReporter.sendEvent(PusherReconnectSuccessEvent.kTopicType, PusherReconnectSuccessEvent.kTopicValue, PusherReconnectSuccessEvent.getArgsStr(args));
416  } else if (what == ALIVC_PUSHER_EVENT_PUSH_CONNECTION_LOST.getCode()) {
417  AlivcLog.e(TAG, "[Callback-PushNetwork] onConnectionLost");
418  if (mPushNetworkListener != null) {
419  mThreadPoolExecutor.execute(new Runnable() {
420  @Override
421  public void run() {
422  mPushNetworkListener.onConnectionLost(getLivePusherReference());
423  }
424  });
425  }
426 
427  PusherConnectionLostEvent.Args args = new PusherConnectionLostEvent.Args();
428  if (param1 == 0) {
429  args.reason = "rtmp_";
430  } else if (param1 == 1) {
431  args.reason = "artc_";
432  }
433  args.reason += String.valueOf(param2);
434  mLiveEventReporter.sendEvent(PusherConnectionLostEvent.kTopicType, PusherConnectionLostEvent.kTopicValue, PusherConnectionLostEvent.getArgsStr(args));
435  } else if (what == ALIVC_PUSHER_ERROR_SDK_PUSH_RECONNECT_FAIL.getCode()) {
436  AlivcLog.e(TAG, "[Callback-PushNetwork] onReconnectFail");
437  isReconnect = false;
438  if (mHandler != null) {
439  mHandler.removeMessages(MESSAGE_RECONNECT_SUCCESS);
440  }
441  if (mPushNetworkListener != null) {
442  mThreadPoolExecutor.execute(new Runnable() {
443  @Override
444  public void run() {
445  mPushNetworkListener.onReconnectFail(getLivePusherReference());
446  }
447  });
448  }
449  mPushStatus = AlivcLivePushStats.ERROR;
450  mLastError = ALIVC_PUSHER_ERROR_SDK_PUSH_RECONNECT_FAIL;
451 
452  PusherReconnectFailedEvent.Args args = new PusherReconnectFailedEvent.Args();
453  args.errCode = what;
454  args.errMsg = msg;
455  mLiveEventReporter.sendEvent(PusherReconnectFailedEvent.kTopicType, PusherReconnectFailedEvent.kTopicValue, PusherReconnectFailedEvent.getArgsStr(args));
456  } else if (what == ALIVC_PUSHER_ERROR_SDK_PUSH_SEND_DATA_TIMEOUT.getCode()) {
457  AlivcLog.w(TAG, "[Callback-PushNetwork] onSendDataTimeout");
458  if (mPushNetworkListener != null) {
459  mThreadPoolExecutor.execute(new Runnable() {
460  @Override
461  public void run() {
462  mPushNetworkListener.onSendDataTimeout(getLivePusherReference());
463  }
464  });
465  }
466 
467  PusherSendDataTimeoutEvent.Args args = null;
468  mLiveEventReporter.sendEvent(PusherSendDataTimeoutEvent.kTopicType, PusherSendDataTimeoutEvent.kTopicValue, PusherSendDataTimeoutEvent.getArgsStr(args));
469  } else if (what == ALIVC_PUSHER_ERROR_SDK_PUSH_CONNECT.getCode()
470  || what == ALIVC_LIVE_ERROR_SYSTEM_RTMP_OOM.getCode()
471  || what == ALIVC_PUSHER_ERROR_SDK_PUSH_SETUPURL.getCode()
472  || what == ALIVC_PUSHER_ERROR_SDK_PUSH_CONNECT_STREAM.getCode()
473  || what == ALIVC_PUSHER_ERROR_SDK_PUSH_START_PUSH_TIMEOUT.getCode()) {
474  AlivcLog.e(TAG, "[Callback-PushNetwork] onConnectFail");
475  if (mPushNetworkListener != null) {
476  mThreadPoolExecutor.execute(new Runnable() {
477  @Override
478  public void run() {
479  mPushNetworkListener.onConnectFail(getLivePusherReference());
480  }
481  });
482  }
483  mPushStatus = AlivcLivePushStats.ERROR;
484  mLastError = getErrorByCode(what);
485 
486  PusherStartPushFailedEvent.Args args = new PusherStartPushFailedEvent.Args();
487  args.errCode = what;
488  args.errMsg = msg;
489  mLiveEventReporter.sendEvent(PusherStartPushFailedEvent.kTopicType, PusherStartPushFailedEvent.kTopicValue, PusherStartPushFailedEvent.getArgsStr(args));
490  } else if (what == ALIVC_PUSHER_EVENT_NATIVE_LIVE_PUSH_INIT_SUCCESS.getCode()) {
491 
492  } else if (what == ALIVC_PUSHER_EVENT_NATIVE_LIVE_PUSH_PREVIEW_STARTED.getCode()) {
493  AlivcLog.i(TAG, "[Callback-PushInfo] onPreviewStarted");
494  if (mPushInfoListener != null) {
495  mThreadPoolExecutor.execute(new Runnable() {
496  @Override
497  public void run() {
498  mPushInfoListener.onPreviewStarted(getLivePusherReference());
499  }
500  });
501  }
502  mPushStatus = AlivcLivePushStats.PREVIEWED;
503  addWaterMark();
504  } else if (what == ALIVC_PUSHER_EVENT_NATIVE_LIVE_PUSH_PREVIEW_STOPED.getCode()) {
505  AlivcLog.i(TAG, "[Callback-PushInfo] onPreviewStopped");
506  if (mPushInfoListener != null) {
507  mThreadPoolExecutor.execute(new Runnable() {
508  @Override
509  public void run() {
510  if (mPushInfoListener != null) {
511  mPushInfoListener.onPreviewStopped(getLivePusherReference());
512  }
513  }
514  });
515  }
516  mPushStatus = AlivcLivePushStats.INIT;
517  } else if (what == ALIVC_PUSHER_EVENT_PUSH_STARTED.getCode()) {
518  AlivcLog.i(TAG, "[Callback-PushInfo] onPushStarted");
519  mPushStatus = AlivcLivePushStats.PUSHED;
520  if (mPushInfoListener != null) {
521  mThreadPoolExecutor.execute(new Runnable() {
522  @Override
523  public void run() {
524  mPushInfoListener.onPushStarted(getLivePusherReference());
525  }
526  });
527  }
528 
529  PusherStartPushSuccessEvent.Args args = new PusherStartPushSuccessEvent.Args();
530  args.url = mPushUrl;
531  mLiveEventReporter.sendEvent(PusherStartPushSuccessEvent.kTopicType, PusherStartPushSuccessEvent.kTopicValue, PusherStartPushSuccessEvent.getArgsStr(args));
532  } else if (what == ALIVC_PUSHER_EVENT_PUSH_STOPED.getCode()) {
533  AlivcLog.i(TAG, "[Callback-PushInfo] onPushStopped");
534  if (mPushInfoListener != null) {
535  mThreadPoolExecutor.execute(new Runnable() {
536  @Override
537  public void run() {
538  if (mPushInfoListener != null) {
539  mPushInfoListener.onPushStopped(getLivePusherReference());
540  }
541  }
542  });
543  }
544  PusherStopPushSuccessEvent.Args args = new PusherStopPushSuccessEvent.Args();
545  args.url = mPushUrl;
546  mLiveEventReporter.sendEvent(PusherStopPushSuccessEvent.kTopicType, PusherStopPushSuccessEvent.kTopicValue, PusherStopPushSuccessEvent.getArgsStr(args));
547  } else if(what == ALIVC_PUSHER_EVENT_PUSH_CRASH.getCode()){
548  AlivcLog.i(TAG, "found SDK crashed!");
549  mLiveEventReporter.sendEvent(PusherSDKCrashEvent.kTopicType, PusherSDKCrashEvent.kTopicValue, PusherSDKCrashEvent.getArgsStr(arg7, arg8));
550  } else if(what == ALIVC_PUSHER_EVENT_GENERAL_MONITOR.getCode()) {
551  AlivcLivePushConstants.Topic topicType = AlivcLivePushConstants.Topic.event;
552  //kAction=0, kEvent=1, kError=2, kBiz=3
553  int topicTypeId = (int)arg6;
554  switch (topicTypeId) {
555  case 0: topicType = AlivcLivePushConstants.Topic.action; break;
556  case 1: topicType = AlivcLivePushConstants.Topic.event; break;
557  case 2: topicType = AlivcLivePushConstants.Topic.error; break;
558  case 3: topicType = AlivcLivePushConstants.Topic.biz; break;
559  default: assert(false);
560  }
561 
562  assert(!arg7.isEmpty());
563  String topicValue = arg7;
564  String argJsonStr = arg8;
565  Map<String, String> param = new HashMap<String, String>();
566  try {
567  JSONObject obj = new JSONObject(argJsonStr);
568  Iterator it = obj.keys();
569  while (it.hasNext()) {
570  String key = it.next().toString();
571  String value = (String)obj.get(key).toString();
572  param.put(key, value);
573  }
574  } catch(JSONException e) {
575  AlivcLog.e(TAG, "Invalid json object: " + arg8);
576  } catch(Exception e) {
577  AlivcLog.e(TAG, "Unknown exception: " + e.getMessage());
578  }
579  mLiveEventReporter.sendEvent(topicType, topicValue, param);
580  } else if(what == ALIVC_PUSHER_EVENT_PUSH_MEDIAINFO.getCode()) {
581 
582  } else if(what == ALIVC_PUSHER_EVENT_PUSH_DELAY_INFO.getCode()) {
583 
584  PusherDelayInfoEvent.Args args = new PusherDelayInfoEvent.Args();
585  args.totalDelay = param1;
586  args.captureDelay = param2;
587  args.encoderDelay = param3;
588  args.sendDelay = param4;
589 
590  AlivcLog.d(TAG, "AlivcLivePusher push delay");
591 
592  mLiveEventReporter.sendEvent(PusherDelayInfoEvent.kTopicType, PusherDelayInfoEvent.kTopicValue, PusherDelayInfoEvent.getArgsStr(args));
593 
594 
595  JSONObject gDelayObject = new JSONObject();
596 
597  try {
598  gDelayObject.put("gdelay", param1);
599 
600  sendMessageInternal(gDelayObject.toString(),10,0,false, true);
601 
602  } catch (Exception e) {
603  e.printStackTrace();
604  }
605 
606 
607  } else if (what == ALIVC_PUSHER_EVENT_NATIVE_LIVE_PUSH_PUSH_PAUSED.getCode()) {
608  AlivcLog.i(TAG, "[Callback-PushInfo] onPushPaused");
609  if (mPushInfoListener != null) {
610  mThreadPoolExecutor.execute(new Runnable() {
611  @Override
612  public void run() {
613  mPushInfoListener.onPushPaused(getLivePusherReference());
614  }
615  });
616  }
617 
618  PusherOnPauseEvent.Args args = null;
619  mLiveEventReporter.sendEvent(PusherOnPauseEvent.kTopicType, PusherOnPauseEvent.kTopicValue, PusherOnPauseEvent.getArgsStr(args));
620  } else if (what == ALIVC_PUSHER_EVENT_NATIVE_LIVE_PUSH_PUSH_RESUMED.getCode()) {
621  AlivcLog.i(TAG, "[Callback-PushInfo] onPushResumed");
622  if (mNativeAlivcLivePusher.isPushing()) {
623  mPushStatus = AlivcLivePushStats.PUSHED;
624  } else {
625  mPushStatus = AlivcLivePushStats.PREVIEWED;
626  }
627  if (mPushInfoListener != null) {
628  mThreadPoolExecutor.execute(new Runnable() {
629  @Override
630  public void run() {
631  mPushInfoListener.onPushResumed(getLivePusherReference());
632  }
633  });
634  }
635 
636  PusherOnResumeEvent.Args args = null;
637  mLiveEventReporter.sendEvent(PusherOnResumeEvent.kTopicType, PusherOnResumeEvent.kTopicValue, PusherOnResumeEvent.getArgsStr(args));
638  } else if (what == ALIVC_FRAMEWORK_RENDER_FIRST_FRAME_PREVIEWED.getCode()) {
639  AlivcLog.i(TAG, "[Callback-PushInfo] onFirstFramePreviewed");
640  if (mPushInfoListener != null) {
641  mThreadPoolExecutor.execute(new Runnable() {
642  @Override
643  public void run() {
644  mPushInfoListener.onFirstFramePreviewed(getLivePusherReference());
645  }
646  });
647  }
648  } else if (what == ALIVC_PUSHER_EVENT_NATIVE_LIVE_PUSH_PUSH_RESTARTED.getCode()) {
649  AlivcLog.i(TAG, "[Callback-PushInfo] onPushRestarted");
650  mPushStatus = AlivcLivePushStats.PUSHED;
651  if (mPushInfoListener != null) {
652  mThreadPoolExecutor.execute(new Runnable() {
653  @Override
654  public void run() {
655  mPushInfoListener.onPushRestarted(getLivePusherReference());
656  }
657  });
658  }
659 
660  PusherOnRestartEvent.Args args = null;
661  mLiveEventReporter.sendEvent(PusherOnRestartEvent.kTopicType, PusherOnRestartEvent.kTopicValue, PusherOnRestartEvent.getArgsStr(args));
662  } else if (what == ALIVC_PUSHER_EVENT_PUSH_DROP_FRAME.getCode()) {//丢帧
663  AlivcLog.w(TAG, "[Callback-PushInfo] onDropFrame");
664  AlivcLog.w(TAG, "[Callback-PushNetwork] onPacketsLost");
665  PusherDropFrameEvent.PusherDropFrameArgs args = new PusherDropFrameEvent.PusherDropFrameArgs();
666  args.vpiubbd = param1;
667  args.vpiubad = param2;
668  args.apiubbd = param3;
669  args.apiubad = param4;
670  mLiveEventReporter.sendEvent(PusherDropFrameEvent.kTopicType, PusherDropFrameEvent.kTopicValue, PusherDropFrameEvent.getArgsStr(args));
671  if (mPushInfoListener != null) {
672  mThreadPoolExecutor.execute(new Runnable() {
673  @Override
674  public void run() {
675  mPushInfoListener.onDropFrame(getLivePusherReference(), param1, param2);
676 
677  if (mPushNetworkListener != null) {
678  mPushNetworkListener.onPacketsLost(getLivePusherReference());
679  }
680  }
681  });
682  }
683 
684  } else if (what == ALIVC_PUSHER_EVENT_NATIVE_LIVE_PUSH_ADJUST_BITRATE.getCode()) {
685  PusherAdjustBitrateEvent.Args args = new PusherAdjustBitrateEvent.Args();
686  args.oeb = param1 / 1000;
687  args.neb = param2 / 1000;
688  Map map = getPerformanceMap();
689  if (map != null) {
690  args.ceb = getInteger(map, "mVideoEncodeBitrate") + getInteger(map, "mAudioEncodeBitrate");
691  args.cub = getInteger(map, "mAudioUploadBitrate") + getInteger(map, "mVideoUploadBitrate");
692  }
693  AlivcLog.i(TAG, "[Callback-PushInfo] onAdjustBitrate: " + args.oeb + ", " + args.neb);
694  mLiveEventReporter.sendEventWithLevel(PusherAdjustBitrateEvent.kTopicType, PusherAdjustBitrateEvent.kTopicValue, PusherAdjustBitrateEvent.getArgsStr(args), AlivcLivePushMonitorLevel.CUT);
695  if (mPushInfoListener != null) {
696  mThreadPoolExecutor.execute(new Runnable() {
697  @Override
698  public void run() {
699  mPushInfoListener.onAdjustBitrate(getLivePusherReference(), param1 / 1000, param2 / 1000);
700  }
701  });
702  }
703  } else if (what == ALIVC_PUSHER_EVENT_NATIVE_LIVE_PUSH_CHANGE_FPS.getCode()) {
704  AlivcLog.i(TAG, "[Callback-PushInfo] onAdjustFps: " + param1 + ", " + param2);
705  PusherAdjustFpsEvent.Args args = new PusherAdjustFpsEvent.Args();
706  args.oldFps = param1;
707  args.newFps = param2;
708  mLiveEventReporter.sendEvent(PusherAdjustFpsEvent.kTopicType, PusherAdjustFpsEvent.kTopicValue, PusherAdjustFpsEvent.getArgsStr(args));
709  if (mPushInfoListener != null) {
710  mThreadPoolExecutor.execute(new Runnable() {
711  @Override
712  public void run() {
713  mPushInfoListener.onAdjustFps(getLivePusherReference(), param1, param2);
714  }
715  });
716  }
717  } else if (what == ALIVC_PUSHER_EVENT_NATIVE_LIVE_PUSH_CHANGE_RESOLUTION.getCode()) {
718 
719  } else if (what == ALIVC_PUSHER_ERROR_SDK_PUSH_RTS_DOWN_TO_RTMP.getCode()) {
720  //RTS降级到RTMP逻辑
721  //rtsDownToRtmp();
722  } else if (what == ALIVC_PUSHER_EVENT_PUSH_SENDED_FIRST_AV.getCode()) {
723  //开始推流
724  PusherFirstFrameSentEvent.Args args = new PusherFirstFrameSentEvent.Args();
725  args.vutMs = param2;
726  args.autMs = param1;
727  args.resolution = mAlivcLivePushConfig.getResolution().toString().substring(11);
728  args.st = mAlivcLivePushConfig.getAudioChannels() == 1 ? "single" : "dual";
729  args.ao = mAlivcLivePushConfig.isAudioOnly();
730  args.vo = mAlivcLivePushConfig.isVideoOnly();
731  args.he = mAlivcLivePushConfig.getVideoEncodeMode().equals(Encode_MODE_HARD);//是否使用硬编
732  args.wc = mAlivcLivePushConfig.getWaterMarkInfos().size();//水印
733  args.pum = mAlivcLivePushConfig.isPushMirror();
734  args.fps = mAlivcLivePushConfig.getFps();
735  args.ivb = mAlivcLivePushConfig.getInitialVideoBitrate();
736  args.mavb = mAlivcLivePushConfig.getTargetVideoBitrate();
737  args.mivb = mAlivcLivePushConfig.getMinVideoBitrate();
738  args.asr = mAlivcLivePushConfig.getAudioSampleRate().getAudioSampleRate();
739  args.po = mAlivcLivePushConfig.getPreviewOrientation();
740  args.ct = mAlivcLivePushConfig.getCameraType();
741  args.flash = mAlivcLivePushConfig.isFlash();
742  args.crmc = mAlivcLivePushConfig.getConnectRetryCount();
743  args.cri = mAlivcLivePushConfig.getConnectRetryInterval();
744  args.prm = mAlivcLivePushConfig.isPreviewMirror();
745  args.gop = mAlivcLivePushConfig.getVideoEncodeGop();
746  args.utm = (mAlivcLivePushConfig.getConnectRetryCount() * mAlivcLivePushConfig.getConnectRetryInterval()) / 1000;
747  mLiveEventReporter.sendEvent(PusherFirstFrameSentEvent.kTopicType, PusherFirstFrameSentEvent.kTopicValue, PusherFirstFrameSentEvent.getArgsStr(args));
748  AlivcLog.i(TAG, "[Callback-PushInfo] onFirstFramePushed");
749  if (mPushInfoListener != null) {
750  mThreadPoolExecutor.execute(new Runnable() {
751  @Override
752  public void run() {
753  mPushInfoListener.onFirstFramePushed(getLivePusherReference());
754  }
755  });
756  }
757  } else if (what == ALIVC_PUSHER_EVENT_CAPTURE_OPEN_CAMERA_SUCCESS.getCode()) {
758 
759  } else if (what == ALIVC_PUSHER_EVENT_CAPTURE_OPEN_MIC_SUCCESS.getCode()) {
760 
761  } else if (what == ALIVC_PUSHER_EVENT_CAPTURE_CLOSE_CAMERA_SUCCESS.getCode()) {
762 
763  } else if (what == ALIVC_PUSHER_EVENT_NATIVE_LIVE_PUSH_OPEN_VIDEO_ENCODER_SUCCESS.getCode()) {
764 
765  } else if (what == ALIVC_PUSHER_EVENT_NATIVE_LIVE_PUSH_CAPTURE_VIDEO_SAMPLES_OVERFLOW.getCode()) {
766  //render 处理不过来,capture丢帧
767  } else if (what == ALIVC_PUSHER_EVENT_PUSH_SENDED_SEI.getCode()) {
768  AlivcLog.i(TAG, "[Callback-PushNetwork] onSendMessage");
769  if (mPushNetworkListener != null) {
770  mThreadPoolExecutor.execute(new Runnable() {
771  @Override
772  public void run() {
773  mPushNetworkListener.onSendMessage(getLivePusherReference());
774  }
775  });
776  }
777  }
778 
779  //播放器监听
780  else if (what == ALIVC_PUSHER_ERROR_BGM_OPEN_FAILED.getCode()) {
781  AlivcLog.e(TAG, "[Callback-PushBGM] onOpenFailed");
782  mPlayStats = AlivcLivePlayStats.IDLE;
783  if (mPushBGMListener != null) {
784  mPushBGMListener.onOpenFailed();
785  }
786  if (mNativeAlivcLivePusher != null) {
787  mNativeAlivcLivePusher.stopBGM();
788  }
789  } else if (what == ALIVC_PUSHER_ERROR_BGM_TIMEOUT.getCode()) {
790  AlivcLog.e(TAG, "[Callback-PushBGM] onDownloadTimeout");
791  mPlayStats = AlivcLivePlayStats.IDLE;
792  if (mPushBGMListener != null) {
793  mPushBGMListener.onDownloadTimeout();
794  }
795  } else if (what == ALIVC_PUSHER_EVENT_BGM_OPEN_SUCCESS.getCode()) {
796  AlivcLog.i(TAG, "[Callback-PushBGM] onStarted");
797  mPlayStats = AlivcLivePlayStats.STARTED;
798  if (mPushBGMListener != null) {
799  mPushBGMListener.onStarted();
800  }
801  } else if (what == ALIVC_PUSHER_EVENT_BGM_STOP_SUCCESS.getCode()) {
802  AlivcLog.i(TAG, "[Callback-PushBGM] onStopped");
803  mPlayStats = AlivcLivePlayStats.STOPPED;
804  if (mPushBGMListener != null) {
805  mPushBGMListener.onStopped();
806  }
807  } else if (what == ALIVC_PUSHER_EVENT_BGM_PAUSE_SUCCESS.getCode()) {
808  AlivcLog.i(TAG, "[Callback-PushBGM] onPaused");
809  mPlayStats = AlivcLivePlayStats.PAUSED;
810  if (mPushBGMListener != null) {
811  mPushBGMListener.onPaused();
812  }
813  } else if (what == ALIVC_PUSHER_EVENT_BGM_RESUME_SUCCESS.getCode()) {
814  AlivcLog.i(TAG, "[Callback-PushBGM] onResumed");
815  mPlayStats = AlivcLivePlayStats.STARTED;
816  if (mPushBGMListener != null) {
817  mPushBGMListener.onResumed();
818  }
819  } else if (what == ALIVC_PUSHER_EVENT_BGM_COMPLETED.getCode()) {
820  AlivcLog.i(TAG, "[Callback-PushBGM] onCompleted");
821  if (mPushBGMListener != null) {
822  mPushBGMListener.onCompleted();
823  }
824  mPlayStats = AlivcLivePlayStats.IDLE;
825  } else if (what == ALIVC_PUSHER_EVENT_BGM_PROGRESS.getCode()) {
826  if (mPushBGMListener != null) {
827  mPushBGMListener.onProgress((long) param1, (long) param2);
828  }
829  } else if (what == ALIVC_PUSHER_EVENT_CAPTURE_OPEN_SCREENCAPTURE_SUCCESS.getCode()) {
830 
831  } else if (what == ALIVC_PUSHER_EVENT_CAPTURE_CLOSE_SCREENCAPTURE_SUCCESS.getCode()) {
832 
833  } else if (what == ALIVC_PUSHER_EVENT_NATIVE_LIVE_PUSH_GL_CONTEXT_CREATED.getCode()) {
834  AlivcLog.i(TAG, "[Callback-PusherRenderContext] onSharedContextCreated");
835  if (mRenderContextListener != null) {
836  mRenderContextListener.onSharedContextCreated(arg6);
837  }
838  } else if (what == ALIVC_PUSHER_EVENT_NATIVE_LIVE_PUSH_GL_CONTEXT_DESTROYED.getCode()) {
839  AlivcLog.i(TAG, "[Callback-PusherRenderContext] onSharedContextDestroyed");
840  if (mRenderContextListener != null) {
841  mRenderContextListener.onSharedContextDestroyed(arg6);
842  }
843  }
844  // 系统错误监听器
845  else if (what > 0x30010000 && what < 0x30020000) {
846  if (mErrorMap.get(what) != null) {
847  mErrorMap.get(what).setMsg(msg);
848  }
849  AlivcLog.e(TAG, "[Callback-PushError] onSystemError:" + mErrorMap.get(what));
850  if (mPushErrorListener != null) {
851  mThreadPoolExecutor.execute(new Runnable() {
852  @Override
853  public void run() {
854  mPushErrorListener.onSystemError(getLivePusherReference(), mErrorMap.get(what));
855  }
856  });
857  }
858 
859  PusherSystemErrorEvent.Args args = new PusherSystemErrorEvent.Args();
860  Map map = getPerformanceMap();
861  if (map != null) {
862  args.totalUploadSize = getLong(map, "mTotalSizeOfUploadedPackets");
863  args.totalTime = getLong(map, "mTotalTimeOfPublishing");
864  args.error_code = what;
865  if (mErrorMap.get(what) != null) {
866  args.error_msg = msg;
867  }
868  mLiveEventReporter.sendEvent(PusherSystemErrorEvent.kTopicType, PusherSystemErrorEvent.kTopicValue, PusherSystemErrorEvent.getArgsStr(args));
869  }
870  mPushStatus = AlivcLivePushStats.ERROR;
871  mLastError = getErrorByCode(what);
872  }
873  else if (what == ALIVC_PUSHER_ERROR_SDK_LIVE_PUSH_LOW_PERFORMANCE.getCode()) {
874  // When callback is low performance, do not set the status into a forbidden state.
875  if (mErrorMap.get(what) != null) {
876  mErrorMap.get(what).setMsg(msg);
877  }
878  AlivcLog.w(TAG, "low performance warning:" + mErrorMap.get(what));
879  PusherSdkErrorEvent.Args args = new PusherSdkErrorEvent.Args();
880  Map map = getPerformanceMap();
881  if (map != null) {
882  args.totalUploadSize = ParameterUtil.getLong(map, "mTotalSizeOfUploadedPackets");
883  args.totalTime = ParameterUtil.getLong(map, "mTotalTimeOfPublishing");
884  args.error_code = what;
885  if (mErrorMap.get(what) != null) {
886  args.error_msg = msg;
887  }
888  mLiveEventReporter.sendEvent(PusherSdkErrorEvent.kTopicType, PusherSdkErrorEvent.kTopicValue, PusherSdkErrorEvent.getArgsStr(args));
889  }
890  }
891  // 其他
892  else {
893  if (mErrorMap.get(what) != null) {
894  mErrorMap.get(what).setMsg(msg);
895  }
896  AlivcLog.e(TAG, "[Callback-PushError] onSDKError:" + mErrorMap.get(what));
897  if (mPushErrorListener != null) {
898  mThreadPoolExecutor.execute(new Runnable() {
899  @Override
900  public void run() {
901  mPushErrorListener.onSDKError(getLivePusherReference(), mErrorMap.get(what));
902  }
903  });
904  }
905 
906  PusherSdkErrorEvent.Args args = new PusherSdkErrorEvent.Args();
907  Map map = getPerformanceMap();
908  if (map != null) {
909  args.totalUploadSize = getLong(map, "mTotalSizeOfUploadedPackets");
910  args.totalTime = getLong(map, "mTotalTimeOfPublishing");
911  args.error_code = what;
912  if (mErrorMap.get(what) != null) {
913  args.error_msg = msg;
914  }
915  mLiveEventReporter.sendEvent(PusherSdkErrorEvent.kTopicType, PusherSdkErrorEvent.kTopicValue, PusherSdkErrorEvent.getArgsStr(args));
916  }
917  mPushStatus = AlivcLivePushStats.ERROR;
918  mLastError = getErrorByCode(what);
919  }
920  }
921  });
922  mNativeAlivcLivePusher.init();
923  BGMPlayerJNI.setContext(mContext);
924  mPushStatus = AlivcLivePushStats.INIT;
925  }
926 
927  @Override
928  public void setCustomDetect(AlivcLivePushCustomDetect customVideoDetect) {
929  AlivcLog.i(TAG, "[API-Pusher] setCustomDetect");
930  if (mNativeAlivcLivePusher == null) {
931  return;
932  }
933  mNativeAlivcLivePusher.setCustomDetect(customVideoDetect);
934  }
935 
936  @Override
937  public void setCustomFilter(AlivcLivePushCustomFilter customVideoFilter) {
938  AlivcLog.i(TAG, "[API-Pusher] setCustomFilter");
939  if (mNativeAlivcLivePusher == null) {
940  return;
941  }
942  mNativeAlivcLivePusher.setCustomFilter(customVideoFilter);
943  }
944 
945  @Override
946  public void setCustomAudioFilter(AlivcLivePushCustomAudioFilter customAudioFilter) {
947  AlivcLog.i(TAG, "[API-Pusher] setCustomAudioFilter: " + customAudioFilter);
948  if (mNativeAlivcLivePusher == null) {
949  return;
950  }
951  mNativeAlivcLivePusher.setCustomAudioFilter(customAudioFilter);
952  }
953 
954  @Override
955  public void destroy() throws IllegalStateException {
956  AlivcLog.i(TAG, "[API-Pusher] destroy");
957  LogWhenGoBackOrFront((Application) mContext.getApplicationContext(), false);
958 
959  if (mNativeAlivcLivePusher != null) {
960  mNativeAlivcLivePusher.release();
961  }
962 
963  mDynamicAddsonCount = 0;
964 
965  if (registeredCallback) {
966  try {
967  mContext.unregisterReceiver(mHeadsetPlugReceiver);
968  } catch (Exception e) {
969  AlivcLog.e(TAG, "unregisterReceiver exception");
970  }
971  registeredCallback = false;
972  }
973  if (mBluetoothHelper != null) {
974  mBluetoothHelper.stop();
975  }
976  unregisterTelephony();
977  mPushStatus = AlivcLivePushStats.IDLE;
978 
979  stopScheduleExecutor();
980 
981  if (mThreadPoolExecutor != null && !mThreadPoolExecutor.isShutdown()) {
982  mThreadPoolExecutor.shutdown();
983  }
984  mThreadPoolExecutor = null;
985 
986  mNativeAlivcLivePusher = null;
987  mPushInfoListener = null;
988  mPushErrorListener = null;
989  mPushNetworkListener = null;
990  mPushBGMListener = null;
991 
992  mPreviewView = null;
993  mContext = null;
994  mAlivcLivePushConfig = null;
995 
996  mErrorMap = null;
997  mPreviewCallback = null;
998  if (mHandler != null) {
999  mHandler.removeMessages(MESSAGE_RECONNECT_SUCCESS);
1000  }
1001  mHandler = null;
1002 
1003  if (mWeakAlivcLivePusher != null) {
1004  mWeakAlivcLivePusher.clear();
1005  mWeakAlivcLivePusher = null;
1006  }
1007  BGMPlayerJNI.setContext(null);
1008  }
1009 
1010  @Override
1011  public void setLivePusherReference(AlivcLivePusher livePusher) {
1012  mWeakAlivcLivePusher = new WeakReference<>(livePusher);
1013  }
1014 
1015  private AlivcLivePusher getLivePusherReference() {
1016  return (mWeakAlivcLivePusher != null) ? mWeakAlivcLivePusher.get() : null;
1017  }
1018 
1019  @Override
1020  public void startPreview(SurfaceView surfaceView) throws IllegalArgumentException, IllegalStateException {
1021  AlivcLog.i(TAG, "[API-Pusher] startPreview");
1022  PusherStartPreviewEvent.Args args = new PusherStartPreviewEvent.Args();
1023  args.sync = true;
1024  if (mLiveEventReporter != null) {
1025  mLiveEventReporter.sendEvent(PusherStartPreviewEvent.kTopicType, PusherStartPreviewEvent.kTopicValue, PusherStartPreviewEvent.getArgsStr(args));
1026  }
1027 
1028  if (mNativeAlivcLivePusher == null) {
1029  AlivcLog.e(TAG, "Illegal State, you should init first");
1030  return;
1031  }
1032  if (mPushStatus != AlivcLivePushStats.INIT && mPushStatus != AlivcLivePushStats.PREVIEWED) {
1033  AlivcLog.e(TAG, "status error current state is " + AlivcLivePushStats.values()[mPushStatus.ordinal()]);
1034  return;
1035  }
1036 
1037  this.mPreviewView = surfaceView;
1038  int result = 0;
1039  if (surfaceView == null) {
1040  result = mNativeAlivcLivePusher.startPreview(null, true);
1041  if (result == 0) {
1042  mPushStatus = AlivcLivePushStats.PREVIEWED;
1043  } else {
1044  AlivcLog.e(TAG, "start preview error");
1045  return;
1046  }
1047  } else {
1048  result = mNativeAlivcLivePusher.startPreview(surfaceView.getHolder().getSurface(), true);
1049  if (result == 0) {
1050  surfaceView.getHolder().addCallback(mPreviewCallback);
1051  mPushStatus = AlivcLivePushStats.PREVIEWED;
1052  } else {
1053  AlivcLog.e(TAG, "start preview error");
1054  }
1055  }
1056  }
1057 
1058  @Override
1059  public void startPreviewAsync(SurfaceView surfaceView) throws IllegalArgumentException, IllegalStateException {
1060  AlivcLog.i(TAG, "[API-Pusher] startPreviewAsync");
1061 
1062  PusherStartPreviewEvent.Args args = new PusherStartPreviewEvent.Args();
1063  args.sync = false;
1064  if (mLiveEventReporter != null) {
1065  mLiveEventReporter.sendEvent(PusherStartPreviewEvent.kTopicType, PusherStartPreviewEvent.kTopicValue, PusherStartPreviewEvent.getArgsStr(args));
1066  }
1067 
1068  if (mNativeAlivcLivePusher == null) {
1069  AlivcLog.e(TAG, "Illegal State, you should init first");
1070  return;
1071  }
1072 
1073  if (mPushStatus != AlivcLivePushStats.INIT && mPushStatus != AlivcLivePushStats.PREVIEWED) {
1074  AlivcLog.e(TAG, "status error current state is " + AlivcLivePushStats.values()[mPushStatus.ordinal()]);
1075  return;
1076  }
1077 
1078  mPushStatus = AlivcLivePushStats.PREVIEWING;
1079  this.mPreviewView = surfaceView;
1080  int result = 0;
1081  if (surfaceView == null) {
1082  result = mNativeAlivcLivePusher.startPreview(null, false);
1083  if (result == 0) {
1084  mPushStatus = AlivcLivePushStats.PREVIEWED;
1085  } else {
1086  AlivcLog.e(TAG, "start preview async error");
1087  }
1088  } else {
1089  result = mNativeAlivcLivePusher.startPreview(surfaceView.getHolder().getSurface(), false);
1090  if (result == 0) {
1091  surfaceView.getHolder().addCallback(mPreviewCallback);
1092  mPushStatus = AlivcLivePushStats.PREVIEWED;
1093  } else {
1094  AlivcLog.e(TAG, "start preview async error");
1095  }
1096  }
1097  }
1098 
1099  @Override
1100  public void startPreview(Context context, FrameLayout frameLayout, boolean isAnchor) throws IllegalArgumentException, IllegalStateException {
1101 
1102  }
1103 
1104  @Override
1105  public void stopPreview() throws IllegalStateException {
1106  AlivcLog.i(TAG, "[API-Pusher] stopPreview");
1107  PusherStopPreviewEvent.Args args = null;
1108  if (mLiveEventReporter != null) {
1109  mLiveEventReporter.sendEvent(PusherStopPreviewEvent.kTopicType, PusherStopPreviewEvent.kTopicValue, PusherStopPreviewEvent.getArgsStr(args));
1110  }
1111 
1112  if (mNativeAlivcLivePusher == null) {
1113  AlivcLog.e(TAG, "Illegal State, you should init first");
1114  return;
1115  }
1116 
1117  mDynamicAddsonCount = 0;
1118 
1119  if (mPushStatus != AlivcLivePushStats.INIT && mPushStatus != AlivcLivePushStats.PREVIEWED) {
1120  AlivcLog.e(TAG, "status error current state is " + AlivcLivePushStats.values()[mPushStatus.ordinal()]);
1121  return;
1122  }
1123 
1124  int result = mNativeAlivcLivePusher.stopPreview();
1125  if (result == 0) {
1126  mPushStatus = AlivcLivePushStats.INIT;
1127  } else {
1128  AlivcLog.e(TAG, "stop preview error");
1129  }
1130  }
1131 
1132  @Override
1133  public void startPush(String url) throws IllegalArgumentException, IllegalStateException {
1134  AlivcLog.i(TAG, "[API-Pusher] startPush: " + url);
1135  if (mNativeAlivcLivePusher == null || mAlivcLivePushConfig == null) {
1136  AlivcLog.e(TAG, "Illegal State, you should init first");
1137  return;
1138  }
1139 
1140  url = AlivcLiveURLTools.trimUrl(url);
1141  if (!AlivcLiveURLTools.checkPushUrl(url)) {
1142  AlivcLog.e(TAG, "Illegal argument, push url error!");
1143  return;
1144  }
1145 
1146  if ((mAlivcLivePushConfig.isAudioOnly() || mAlivcLivePushConfig.isVideoOnly()) && url.startsWith(AlivcLiveStreamType.EnumType.AlivcLiveStreamRts.getPrefix())) {
1147  AlivcLog.e(TAG, "RTC protocol don't support audio/video only stream");
1148  return;
1149  }
1150 
1151  if ((mPushStatus != AlivcLivePushStats.PREVIEWED && mPushStatus != AlivcLivePushStats.INIT)
1152  && mPushStatus != AlivcLivePushStats.PUSHED) {
1153  AlivcLog.e(TAG, "status error current state is " + AlivcLivePushStats.values()[mPushStatus.ordinal()]);
1154  return;
1155  }
1156 
1157  if (mPushStatus.equals(AlivcLivePushStats.INIT)) {
1158  mPreviewView = null;
1159  int result = mNativeAlivcLivePusher.startPreview(null, true);
1160  if (result != 0) {
1161  AlivcLog.e(TAG, "start push error : create gl resource failed");
1162  return;
1163  }
1164  }
1165  mPushUrl = url;
1166  if (mPushUrl.contains(AUTH_KEY)) {
1167  getNetworkTime();
1168  }
1169 
1170  mLiveEventReporter.refreshPushId();
1171  int result = mNativeAlivcLivePusher.startPush(url, true);
1172  if (result == 0) {
1173  if (mPushStatus != AlivcLivePushStats.PUSHED) {
1174  mPushStatus = AlivcLivePushStats.PUSHED;
1175  if (mAlivcLivePushConfig.getMediaProjectionPermissionResultData() != null) {
1176  mScreenStatus = ScreenRecordStatus.SCREEN_RECORD_NORMAL;
1177  }
1178  }
1179  } else {
1180  AlivcLog.e(TAG, "start push error");
1181  return;
1182  }
1183 
1184  reportStartPushEvent(false, true);
1185 
1186  String pauseImage = mAlivcLivePushConfig.getPausePushImage() == null ? "" : mAlivcLivePushConfig.getPausePushImage();
1187  String networkImage = mAlivcLivePushConfig.getNetworkPoorPushImage() == null ? "" : mAlivcLivePushConfig.getNetworkPoorPushImage();
1188  mNativeAlivcLivePusher.addPushImage(pauseImage, networkImage);
1189  startScheduleExecutor();
1190  }
1191 
1192  @Override
1193  public void startPushAsync(String url) throws IllegalArgumentException, IllegalStateException {
1194  AlivcLog.i(TAG, "[API-Pusher] startPushAsync: " + url);
1195  if (mNativeAlivcLivePusher == null || mAlivcLivePushConfig == null) {
1196  AlivcLog.e(TAG, "Illegal State, you should init first");
1197  return;
1198  }
1199 
1200  url = AlivcLiveURLTools.trimUrl(url);
1201  if (!AlivcLiveURLTools.checkPushUrl(url)) {
1202  AlivcLog.e(TAG, "Illegal argument, push url error!");
1203  return;
1204  }
1205 
1206  if ((mPushStatus != AlivcLivePushStats.PREVIEWED && mPushStatus != AlivcLivePushStats.INIT)
1207  && mPushStatus != AlivcLivePushStats.PUSHED) {
1208  AlivcLog.e(TAG, "status error current state is " + AlivcLivePushStats.values()[mPushStatus.ordinal()]);
1209  return;
1210  }
1211 
1212  if ((mAlivcLivePushConfig.isAudioOnly() || mAlivcLivePushConfig.isVideoOnly()) && url.startsWith(AlivcLiveStreamType.EnumType.AlivcLiveStreamRts.getPrefix())) {
1213  AlivcLog.e(TAG, "RTC protocol don't support audio/video only stream");
1214  return;
1215  }
1216 
1217  if (mPushStatus.equals(AlivcLivePushStats.INIT)) {
1218  mPreviewView = null;
1219  int result = mNativeAlivcLivePusher.startPreview(null, true);
1220  if (result != 0) {
1221  AlivcLog.e(TAG, "start push error : create gl resource failed");
1222  return;
1223  }
1224  }
1225 
1226  mPushUrl = url;
1227  if (mPushUrl.contains(AUTH_KEY)) {
1228  getNetworkTime();
1229  }
1230 
1231  mLiveEventReporter.refreshPushId();
1232  int result = mNativeAlivcLivePusher.startPush(url, false);
1233  if (result == 0) {
1234  if (mPushStatus != AlivcLivePushStats.PUSHED) {
1235  mPushStatus = AlivcLivePushStats.PUSHED;
1236  if (mAlivcLivePushConfig.getMediaProjectionPermissionResultData() != null) {
1237  mScreenStatus = ScreenRecordStatus.SCREEN_RECORD_NORMAL;
1238  }
1239  }
1240  } else {
1241  AlivcLog.e(TAG, "start push async error");
1242  return;
1243  }
1244 
1245  reportStartPushEvent(false, false);
1246 
1247  String pauseImage = mAlivcLivePushConfig.getPausePushImage() == null ? "" : mAlivcLivePushConfig.getPausePushImage();
1248  String networkImage = mAlivcLivePushConfig.getNetworkPoorPushImage() == null ? "" : mAlivcLivePushConfig.getNetworkPoorPushImage();
1249  mNativeAlivcLivePusher.addPushImage(pauseImage, networkImage);
1250  startScheduleExecutor();
1251  }
1252 
1253  @Override
1254  public void restartPush() throws IllegalStateException {
1255  AlivcLog.i(TAG, "[API-Pusher] restartPush");
1256  if (mNativeAlivcLivePusher == null || mAlivcLivePushConfig == null) {
1257  AlivcLog.e(TAG, "Illegal State, you should init first");
1258  return;
1259  }
1260 
1261  if (mPreviewView == null && mAlivcLivePushConfig.getMediaProjectionPermissionResultData() == null
1262  && !mAlivcLivePushConfig.isAudioOnly()) {
1263  AlivcLog.e(TAG, "illegal argument");
1264  return;
1265  }
1266 
1267  if ((mAlivcLivePushConfig.isAudioOnly() || mAlivcLivePushConfig.isVideoOnly())
1268  && (!TextUtils.isEmpty(mPushUrl) && mPushUrl.startsWith(AlivcLiveStreamType.EnumType.AlivcLiveStreamRts.getPrefix()))) {
1269  AlivcLog.e(TAG, "RTC protocol don't support audio/video only stream");
1270  return;
1271  }
1272 
1273  if (mPushStatus != AlivcLivePushStats.PUSHED && mPushStatus != AlivcLivePushStats.ERROR) {
1274  AlivcLog.e(TAG, "status error current state is " + AlivcLivePushStats.values()[mPushStatus.ordinal()]);
1275  return;
1276  }
1277 
1278  mDynamicAddsonCount = 0;
1279 
1280  stopScheduleExecutor();
1281 
1282  Surface surface = mPreviewView != null ? mPreviewView.getHolder().getSurface() : null;
1283  int result = mNativeAlivcLivePusher.restartPush(surface, true, 1000);
1284  if (result == 0) {
1285  mPushStatus = AlivcLivePushStats.PUSHED;
1286  if (mAlivcLivePushConfig.getMediaProjectionPermissionResultData() != null) {
1287  mScreenStatus = ScreenRecordStatus.SCREEN_RECORD_NORMAL;
1288  }
1289  } else {
1290  AlivcLog.e(TAG, "restart push error");
1291  return;
1292  }
1293  String pauseImage = mAlivcLivePushConfig.getPausePushImage() == null ? "" : mAlivcLivePushConfig.getPausePushImage();
1294  String networkImage = mAlivcLivePushConfig.getNetworkPoorPushImage() == null ? "" : mAlivcLivePushConfig.getNetworkPoorPushImage();
1295  mNativeAlivcLivePusher.addPushImage(pauseImage, networkImage);
1296 
1297  reportStartPushEvent(true, true);
1298 
1299  startScheduleExecutor();
1300 
1301  }
1302 
1303  @Override
1304  public void restartPushAsync() throws IllegalStateException {
1305  AlivcLog.i(TAG, "[API-Pusher] restartPushAsync");
1306  if (mNativeAlivcLivePusher == null || mAlivcLivePushConfig == null) {
1307  AlivcLog.e(TAG, "Illegal State, you should init first");
1308  return;
1309  }
1310 
1311  if (mPreviewView == null && mAlivcLivePushConfig.getMediaProjectionPermissionResultData() == null
1312  && !mAlivcLivePushConfig.isAudioOnly()) {
1313  AlivcLog.e(TAG, "illegal argument");
1314  return;
1315  }
1316 
1317  if ((mAlivcLivePushConfig.isAudioOnly() || mAlivcLivePushConfig.isVideoOnly())
1318  && (!TextUtils.isEmpty(mPushUrl) && mPushUrl.startsWith(AlivcLiveStreamType.EnumType.AlivcLiveStreamRts.getPrefix()))) {
1319  AlivcLog.e(TAG, "RTC protocol don't support audio/video only stream");
1320  return;
1321  }
1322 
1323  if (mPushStatus != AlivcLivePushStats.PUSHED && mPushStatus != AlivcLivePushStats.ERROR) {
1324  AlivcLog.e(TAG, "status error current state is " + AlivcLivePushStats.values()[mPushStatus.ordinal()]);
1325  return;
1326  }
1327 
1328  Surface surface = mPreviewView != null ? mPreviewView.getHolder().getSurface() : null;
1329  int result = mNativeAlivcLivePusher.restartPush(surface, false, 1000);
1330  if (result == 0) {
1331  mPushStatus = AlivcLivePushStats.RESTARTING;
1332  } else {
1333  AlivcLog.e(TAG, "restart push async error");
1334  return;
1335  }
1336  String pauseImage = mAlivcLivePushConfig.getPausePushImage() == null ? "" : mAlivcLivePushConfig.getPausePushImage();
1337  String networkImage = mAlivcLivePushConfig.getNetworkPoorPushImage() == null ? "" : mAlivcLivePushConfig.getNetworkPoorPushImage();
1338  mNativeAlivcLivePusher.addPushImage(pauseImage, networkImage);
1339 
1340  stopScheduleExecutor();
1341 
1342  reportStartPushEvent(true, false);
1343 
1344  startScheduleExecutor();
1345  }
1346 
1347  @Override
1348  public void reconnectPushAsync(String url) throws IllegalStateException {
1349  AlivcLog.i(TAG, "[API-Pusher] reconnectPushAsync");
1350  if (mNativeAlivcLivePusher == null || mAlivcLivePushConfig == null) {
1351  AlivcLog.e(TAG, "Illegal State, you should init first");
1352  return;
1353  }
1354 
1355  url = AlivcLiveURLTools.trimUrl(url);
1356  if (!AlivcLiveURLTools.checkPushUrl(url)) {
1357  return;
1358  }
1359 
1360  if (mPushStatus != AlivcLivePushStats.PUSHED && mPushStatus != AlivcLivePushStats.PAUSED &&
1361  mPushStatus != AlivcLivePushStats.ERROR) {
1362  AlivcLog.e(TAG, "status error current state is " + AlivcLivePushStats.values()[mPushStatus.ordinal()]);
1363  return;
1364  }
1365 
1366  if (isNetworkPushing()) {
1367  return;
1368  }
1369  mPushUrl = url;
1370  getNetworkTime();
1371 
1372  int result = mNativeAlivcLivePusher.reconnect(url, false);
1373  if (result == 0) {
1374  isReconnect = false;
1375  if (mHandler != null) {
1376  mHandler.removeMessages(MESSAGE_RECONNECT_SUCCESS);
1377  }
1378  mPushStatus = AlivcLivePushStats.PUSHED;
1379  if (mAlivcLivePushConfig.getMediaProjectionPermissionResultData() != null) {
1380  mScreenStatus = ScreenRecordStatus.SCREEN_RECORD_NORMAL;
1381  }
1382  } else {
1383  AlivcLog.e(TAG, "reconnect push async error");
1384  return;
1385  }
1386 
1387  //重新连接推流
1388  PusherReconnectEvent.Args args = new PusherReconnectEvent.Args();
1389  Map map = getPerformanceMap();
1390  if (map != null) {
1391  args.vutMs = getLong(map, "mVideoDurationFromeCaptureToUpload");
1392  args.autMs = getLong(map, "mAudioDurationFromeCaptureToUpload");
1393  if (mLiveEventReporter != null) {
1394  mLiveEventReporter.sendEvent(PusherReconnectEvent.kTopicType, PusherReconnectEvent.kTopicValue, PusherReconnectEvent.getArgsStr(args));
1395  }
1396  }
1397  }
1398 
1399  @Override
1400  public void stopPush() throws IllegalStateException {
1401  AlivcLog.i(TAG, "[API-Pusher] stopPush");
1402  PusherStopPushEvent.Args args = new PusherStopPushEvent.Args();
1403  Map map = getPerformanceMap();
1404  if (map != null) {
1405  args.totalUploadSize = ParameterUtil.getLong(map, "mTotalSizeOfUploadedPackets");
1406  args.totalTime = ParameterUtil.getLong(map, "mTotalTimeOfPublishing");
1407  if (mLiveEventReporter != null) {
1408  mLiveEventReporter.sendEvent(PusherStopPushEvent.kTopicType, PusherStopPushEvent.kTopicValue, PusherStopPushEvent.getArgsStr(args));
1409  }
1410  }
1411 
1412  if (mNativeAlivcLivePusher == null) {
1413  AlivcLog.e(TAG, "Illegal State, you should init first");
1414  return;
1415  }
1416  if (mPushStatus != AlivcLivePushStats.PREVIEWED && mPushStatus != AlivcLivePushStats.PUSHED
1417  && mPushStatus != AlivcLivePushStats.PAUSED && mPushStatus != AlivcLivePushStats.ERROR) {
1418  AlivcLog.e(TAG, "status error current state is " + AlivcLivePushStats.values()[mPushStatus.ordinal()]);
1419  return;
1420  }
1421 
1422  int result = mNativeAlivcLivePusher.stopPush();
1423  if (result == 0) {
1424  mPushStatus = AlivcLivePushStats.PREVIEWED;
1425  } else {
1426  AlivcLog.e(TAG, "stop push error");
1427  return;
1428  }
1429  if (mPreviewView == null) {
1430  mNativeAlivcLivePusher.stopPreview();
1431  mPushStatus = AlivcLivePushStats.INIT;
1432  }
1433  stopScheduleExecutor();
1434  }
1435 
1436  @Override
1437  public void pause() throws IllegalStateException {
1438  AlivcLog.i(TAG, "[API-Pusher] pause");
1439  if (mNativeAlivcLivePusher == null || mAlivcLivePushConfig == null) {
1440  AlivcLog.e(TAG, "Illegal State, you should init first");
1441  return;
1442  }
1443  if (mAlivcLivePushConfig.isExternMainStream()) {
1444  return;
1445  }
1446  if (mPushStatus != AlivcLivePushStats.PUSHED && mPushStatus != AlivcLivePushStats.PAUSED
1447  && mPushStatus != AlivcLivePushStats.PREVIEWED) {
1448  AlivcLog.e(TAG, "status error current state is " + AlivcLivePushStats.values()[mPushStatus.ordinal()]);
1449  return;
1450  }
1451  mPushStatus = AlivcLivePushStats.PAUSED;
1452 
1453  mNativeAlivcLivePusher.pause();
1454 
1455  //reclock pause time
1456  PusherPauseEvent.mLastPauseTime = System.currentTimeMillis();
1457  PusherPauseEvent.Args args = new PusherPauseEvent.Args();
1458  Map map = getPerformanceMap();
1459  if (map != null) {
1460  args.isPauseScreen = false;
1461  args.totalUploadSize = ParameterUtil.getLong(map, "mTotalSizeOfUploadedPackets");
1462  args.totalTime = ParameterUtil.getLong(map, "mTotalTimeOfPublishing");
1463  if (mLiveEventReporter != null) {
1464  mLiveEventReporter.sendEvent(PusherPauseEvent.kTopicType, PusherPauseEvent.kTopicValue, PusherPauseEvent.getArgsStr(args));
1465  }
1466  }
1467  }
1468 
1469  @Override
1470  public void resume() throws IllegalStateException {
1471  AlivcLog.i(TAG, "[API-Pusher] resume");
1472  if (mNativeAlivcLivePusher == null || mAlivcLivePushConfig == null) {
1473  AlivcLog.e(TAG, "Illegal State, you should init first");
1474  return;
1475  }
1476  if (mAlivcLivePushConfig.isExternMainStream()) {
1477  return;
1478  }
1479  if (mPushStatus != AlivcLivePushStats.PAUSED && mPushStatus != AlivcLivePushStats.ERROR) {
1480  AlivcLog.e(TAG, "status error current state is " + AlivcLivePushStats.values()[mPushStatus.ordinal()]);
1481  return;
1482  }
1483 
1484  mNativeAlivcLivePusher.resume(true);
1485  PusherResumeEvent.Args args = new PusherResumeEvent.Args();
1486  Map map = getPerformanceMap();
1487  if (map != null) {
1488  args.sync = true;
1489  args.isResumeScreen = false;
1490  args.totalUploadSize = ParameterUtil.getLong(map, "mTotalSizeOfUploadedPackets");
1491  args.totalTime = ParameterUtil.getLong(map, "mTotalTimeOfPublishing");
1492  if (PusherPauseEvent.mLastPauseTime == 0) {
1493  args.cost = 0;
1494  } else {
1495  args.cost = System.currentTimeMillis() - PusherPauseEvent.mLastPauseTime;
1496  }
1497  if (mLiveEventReporter != null) {
1498  mLiveEventReporter.sendEvent(PusherResumeEvent.kTopicType, PusherResumeEvent.kTopicValue, PusherResumeEvent.getArgsStr(args));
1499  }
1500  }
1501  //reset to 0
1502  PusherPauseEvent.mLastPauseTime = 0;
1503 
1504  if (mNativeAlivcLivePusher.isPushing()) {
1505  mPushStatus = AlivcLivePushStats.PUSHED;
1506  } else {
1507  mPushStatus = AlivcLivePushStats.PREVIEWED;
1508  }
1509  }
1510 
1511  @Override
1512  public void resumeAsync() throws IllegalStateException {
1513  AlivcLog.i(TAG, "[API-Pusher] resumeAsync");
1514  if (mNativeAlivcLivePusher == null || mAlivcLivePushConfig == null) {
1515  AlivcLog.e(TAG, "Illegal State, you should init first");
1516  return;
1517  }
1518  if (mAlivcLivePushConfig.isExternMainStream()) {
1519  return;
1520  }
1521  if (mPushStatus != AlivcLivePushStats.PAUSED && mPushStatus != AlivcLivePushStats.ERROR) {
1522  AlivcLog.e(TAG, "status error current state is " + AlivcLivePushStats.values()[mPushStatus.ordinal()]);
1523  return;
1524  }
1525  mPushStatus = AlivcLivePushStats.RESUMING;
1526  mNativeAlivcLivePusher.resume(false);
1527  PusherResumeEvent.Args args = new PusherResumeEvent.Args();
1528  Map map = getPerformanceMap();
1529  if (map != null) {
1530  args.sync = false;
1531  args.isResumeScreen = false;
1532  args.totalUploadSize = ParameterUtil.getLong(map, "mTotalSizeOfUploadedPackets");
1533  args.totalTime = ParameterUtil.getLong(map, "mTotalTimeOfPublishing");
1534  if (PusherPauseEvent.mLastPauseTime == 0) {
1535  args.cost = 0;
1536  } else {
1537  args.cost = System.currentTimeMillis() - PusherPauseEvent.mLastPauseTime;
1538  }
1539  if (mLiveEventReporter != null) {
1540  mLiveEventReporter.sendEvent(PusherResumeEvent.kTopicType, PusherResumeEvent.kTopicValue, PusherResumeEvent.getArgsStr(args));
1541  }
1542  }
1543  //reset to 0
1544  PusherPauseEvent.mLastPauseTime = 0;
1545  }
1546 
1547  @Override
1548  public void pauseScreenCapture() throws IllegalStateException {
1549  AlivcLog.i(TAG, "[API-Pusher] pauseScreenCapture");
1550  if (mNativeAlivcLivePusher == null) {
1551  AlivcLog.e(TAG, "Illegal State, you should init first");
1552  return;
1553  }
1554  if (mPushStatus != AlivcLivePushStats.PUSHED && mPushStatus != AlivcLivePushStats.PAUSED
1555  && mPushStatus != AlivcLivePushStats.PREVIEWED) {
1556  AlivcLog.e(TAG, "status error current state is " + AlivcLivePushStats.values()[mPushStatus.ordinal()]);
1557  return;
1558  }
1559  mPushStatus = AlivcLivePushStats.PAUSED;
1560 
1561  //reclock pause time
1562  PusherPauseEvent.mLastPauseTime = System.currentTimeMillis();
1563 
1564  mNativeAlivcLivePusher.pauseScreenCapture();
1565  PusherPauseEvent.Args args = new PusherPauseEvent.Args();
1566  Map map = getPerformanceMap();
1567  if (map != null) {
1568  args.isPauseScreen = true;
1569  args.totalUploadSize = ParameterUtil.getLong(map, "mTotalSizeOfUploadedPackets");
1570  args.totalTime = ParameterUtil.getLong(map, "mTotalTimeOfPublishing");
1571  if (mLiveEventReporter != null) {
1572  mLiveEventReporter.sendEvent(PusherPauseEvent.kTopicType, PusherPauseEvent.kTopicValue, PusherPauseEvent.getArgsStr(args));
1573  }
1574  }
1575  }
1576 
1577  @Override
1578  public void resumeScreenCapture() throws IllegalStateException {
1579  AlivcLog.i(TAG, "[API-Pusher] resumeScreenCapture");
1580  if (mNativeAlivcLivePusher == null) {
1581  AlivcLog.e(TAG, "Illegal State, you should init first");
1582  return;
1583  }
1584  if (mPushStatus != AlivcLivePushStats.PAUSED) {
1585  AlivcLog.e(TAG, "status error current state is " + AlivcLivePushStats.values()[mPushStatus.ordinal()]);
1586  return;
1587  }
1588 
1589  mNativeAlivcLivePusher.resumeScreenCapture();
1590  PusherResumeEvent.Args args = new PusherResumeEvent.Args();
1591  Map map = getPerformanceMap();
1592  if (map != null) {
1593  args.sync = true;
1594  args.isResumeScreen = true;
1595  args.totalUploadSize = ParameterUtil.getLong(map, "mTotalSizeOfUploadedPackets");
1596  args.totalTime = ParameterUtil.getLong(map, "mTotalTimeOfPublishing");
1597  args.cost = System.currentTimeMillis() - PusherPauseEvent.mLastPauseTime;
1598  if (mLiveEventReporter != null) {
1599  mLiveEventReporter.sendEvent(PusherResumeEvent.kTopicType, PusherResumeEvent.kTopicValue, PusherResumeEvent.getArgsStr(args));
1600  }
1601  }
1602  //reset to 0
1603  PusherPauseEvent.mLastPauseTime = 0;
1604 
1605  if (mNativeAlivcLivePusher.isPushing()) {
1606  mPushStatus = AlivcLivePushStats.PUSHED;
1607  } else {
1608  mPushStatus = AlivcLivePushStats.PREVIEWED;
1609  }
1610  }
1611 
1612  @Override
1613  public void switchCamera() throws IllegalStateException {
1614  AlivcLog.i(TAG, "[API-Pusher] switchCamera");
1615  if (mNativeAlivcLivePusher == null || mAlivcLivePushConfig == null) {
1616  AlivcLog.e(TAG, "Illegal State, you should init first");
1617  return;
1618  }
1619  if (mPushStatus != AlivcLivePushStats.PREVIEWED && mPushStatus != AlivcLivePushStats.PUSHED) {
1620  AlivcLog.e(TAG, "status error current state is " + AlivcLivePushStats.values()[mPushStatus.ordinal()]);
1621  return;
1622  }
1623  mNativeAlivcLivePusher.switchCamera();
1624 
1625  if (mAlivcLivePushConfig.getCameraType() == CAMERA_TYPE_FRONT.getCameraId()) {
1626  mAlivcLivePushConfig.setCameraType(CAMERA_TYPE_BACK);
1627  } else {
1628  mAlivcLivePushConfig.setCameraType(CAMERA_TYPE_FRONT);
1629  }
1630 
1631  //send switch camera
1632  PusherSwitchCameraEvent.Args args = new PusherSwitchCameraEvent.Args();
1633  args.isFrontCamera = mAlivcLivePushConfig.getCameraType() == CAMERA_TYPE_FRONT.getCameraId();
1634  if (mLiveEventReporter != null) {
1635  mLiveEventReporter.sendEvent(PusherSwitchCameraEvent.kTopicType, PusherSwitchCameraEvent.kTopicValue, PusherSwitchCameraEvent.getArgsStr(args));
1636  }
1637  }
1638 
1639  @Override
1640  public void setAutoFocus(boolean autoFocus) throws IllegalStateException {
1641  AlivcLog.i(TAG, "[API-Pusher] setAutoFocus: " + autoFocus);
1642  if (mNativeAlivcLivePusher == null) {
1643  AlivcLog.e(TAG, "Illegal State, you should init first");
1644  return;
1645  }
1646  if (mPushStatus != AlivcLivePushStats.PREVIEWED && mPushStatus != AlivcLivePushStats.PUSHED) {
1647  AlivcLog.e(TAG, "status error current state is " + AlivcLivePushStats.values()[mPushStatus.ordinal()]);
1648  return;
1649  }
1650  mNativeAlivcLivePusher.setCameraFocus(autoFocus, 0, 0);
1651  }
1652 
1653  @Override
1654  public void focusCameraAtAdjustedPoint(float x, float y, boolean autoFocus) throws IllegalStateException {
1655  AlivcLog.i(TAG, "[API-Pusher] focusCameraAtAdjustedPoint: x=" + x + ", y=" + y + ", autoFocus=" + autoFocus);
1656  if (mNativeAlivcLivePusher == null) {
1657  AlivcLog.e(TAG, "Illegal State, you should init first");
1658  return;
1659  }
1660  if (mPushStatus != AlivcLivePushStats.PREVIEWED && mPushStatus != AlivcLivePushStats.PUSHED) {
1661  AlivcLog.e(TAG, "status error current state is " + AlivcLivePushStats.values()[mPushStatus.ordinal()]);
1662  return;
1663  }
1664  mNativeAlivcLivePusher.setCameraFocus(autoFocus, x, y);
1665  }
1666 
1667  @Override
1668  public void setExposure(int exposure) {
1669  AlivcLog.i(TAG, "[API-Pusher] setExposure: " + exposure);
1670  if (mNativeAlivcLivePusher == null) {
1671  AlivcLog.e(TAG, "Illegal State, you should init first");
1672  return;
1673  }
1674  if (mPushStatus != AlivcLivePushStats.PREVIEWED && mPushStatus != AlivcLivePushStats.PUSHED) {
1675  AlivcLog.e(TAG, "status error current state is " + AlivcLivePushStats.values()[mPushStatus.ordinal()]);
1676  return;
1677  }
1678  mNativeAlivcLivePusher.setExposureCompensation(exposure);
1679  }
1680 
1681  @Override
1682  public int getCurrentExposure() {
1683  AlivcLog.i(TAG, "[API-Pusher] getCurrentExposure");
1684  if (mNativeAlivcLivePusher == null) {
1685  AlivcLog.e(TAG, "Illegal State, you should init first");
1686  return -1;
1687  }
1688  if (mPushStatus != AlivcLivePushStats.PREVIEWED && mPushStatus != AlivcLivePushStats.PUSHED) {
1689  AlivcLog.e(TAG, "status error current state is " + AlivcLivePushStats.values()[mPushStatus.ordinal()]);
1690  return -1;
1691  }
1692  return mNativeAlivcLivePusher.getCurrentExposureCompensation();
1693  }
1694 
1695  @Override
1696  public int getSupportedMinExposure() {
1697  AlivcLog.i(TAG, "[API-Pusher] getSupportedMinExposure");
1698  if (mNativeAlivcLivePusher == null) {
1699  AlivcLog.e(TAG, "Illegal State, you should init first");
1700  return -1;
1701  }
1702  if (mPushStatus != AlivcLivePushStats.PREVIEWED && mPushStatus != AlivcLivePushStats.PUSHED) {
1703  AlivcLog.e(TAG, "status error current state is " + AlivcLivePushStats.values()[mPushStatus.ordinal()]);
1704  return -1;
1705  }
1706  return mNativeAlivcLivePusher.getMinExposureCompensation();
1707  }
1708 
1709  @Override
1710  public int getSupportedMaxExposure() {
1711  AlivcLog.i(TAG, "[API-Pusher] getSupportedMaxExposure");
1712  if (mNativeAlivcLivePusher == null) {
1713  AlivcLog.e(TAG, "Illegal State, you should init first");
1714  return -1;
1715  }
1716  if (mPushStatus != AlivcLivePushStats.PREVIEWED && mPushStatus != AlivcLivePushStats.PUSHED) {
1717  AlivcLog.e(TAG, "status error current state is " + AlivcLivePushStats.values()[mPushStatus.ordinal()]);
1718  return -1;
1719  }
1720  return mNativeAlivcLivePusher.getMaxExposureCompensation();
1721  }
1722 
1723  @Override
1724  public int setLiveMixTranscodingConfig(AlivcLiveTranscodingConfig config) {
1725  return -1;
1726  }
1727 
1728  @Override
1729  public int muteLocalCamera(boolean mute) {
1730  // TODO need implement
1731  return -1;
1732  }
1733 
1734  @Override
1735  public int enableSpeakerphone(boolean enable) {
1736  // TODO need implement
1737  return -1;
1738  }
1739 
1740  @Override
1741  public boolean isSpeakerphoneOn() {
1742  // TODO need implement
1743  return false;
1744  }
1745 
1746  @Override
1747  public void setZoom(int zoom) throws IllegalStateException {
1748  AlivcLog.i(TAG, "[API-Pusher] setZoom: " + zoom);
1749  if (mNativeAlivcLivePusher == null) {
1750  AlivcLog.e(TAG, "Illegal State, you should init first");
1751  return;
1752  }
1753  if (mPushStatus != AlivcLivePushStats.PREVIEWED && mPushStatus != AlivcLivePushStats.PUSHED) {
1754  AlivcLog.e(TAG, "status error current state is " + AlivcLivePushStats.values()[mPushStatus.ordinal()]);
1755  return;
1756  }
1757  mNativeAlivcLivePusher.setCameraZoom(zoom);
1758  }
1759 
1760  @Override
1761  public int getMaxZoom() throws IllegalStateException {
1762  AlivcLog.i(TAG, "[API-Pusher] getMaxZoom");
1763  if (mNativeAlivcLivePusher == null) {
1764  AlivcLog.e(TAG, "Illegal State, you should init first");
1765  return -1;
1766  }
1767  if (mPushStatus != AlivcLivePushStats.PREVIEWED && mPushStatus != AlivcLivePushStats.PUSHED) {
1768  AlivcLog.e(TAG, "status error current state is " + AlivcLivePushStats.values()[mPushStatus.ordinal()]);
1769  return -1;
1770  }
1771  return mNativeAlivcLivePusher.getCameraMaxZoom();
1772  }
1773 
1774  @Override
1775  public int getCurrentZoom() throws IllegalStateException {
1776  AlivcLog.i(TAG, "[API-Pusher] getCurrentZoom");
1777  if (mNativeAlivcLivePusher == null) {
1778  AlivcLog.e(TAG, "Illegal State, you should init first");
1779  return -1;
1780  }
1781  if (mPushStatus != AlivcLivePushStats.PREVIEWED && mPushStatus != AlivcLivePushStats.PUSHED) {
1782  AlivcLog.e(TAG, "status error current state is " + AlivcLivePushStats.values()[mPushStatus.ordinal()]);
1783  return -1;
1784  }
1785 
1786  return mNativeAlivcLivePusher.getCameraCurrentZoom();
1787  }
1788 
1789  @Override
1790  public void setMute(boolean mute) throws IllegalStateException {
1791  AlivcLog.i(TAG, "[API-Pusher] setMute: " + mute);
1792  if (mNativeAlivcLivePusher == null || mAlivcLivePushConfig == null) {
1793  AlivcLog.e(TAG, "Illegal State, you should init first");
1794  return;
1795  }
1796  if (mPushStatus != AlivcLivePushStats.PREVIEWED && mPushStatus != AlivcLivePushStats.PUSHED && mPushStatus != AlivcLivePushStats.PAUSED) {
1797  AlivcLog.e(TAG, "status error current state is " + AlivcLivePushStats.values()[mPushStatus.ordinal()]);
1798  return;
1799  }
1800  mNativeAlivcLivePusher.setMute(mute);
1801 
1802  mMute = mute;
1803  //send mute event
1804  if (mLiveEventReporter != null) {
1805  if (mute) {
1806  PusherMuteOnEvent.Args args = new PusherMuteOnEvent.Args();
1807  mLiveEventReporter.sendEvent(PusherMuteOffEvent.kTopicType, PusherMuteOffEvent.kTopicValue, PusherMuteOnEvent.getArgsStr(args));
1808  } else {
1809  PusherMuteOffEvent.Args args = new PusherMuteOffEvent.Args();
1810  mLiveEventReporter.sendEvent(PusherMuteOffEvent.kTopicType, PusherMuteOffEvent.kTopicValue, PusherMuteOffEvent.getArgsStr(args));
1811  }
1812  }
1813  }
1814 
1815  @Override
1816  public void setFlash(boolean flash) throws IllegalStateException {
1817  AlivcLog.i(TAG, "[API-Pusher] setFlash: " + flash);
1818  if (mNativeAlivcLivePusher == null || mAlivcLivePushConfig == null) {
1819  AlivcLog.e(TAG, "Illegal State, you should init first");
1820  return;
1821  }
1822  if (mPushStatus != AlivcLivePushStats.PREVIEWED && mPushStatus != AlivcLivePushStats.PUSHED) {
1823  AlivcLog.e(TAG, "status error current state is " + AlivcLivePushStats.values()[mPushStatus.ordinal()]);
1824  return;
1825  }
1826  mNativeAlivcLivePusher.setFlash(flash);
1827  mAlivcLivePushConfig.setFlash(flash);
1828  //send flash event
1829  PusherSetFlashEvent.Args args = new PusherSetFlashEvent.Args();
1830  args.isOpen = flash;
1831  if (mLiveEventReporter != null) {
1832  mLiveEventReporter.sendEvent(PusherSetFlashEvent.kTopicType, PusherSetFlashEvent.kTopicValue, PusherSetFlashEvent.getArgsStr(args));
1833  }
1834  }
1835 
1836  @Override
1837  public void setPushMirror(boolean mirror) throws IllegalStateException {
1838  AlivcLog.i(TAG, "[API-Pusher] setPushMirror: " + mirror);
1839  if (mNativeAlivcLivePusher == null) {
1840  AlivcLog.e(TAG, "Illegal State, you should init first");
1841  return;
1842  }
1843  if (mPushStatus != AlivcLivePushStats.PREVIEWED && mPushStatus != AlivcLivePushStats.PUSHED) {
1844  AlivcLog.e(TAG, "status error current state is " + AlivcLivePushStats.values()[mPushStatus.ordinal()]);
1845  return;
1846  }
1847  mNativeAlivcLivePusher.setPusherMirror(mirror);
1848  }
1849 
1850  @Override
1851  public void setPreviewMirror(boolean mirror) throws IllegalStateException {
1852  AlivcLog.i(TAG, "[API-Pusher] setPreviewMirror: " + mirror);
1853  if (mNativeAlivcLivePusher == null) {
1854  AlivcLog.e(TAG, "Illegal State, you should init first");
1855  return;
1856  }
1857  if (mPushStatus != AlivcLivePushStats.PREVIEWED && mPushStatus != AlivcLivePushStats.PUSHED) {
1858  AlivcLog.e(TAG, "status error current state is " + AlivcLivePushStats.values()[mPushStatus.ordinal()]);
1859  return;
1860  }
1861  mNativeAlivcLivePusher.setPreviewMirror(mirror);
1862  }
1863 
1864  @Override
1865  public void setTargetVideoBitrate(int targetVideoBitrate) throws IllegalArgumentException, IllegalStateException {
1866  AlivcLog.i(TAG, "[API-Pusher] setTargetVideoBitrate: " + targetVideoBitrate);
1867  if (mNativeAlivcLivePusher == null) {
1868  AlivcLog.e(TAG, "Illegal State, you should init first");
1869  return;
1870  }
1871  if (mPushStatus != AlivcLivePushStats.PREVIEWED && mPushStatus != AlivcLivePushStats.PUSHED) {
1872  AlivcLog.e(TAG, "status error current state is " + AlivcLivePushStats.values()[mPushStatus.ordinal()]);
1873  return;
1874  }
1875  mNativeAlivcLivePusher.setVideoBitrateRange(0, targetVideoBitrate, targetVideoBitrate);
1876  }
1877 
1878  @Override
1879  public void setMinVideoBitrate(int minVideoBitrate) throws IllegalArgumentException, IllegalStateException {
1880  AlivcLog.i(TAG, "[API-Pusher] setMinVideoBitrate: " + minVideoBitrate);
1881  if (mNativeAlivcLivePusher == null) {
1882  AlivcLog.e(TAG, "Illegal State, you should init first");
1883  return;
1884  }
1885  if (mPushStatus != AlivcLivePushStats.PREVIEWED && mPushStatus != AlivcLivePushStats.PUSHED) {
1886  AlivcLog.e(TAG, "status error current state is " + AlivcLivePushStats.values()[mPushStatus.ordinal()]);
1887  return;
1888  }
1889  mNativeAlivcLivePusher.setVideoBitrateRange(minVideoBitrate, 0, 0);
1890  }
1891 
1892  @Override
1893  public boolean isCameraSupportAutoFocus() {
1894  AlivcLog.i(TAG, "[API-Pusher] isCameraSupportAutoFocus");
1895  if (mNativeAlivcLivePusher == null) {
1896  AlivcLog.e(TAG, "Illegal State, you should init first");
1897  return false;
1898  }
1899  if (mPushStatus != AlivcLivePushStats.PREVIEWED && mPushStatus != AlivcLivePushStats.PUSHED) {
1900  AlivcLog.e(TAG, "status error current state is " + AlivcLivePushStats.values()[mPushStatus.ordinal()]);
1901  return false;
1902  }
1903  return mNativeAlivcLivePusher.isCameraSupportAutoFocus();
1904  }
1905 
1906  @Override
1907  public boolean isCameraSupportFlash() {
1908  AlivcLog.i(TAG, "[API-Pusher] isCameraSupportFlash");
1909 
1910  if (mNativeAlivcLivePusher == null) {
1911  AlivcLog.e(TAG, "Illegal State, you should init first");
1912  return false;
1913  }
1914  if (mPushStatus != AlivcLivePushStats.PREVIEWED && mPushStatus != AlivcLivePushStats.PUSHED) {
1915  AlivcLog.e(TAG, "status error current state is " + AlivcLivePushStats.values()[mPushStatus.ordinal()]);
1916  return false;
1917  }
1918  return mNativeAlivcLivePusher.isCameraSupportFlash();
1919  }
1920 
1921  @Override
1922  public boolean isPushing() throws IllegalStateException {
1923  if (mNativeAlivcLivePusher != null) {
1924  return mNativeAlivcLivePusher.isPushing();
1925  }
1926  return false;
1927  }
1928 
1929  @Override
1930  public AlivcLivePushStats getCurrentStatus() {
1931  return mPushStatus;
1932  }
1933 
1934  @Override
1935  public AlivcLivePushError getLastError() {
1936  return mLastError;
1937  }
1938 
1939  @Override
1940  public void snapshot(int count, int interval, AlivcSnapshotListener listener) {
1941  AlivcLog.i(TAG, "[API-Pusher] snapshot");
1942  mSnapshotListener = listener;
1943  if (mNativeAlivcLivePusher != null) {
1944  mNativeAlivcLivePusher.snapshot(count, interval, mInnerSnapshotListener);
1945  }
1946  }
1947 
1948  @Override
1949  public boolean isNetworkPushing() throws IllegalStateException {
1950  if (mNativeAlivcLivePusher != null) {
1951  return mNativeAlivcLivePusher.isNetworkPushing();
1952  }
1953  return false;
1954  }
1955 
1956  @Override
1957  public void setLivePushErrorListener(AlivcLivePushErrorListener errorListener) {
1958  AlivcLog.i(TAG, "[API-Pusher] setLivePushErrorListener");
1959  this.mPushErrorListener = errorListener;
1960  }
1961 
1962  @Override
1963  public void setLivePushInfoListener(AlivcLivePushInfoListener infoListener) {
1964  AlivcLog.i(TAG, "[API-Pusher] setLivePushInfoListener");
1965  this.mPushInfoListener = infoListener;
1966  }
1967 
1968  @Override
1969  public void setLivePushNetworkListener(AlivcLivePushNetworkListener networkListener) {
1970  AlivcLog.i(TAG, "[API-Pusher] setLivePushNetworkListener");
1971  this.mPushNetworkListener = networkListener;
1972  }
1973 
1974  @Override
1975  public void setLivePushBGMListener(AlivcLivePushBGMListener pushBGMListener) {
1976  AlivcLog.i(TAG, "[API-Pusher] setLivePushBGMListener");
1977  this.mPushBGMListener = pushBGMListener;
1978  }
1979 
1980  @Override
1981  public void setLivePushRenderContextListener(AlivcLivePusherRenderContextListener renderCtxListener) {
1982  AlivcLog.i(TAG, "[API-Pusher] setLivePushRenderContextListener");
1983  this.mRenderContextListener = renderCtxListener;
1984  }
1985 
1986  @Override
1987  public AlivcLivePushStatsInfo getLivePushStatsInfo() throws IllegalStateException {
1988  if (mNativeAlivcLivePusher == null) {
1989  return null;
1990  }
1991  AlivcLivePushStatsInfo info = new AlivcLivePushStatsInfo();
1992  String mapStr = mNativeAlivcLivePusher.getPerformanceInfo();
1993  if (mapStr == null || "".equals(mapStr)) {
1994  return null;
1995  }
1996  Map map = new HashMap<String, String>();
1997  StringTokenizer items;
1998  for (StringTokenizer entries = new StringTokenizer(mapStr, "|"); entries.hasMoreTokens();
1999  map.put(items.nextToken(), items.hasMoreTokens() ? ((String) (items.nextToken())) : null)) {
2000  items = new StringTokenizer(entries.nextToken(), ":");
2001  }
2002  try {
2003  info.setVideoCaptureFps(getInteger(map, "mVideoCaptureFps"));
2004  info.setAudioEncodeBitrate(getInteger(map, "mAudioEncodeBitrate"));
2005  info.setVideoRenderFps(getInteger(map, "mVideoRenderingFPS"));
2006  info.setAudioEncodeFps(getInteger(map, "mAudioEncodeFps"));
2007  info.setVideoEncodeMode(AlivcEncodeModeEnum.values()[getInteger(map, "mPresetVideoEncoderMode")]);
2008  info.setVideoEncodeBitrate(getInteger(map, "mVideoEncodeBitrate"));
2009  info.setVideoEncodeFps(getInteger(map, "mVideoEncodedFps"));
2010  info.setTotalFramesOfEncodedVideo(getLong(map, "mTotalFramesOfEncodedVideo"));
2011  info.setTotalTimeOfEncodedVideo(getLong(map, "mTotalTimeOfEncodedVideo"));
2012  info.setVideoEncodeParam(getInteger(map, "mPresetVideoEncoderBitrate"));
2013  info.setAudioUploadBitrate(getInteger(map, "mAudioUploadBitrate"));
2014  info.setVideoUploadBitrate(getInteger(map, "mVideoUploadBitrate"));
2015  info.setAudioPacketsInUploadBuffer(getInteger(map, "mAudioPacketsInBuffer"));
2016  info.setVideoPacketsInUploadBuffer(getInteger(map, "mVideoPacketsInBuffer"));
2017  info.setVideoUploadeFps(getInteger(map, "mVideoUploadedFps"));
2018  info.setAudioUploadFps(getInteger(map, "mAudioUploadingPacketsPerSecond"));
2019  info.setCurrentlyUploadedVideoFramePts(getLong(map, "mCurrentlyUploadedVideoFramePts"));
2020  info.setCurrentlyUploadedAudioFramePts(getLong(map, "mCurrentlyUploadedAudioFramePts"));
2021  info.setPreviousVideoKeyFramePts(getLong(map, "mPreviousKeyFramePts"));
2022  info.setLastVideoPtsInBuffer(getLong(map, "mLastVideoFramePTSInQueue"));
2023  info.setLastAudioPtsInBuffer(getLong(map, "mLastAudioFramePTSInQueue"));
2024  info.setTotalSizeOfUploadedPackets(getLong(map, "mTotalSizeOfUploadedPackets"));
2025  info.setTotalTimeOfUploading(getLong(map, "mTotalTimeOfPublishing"));
2026  info.setTotalFramesOfUploadedVideo(getLong(map, "mTotalFramesOfVideoUploaded"));
2027  info.setTotalDurationOfDropingVideoFrames(getLong(map, "mDropDurationOfVideoFrames"));
2028  info.setTotalTimesOfDropingVideoFrames(getLong(map, "mTotalDroppedTimes"));
2029  info.setTotalTimesOfDisconnect(getInteger(map, "mTotalNetworkDisconnectedTimes"));
2030  info.setTotalTimesOfReconnect(getInteger(map, "mTotalNetworkReconnectedTimes"));
2031  info.setVideoDurationFromeCaptureToUpload(getInteger(map, "mVideoDurationFromeCaptureToUpload"));
2032  info.setAudioDurationFromeCaptureToUpload(getInteger(map, "mAudioDurationFromeCaptureToUpload"));
2033  info.setCurrentUploadPacketSize(getInteger(map, "mCurrentUploadingPacketSize"));
2034  info.setMaxSizeOfVideoPacketsInBuffer(getInteger(map, "mMaxVideoPacketSize"));
2035  info.setMaxSizeOfAudioPacketsInBuffer(getInteger(map, "mMaxAudioPacketSize"));
2036  info.setLastVideoFramePTSInQueue(getLong(map, "mLastVideoFramePTSInQueue"));
2037  info.setLastAudioFramePTSInQueue(getLong(map, "mLastAudioFramePTSInQueue"));
2038  info.setAvPTSInterval(getLong(map, "mAvPTSInterval"));
2039  info.setAudioFrameInEncodeBuffer(getInteger(map, "mAudioFramesInEncoderQueue"));
2040  info.setVideoFramesInEncodeBuffer(getInteger(map, "mVideoFramesInEncoderQueue"));
2041  info.setVideoFramesInRenderBuffer(getInteger(map, "mVideoFramesInRenderQueue"));
2042  info.setVideoRenderConsumingTimePerFrame(getInteger(map, "mVideoRenderConsumingTimePerFrame"));
2043  info.setTotalDroppedAudioFrames(getInteger(map, "mTotalDroppedAudioFrames"));
2044  info.setRtt(getInteger(map, "mRtt"));
2045  info.setVideoLostRate(getInteger(map, "mVideoLostRate"));
2046  info.setAudioLostRate(getInteger(map, "mAudioLostRate"));
2047  info.setVideoReSendBitRate(getInteger(map, "mVideoReSendBitRate"));
2048  info.setAudioReSendBitRate(getInteger(map, "mAudioReSendBitRate"));
2049  info.setVideoEncodingWidth(getInteger(map, "mVideoEncodingWidth"));
2050  info.setVideoEncodingHeight(getInteger(map, "mVideoEncodingHeight"));
2051  info.setVideoEncodingGopSize(getInteger(map, "mVideoEncodingGopSize"));
2052  info.setAudioCapturingSampleRate(getInteger(map, "mAudioCapturingSampleRate"));
2053  info.setAudioCaptureVolume(getInteger(map, "mAudioCaptureVolume"));
2054 
2055  info.setCpu((float)AliLiveInfoUtils.getCPUUsageRatio());
2056  info.setMemory(ParameterUtil.getRunningAppProcessInfo(mContext));
2057  if (!TextUtils.isEmpty(mPushUrl)) {
2058  if (mPushUrl.startsWith(AlivcLiveStreamType.EnumType.AlivcLiveStreamRtmp.getPrefix())) {
2059  info.setAlivcLivePushPublishType(AlivcLiveStreamType.EnumType.AlivcLiveStreamRtmp.getValue());
2060  } else if (mPushUrl.startsWith(AlivcLiveStreamType.EnumType.AlivcLiveStreamRts.getPrefix())) {
2061  info.setAlivcLivePushPublishType(AlivcLiveStreamType.EnumType.AlivcLiveStreamRts.getValue());
2062  }
2063  }
2064  } catch (IllegalStateException e) {
2065  e.printStackTrace();
2066  } catch (Exception e) {
2067  e.printStackTrace();
2068  }
2069  return info;
2070  }
2071 
2072  @Override
2073  public String getPushUrl() {
2074  return AlivcLiveURLTools.getUrlWithoutParameters(mPushUrl);
2075  }
2076 
2077  private void checkConfig(AlivcLivePushConfig livePushConfig) throws IllegalStateException {
2078  if (livePushConfig == null) {
2079  throw new IllegalArgumentException("Invalid parameter, config is null.");
2080  }
2081 
2082  if (livePushConfig.isVideoOnly() && livePushConfig.isAudioOnly()) {
2083  throw new IllegalStateException("cannot set video only and audio only simultaneously");
2084  }
2085 
2086  if (livePushConfig.getTargetVideoBitrate() < 100 || livePushConfig.getTargetVideoBitrate() > 5000) {
2087  throw new IllegalStateException("video target bitrate error, Range:[100 5000]");
2088  }
2089  if (livePushConfig.getMinVideoBitrate() < 100 || livePushConfig.getMinVideoBitrate() > 5000) {
2090  throw new IllegalStateException("video min bitrate error, Range:[100 5000]");
2091  }
2092  if (livePushConfig.getInitialVideoBitrate() < livePushConfig.getMinVideoBitrate() || livePushConfig.getInitialVideoBitrate() < 100
2093  || livePushConfig.getInitialVideoBitrate() > 5000) {
2094  throw new IllegalStateException("init bitrate error");
2095  }
2096  if (livePushConfig.getConnectRetryCount() <= 0 || livePushConfig.getConnectRetryCount() > 100) {
2097  throw new IllegalStateException("connect retry count error, Range:[0 100]");
2098  }
2099  if (livePushConfig.getConnectRetryInterval() <= 0 || livePushConfig.getConnectRetryInterval() > 10000) {
2100  throw new IllegalStateException("connect retry interval error, Range:[0 10000]");
2101  }
2102 
2103  if (livePushConfig.getMinFps() <= 0 || livePushConfig.getMinFps() > livePushConfig.getFps()) {
2104  throw new IllegalStateException("fps error");
2105  }
2106 
2107  for (int i = 0; i < livePushConfig.getWaterMarkInfos().size(); i++) {
2108 
2109  if (livePushConfig.getWaterMarkInfos().get(i).mWaterMarkCoordX > 1 || livePushConfig.getWaterMarkInfos().get(i).mWaterMarkWidth > 1
2110  || livePushConfig.getWaterMarkInfos().get(i).mWaterMarkCoordY > 1 || livePushConfig.getWaterMarkInfos().get(i).mWaterMarkHeight > 1) {
2111  throw new IllegalStateException("watermark param error");
2112  }
2113 
2114  if (livePushConfig.getWaterMarkInfos().get(i).mWaterMarkCoordX < 0 || livePushConfig.getWaterMarkInfos().get(i).mWaterMarkWidth <= 0
2115  || livePushConfig.getWaterMarkInfos().get(i).mWaterMarkCoordY < 0 || livePushConfig.getWaterMarkInfos().get(i).mWaterMarkHeight <= 0) {
2116  throw new IllegalStateException("watermark param error");
2117  }
2118  }
2119  }
2120 
2121  @Override
2122  public void setPreviewOrientation(AlivcPreviewOrientationEnum orientation) {
2123  AlivcLog.i(TAG, "[API-Pusher] setPreviewOrientation: " + orientation);
2124  if (mNativeAlivcLivePusher == null) {
2125  AlivcLog.e(TAG, "Illegal State, you should init first");
2126  return;
2127  }
2128  if (mPushStatus != AlivcLivePushStats.PREVIEWED && mPushStatus != AlivcLivePushStats.PUSHED) {
2129  AlivcLog.e(TAG, "status error current state is " + AlivcLivePushStats.values()[mPushStatus.ordinal()]);
2130  return;
2131  }
2132 
2133  mNativeAlivcLivePusher.setOrientaion(orientation.getOrientation());
2134  }
2135 
2136  @Override
2137  public int setAudioEffectVoiceChangeMode(AlivcLivePushAudioEffectVoiceChangeMode mode) {
2138  AlivcLog.i(TAG, "[API-Pusher] setAudioEffectVoiceChangeMode: " + mode);
2139 
2140  if (mNativeAlivcLivePusher == null || mAlivcLivePushConfig == null) {
2141  AlivcLog.e(TAG, "Illegal State, you should init first");
2142  return -1;
2143  }
2144 
2145  if (mAlivcLivePushConfig.isVideoOnly()) {
2146  AlivcLog.e(TAG, "Sound effect can not be used on the video only mode!");
2147  return -1;
2148  }
2149 
2150  return mNativeAlivcLivePusher.setNativeAudioEffectVoiceMode(mode.getValue());
2151  }
2152 
2153  @Override
2154  public int setAudioEffectReverbMode(AlivcLivePushAudioEffectReverbMode mode) {
2155  AlivcLog.i(TAG, "[API-Pusher] setAudioEffectReverbMode: " + mode);
2156 
2157  if (mNativeAlivcLivePusher == null || mAlivcLivePushConfig == null) {
2158  AlivcLog.e(TAG, "Illegal State, you should init first");
2159  return -1;
2160  }
2161 
2162  if (mAlivcLivePushConfig.isVideoOnly()) {
2163  AlivcLog.e(TAG, "Sound effect can not be used on the video only mode!");
2164  return -1;
2165  }
2166 
2167  return mNativeAlivcLivePusher.setNativeAudioEffectReverbMode(mode.getValue());
2168  }
2169 
2170  private Map<String, String> getPerformanceMap() {
2171  if (mNativeAlivcLivePusher == null) {
2172  return null;
2173  }
2174  String mapStr = mNativeAlivcLivePusher.getPerformanceInfo();
2175  if (mapStr == null || "".equals(mapStr)) {
2176  return null;
2177  }
2178  Map map = new HashMap<String, String>();
2179  StringTokenizer items;
2180  for (StringTokenizer entries = new StringTokenizer(mapStr, "|"); entries.hasMoreTokens(); map
2181  .put(items.nextToken(), items.hasMoreTokens() ? ((String) (items.nextToken())) : null)) {
2182  items = new StringTokenizer(entries.nextToken(), ":");
2183  }
2184  return map;
2185  }
2186 
2187  private String getHeartBeatInfo() {
2188  if (mNativeAlivcLivePusher == null) {
2189  return null;
2190  }
2191 
2192  String heartBeatInfo = mNativeAlivcLivePusher.getPusherInfo();
2193  heartBeatInfo += ",cpu:" + AliLiveInfoUtils.getCPUUsageRatio();
2194  heartBeatInfo += ",mem:" + AliLiveInfoUtils.getMemoryUsageRatio();
2195 
2196  return heartBeatInfo;
2197  }
2198 
2199  @Override
2200  public String getLiveTraceId() {
2201  if (mNativeAlivcLivePusher == null) {
2202  return null;
2203  }
2204  return mNativeAlivcLivePusher.getPusherTraceId();
2205  }
2206 
2207  @Override
2208  public void sendMessage(String info, int repeat, int delay, boolean isKeyFrame) {
2209  AlivcLog.i(TAG, "[API-Pusher] sendMessage: " + info + ", repeat=" + repeat + ", delay=" + delay + ", isKeyFrame=" + isKeyFrame);
2210  try {
2211  sendMessageInternal(info, repeat, delay, isKeyFrame, false);
2212  } catch (Exception e) {
2213  e.printStackTrace();
2214  }
2215  }
2216 
2217  private void sendMessageInternal(String info, int repeat, int delay, boolean isKeyFrame, boolean isGDelayInfo) throws IllegalStateException, IllegalArgumentException {
2218  if (mNativeAlivcLivePusher == null) {
2219  AlivcLog.e(TAG, "Illegal State, you should init first");
2220  return;
2221  }
2222  if (!mNativeAlivcLivePusher.isPushing()) {
2223  AlivcLog.e(TAG, "Status error, status should be PUSHED");
2224  return;
2225  }
2226  if (TextUtils.isEmpty(info) || info.length() > MAX_CHATS) {
2227  AlivcLog.e(TAG, "The maximum length is 4000");
2228  return;
2229  }
2230  mNativeAlivcLivePusher.addSeiInfo(info, repeat, delay, isKeyFrame, isGDelayInfo);
2231  }
2232 
2233  private int getBGMVolume() {
2234  if (mMute) {
2235  return 0;
2236  }
2237  return mBGMVolume;
2238  }
2239 
2240  private int getCaptureVolume() {
2241  if (mMute) {
2242  return 0;
2243  }
2244  return mCaptureVolume;
2245  }
2246 
2247  private boolean getHeadSetPlugOn() {
2248  return LivePusherJNI.headSetOn;
2249  }
2250 
2251  private boolean getBlueToothHeadSetOn() {
2252  if (mBluetoothHelper != null) {
2253  return mBluetoothHelper.isOnHeadsetSco();
2254  }
2255  return false;
2256  }
2257 
2258  @Override
2259  public void startBGMAsync(String path) throws IllegalStateException {
2260  AlivcLog.i(TAG, "[API-Pusher] startBGMAsync");
2261  if (mNativeAlivcLivePusher == null) {
2262  AlivcLog.e(TAG, "Illegal State, you should init first");
2263  return;
2264  }
2265  if (mPushStatus == AlivcLivePushStats.IDLE || mPushStatus == AlivcLivePushStats.ERROR) {
2266  AlivcLog.e(TAG, "status error current state is " + AlivcLivePushStats.values()[mPushStatus.ordinal()]);
2267  return;
2268  }
2269 
2270  if (mPlayStats == AlivcLivePlayStats.IDLE || mPlayStats == AlivcLivePlayStats.STOPPED) {
2271  PusherSetBGMEvent.Args args = new PusherSetBGMEvent.Args();
2272  args.isOpen = true;
2273  args.music = getBGMVolume();
2274  args.voice = getCaptureVolume();
2275  if (mLiveEventReporter != null) {
2276  mLiveEventReporter.sendEvent(PusherSetBGMEvent.kTopicType, PusherSetBGMEvent.kTopicValue, PusherSetBGMEvent.getArgsStr(args));
2277  }
2278  }
2279 
2280  //mNativeAlivcLivePusher.resumeBGM();
2281  mNativeAlivcLivePusher.stopBGM();
2282  mNativeAlivcLivePusher.startBGMAsync(path);
2283  }
2284 
2285  @Override
2286  public void stopBGMAsync() throws IllegalStateException {
2287  AlivcLog.i(TAG, "[API-Pusher] stopBGMAsync");
2288  if (mNativeAlivcLivePusher == null) {
2289  AlivcLog.e(TAG, "Illegal State, you should init first");
2290  return;
2291  }
2292  if (mPlayStats == AlivcLivePlayStats.IDLE) {
2293  AlivcLog.e(TAG, "status error current state is " + AlivcLivePlayStats.values()[mPlayStats.ordinal()]);
2294  return;
2295  }
2296 
2297  mNativeAlivcLivePusher.stopBGM();
2298  PusherSetBGMEvent.Args args = new PusherSetBGMEvent.Args();
2299  args.isOpen = false;
2300  args.music = getBGMVolume();
2301  args.voice = getCaptureVolume();
2302  if (mLiveEventReporter != null) {
2303  mLiveEventReporter.sendEvent(PusherSetBGMEvent.kTopicType, PusherSetBGMEvent.kTopicValue, PusherSetBGMEvent.getArgsStr(args));
2304  }
2305  }
2306 
2307  @Override
2308  public void pauseBGM() throws IllegalStateException {
2309  AlivcLog.i(TAG, "[API-Pusher] pauseBGM");
2310  if (mNativeAlivcLivePusher == null) {
2311  AlivcLog.e(TAG, "Illegal State, you should init first");
2312  return;
2313  }
2314  if (mPlayStats != AlivcLivePlayStats.STARTED) {
2315  AlivcLog.e(TAG, "status error current state is " + AlivcLivePlayStats.values()[mPlayStats.ordinal()]);
2316  return;
2317  }
2318 
2319  mNativeAlivcLivePusher.pauseBGM();
2320  }
2321 
2322  @Override
2323  public void resumeBGM() throws IllegalStateException {
2324  AlivcLog.i(TAG, "[API-Pusher] resumeBGM");
2325  if (mNativeAlivcLivePusher == null) {
2326  AlivcLog.e(TAG, "Illegal State, you should init first");
2327  return;
2328  }
2329  if (mPlayStats != AlivcLivePlayStats.PAUSED) {
2330  AlivcLog.e(TAG, "status error current state is " + AlivcLivePlayStats.values()[mPlayStats.ordinal()]);
2331  return;
2332  }
2333 
2334  mNativeAlivcLivePusher.resumeBGM();
2335  }
2336 
2337  @Override
2338  public void setBGMLoop(boolean isLoop) throws IllegalStateException {
2339  AlivcLog.i(TAG, "[API-Pusher] setBGMLoop: " + isLoop);
2340  if (mNativeAlivcLivePusher != null) {
2341  mNativeAlivcLivePusher.setBGMLoop(isLoop);
2342  }
2343  PusherSetBGMLoopEvent.Args args = new PusherSetBGMLoopEvent.Args();
2344  args.value = isLoop;
2345  if (mLiveEventReporter != null) {
2346  mLiveEventReporter.sendEvent(PusherSetBGMLoopEvent.kTopicType, PusherSetBGMLoopEvent.kTopicValue, PusherSetBGMLoopEvent.getArgsStr(args));
2347  }
2348  }
2349 
2350  @Override
2351  public void setBGMEarsBack(boolean isOpen) throws IllegalStateException {
2352  AlivcLog.i(TAG, "[API-Pusher] setBGMEarsBack: " + isOpen);
2353  if (mNativeAlivcLivePusher != null) {
2354  mNativeAlivcLivePusher.setEarsBack(isOpen);
2355  }
2356  PusherSetBGMEarsBackEvent.Args args = new PusherSetBGMEarsBackEvent.Args();
2357  args.value = isOpen;
2358  args.bh = getBlueToothHeadSetOn() ? 1 : 0;
2359  args.eh = getHeadSetPlugOn() ? 1 : 0;
2360  if (mLiveEventReporter != null) {
2361  mLiveEventReporter.sendEvent(PusherSetBGMEarsBackEvent.kTopicType, PusherSetBGMEarsBackEvent.kTopicValue, PusherSetBGMEarsBackEvent.getArgsStr(args));
2362  }
2363  }
2364 
2365  @Override
2366  public void setBGMVolume(int volume) throws IllegalStateException, IllegalArgumentException {
2367  AlivcLog.i(TAG, "[API-Pusher] setBGMVolume: " + volume);
2368  if (mNativeAlivcLivePusher == null) {
2369  AlivcLog.e(TAG, "Illegal State, you should init first");
2370  return;
2371  }
2372  mBGMVolume = (volume > 0 && volume < 10) ? 10 : volume;
2373  mNativeAlivcLivePusher.setBackgroundMusicVolume(mBGMVolume / 10);
2374  }
2375 
2376  @Override
2377  public void setCaptureVolume(int volume) throws IllegalStateException, IllegalArgumentException {
2378  AlivcLog.i(TAG, "[API-Pusher] setCaptureVolume: " + volume);
2379  if (mNativeAlivcLivePusher == null) {
2380  AlivcLog.e(TAG, "Illegal State, you should init first");
2381  return;
2382  }
2383  mCaptureVolume = (volume > 0 && volume < 10) ? 10 : volume;
2384  mNativeAlivcLivePusher.setAudioVolume(mCaptureVolume / 10);
2385  }
2386 
2387  @Override
2388  public void setAudioDenoise(boolean on) {
2389  AlivcLog.i(TAG, "[API-Pusher] setAudioDenoise: " + on);
2390 
2391  if (mNativeAlivcLivePusher == null || mAlivcLivePushConfig == null) {
2392  AlivcLog.e(TAG, "Illegal State, you should init first");
2393  return;
2394  }
2395 
2396  if (mAlivcLivePushConfig.isVideoOnly()) {
2397  AlivcLog.e(TAG, "Audio denoise can not be used on the video only mode!");
2398  return;
2399  }
2400 
2401  mNativeAlivcLivePusher.setAudioDenoise(on);
2402  }
2403 
2404  @Override
2405  public int startIntelligentDenoise() {
2406  AlivcLog.i(TAG, "[API-Pusher] startIntelligentDenoise");
2407  return setIntelligentDenoiseInternal(true);
2408  }
2409 
2410  @Override
2411  public int stopIntelligentDenoise() {
2412  AlivcLog.i(TAG, "[API-Pusher] stopIntelligentDenoise");
2413  return setIntelligentDenoiseInternal(false);
2414  }
2415 
2416  private int setIntelligentDenoiseInternal(boolean flag) {
2417  if (!AlivcLivePushIntelligentDenoiseManager.isFeatureWorked(mContext)) {
2418  AlivcLog.e(TAG, "Intelligent denoise feature not worked due to the lack of native library file! " +
2419  "You can try to read the API doc to find the solution!");
2420  return -1;
2421  }
2422 
2423  if (mNativeAlivcLivePusher == null || mAlivcLivePushConfig == null) {
2424  AlivcLog.e(TAG, "Illegal State, you should init first");
2425  return -1;
2426  }
2427 
2428  if (mAlivcLivePushConfig.isVideoOnly()) {
2429  AlivcLog.e(TAG, "Audio denoise can not be used on the video only mode!");
2430  return -1;
2431  }
2432 
2433  int result = 0;
2434  if (flag) {
2435  result = mNativeAlivcLivePusher.startNativeIntelligentDenoise();
2436  } else {
2437  result = mNativeAlivcLivePusher.stopNativeIntelligentDenoise();
2438  }
2439 
2440  AlivcLog.i(TAG, "setIntelligentDenoiseInternal " + flag + ", return " + result);
2441  return result;
2442  }
2443 
2444  @Override
2445  public void setQualityMode(AlivcQualityModeEnum mode) throws IllegalStateException {
2446  AlivcLog.i(TAG, "[API-Pusher] setQualityMode: " + mode);
2447  if (mNativeAlivcLivePusher == null) {
2448  AlivcLog.e(TAG, "Illegal State, you should init first");
2449  return;
2450  }
2451  if (AlivcQualityModeEnum.QM_CUSTOM.equals(mode)) {
2452  AlivcLog.e(TAG, "Cannot set QM_CUSTOM dynamically");
2453  return;
2454  }
2455  mNativeAlivcLivePusher.setQualityMode(mode.getQualityMode());
2456  }
2457 
2458  @Override
2459  public void setPreviewMode(AlivcPreviewDisplayMode mode) throws IllegalStateException {
2460  AlivcLog.i(TAG, "[API-Pusher] setPreviewMode: " + mode);
2461  if (mNativeAlivcLivePusher == null || mAlivcLivePushConfig == null) {
2462  AlivcLog.e(TAG, "Illegal State, you should init first");
2463  return;
2464  }
2465  if (mAlivcLivePushConfig.getMediaProjectionPermissionResultData() == null) {
2466  mNativeAlivcLivePusher.setDisplayMode(mode.getPreviewDisplayMode());
2467  }
2468  }
2469 
2470  private void startScheduleExecutor() {
2471  if (mScheduledExecutorService != null) {
2472  return;
2473  }
2474  mScheduledExecutorService = Executors.newScheduledThreadPool(2);
2475  mScheduledExecutorService.scheduleAtFixedRate(new Runnable() {
2476  @Override
2477  public void run() {
2478  mTimeCount = mTimeCount + 1;
2479  if(mTimeCount == 5) {
2480  if (mTimeStamp != -1) {
2481  if (mExpiryTime < 60) {
2482  AlivcLog.w(TAG, "[Callback-PushNetwork] onPushURLAuthenticationOverdue");
2483  if (mPushNetworkListener != null) {
2484  String url = mPushNetworkListener.onPushURLAuthenticationOverdue(getLivePusherReference());
2485  if (!TextUtils.isEmpty(url) && !url.equals(mPushUrl)) {
2486  reconnectPushAsync(url);
2487  }
2488  }
2489  } else {
2490  mExpiryTime = mExpiryTime - 5;
2491  }
2492  }
2493 
2494  PusherHeartBeatEvent.Args args = new PusherHeartBeatEvent.Args();
2495  args.mediaInfo = getHeartBeatInfo();
2496  mLiveEventReporter.sendEvent(PusherHeartBeatEvent.kTopicType, PusherHeartBeatEvent.kTopicValue, PusherHeartBeatEvent.getArgsStr(args));
2497  mTimeCount = 0;
2498  }
2499 
2500  if (mPushInfoListener != null) {
2501  AlivcLivePushStatsInfo statsInfo = getLivePushStatsInfo();
2502  // AlivcLog.i(TAG, "[Callback-PushInfo] onPushStatistics: " + mPushStatus + ", " + statsInfo);
2503  mPushInfoListener.onPushStatistics(getLivePusherReference(), statsInfo);
2504  }
2505  }
2506  }, 0, SCHEDULED_EXECUTOR_SERVICE_PERIOD, TimeUnit.MILLISECONDS);
2507  }
2508 
2509  private void stopScheduleExecutor() {
2510  try {
2511  if (mScheduledExecutorService != null) {
2512  mScheduledExecutorService.shutdown();
2513  if (!mScheduledExecutorService.awaitTermination(1000, TimeUnit.MICROSECONDS)) {
2514  mScheduledExecutorService.shutdownNow();
2515  }
2516  mScheduledExecutorService = null;
2517  }
2518  } catch (InterruptedException e) {
2519  if (mScheduledExecutorService != null) {
2520  mScheduledExecutorService.shutdownNow();
2521  }
2522  mScheduledExecutorService = null;
2523  e.printStackTrace();
2524  }
2525  }
2526 
2527  private int[] getImageWidthHeight(String path) {
2528  BitmapFactory.Options options = new BitmapFactory.Options();
2529 
2530  options.inJustDecodeBounds = true;
2531  try {
2532  Bitmap bitmap = BitmapFactory.decodeFile(path, options); // 此时返回的bitmap为null
2533  } catch (Exception e) {
2534  return new int[]{0, 0};
2535  }
2536 
2537  return new int[]{options.outWidth, options.outHeight};
2538  }
2539 
2540  private void addWaterMark() {
2541  if (mAlivcLivePushConfig == null) {
2542  AlivcLog.e(TAG, "Illegal State, you should init first");
2543  return;
2544  }
2545  ArrayList<WaterMarkInfo> waterMarkInfos = mAlivcLivePushConfig.getWaterMarkInfos();
2546  int size = waterMarkInfos.size();
2547  for (int i = 0; i < size; i++) {
2548  addWaterMark(waterMarkInfos.get(i).mWaterMarkPath, waterMarkInfos.get(i).mWaterMarkCoordX, waterMarkInfos.get(i).mWaterMarkCoordY,
2549  waterMarkInfos.get(i).mWaterMarkWidth);
2550  }
2551  }
2552 
2553  // RTS降级到RTMP逻辑
2554  private void rtsDownToRtmp() {
2555  AlivcLog.w(TAG, "rts downgrade to rtmp");
2556  if (TextUtils.isEmpty(mPushUrl) || !mPushUrl.startsWith(AlivcLiveStreamType.EnumType.AlivcLiveStreamRts.getPrefix())) {
2557  return;
2558  }
2559 
2560  AlivcLog.w(TAG, "pre url: " + mPushUrl);
2561  mPushUrl = mPushUrl.replaceFirst(AlivcLiveStreamType.EnumType.AlivcLiveStreamRts.getPrefix(), AlivcLiveStreamType.EnumType.AlivcLiveStreamRtmp.getPrefix());
2562  AlivcLog.w(TAG, "after url: " + mPushUrl);
2563  mPushStatus = AlivcLivePushStats.ERROR;
2564 
2565  stopPush();
2566  if (mNativeAlivcLivePusher != null) {
2567  mNativeAlivcLivePusher.release();
2568  mNativeAlivcLivePusher.init();
2569  }
2570 
2571  startPushAsync(mPushUrl);
2572  }
2573 
2574  private void reportStartPushEvent(boolean isRestart, boolean isSync) {
2575  PusherStartPushEvent.Args args = new PusherStartPushEvent.Args();
2576  Map map = getPerformanceMap();
2577  if (map != null) {
2578  args.sync = isSync;
2579  args.vutMs = getInteger(map, "mVideoDurationFromeCaptureToUpload");
2580  args.autMs = getInteger(map, "mAudioDurationFromeCaptureToUpload");
2581  args.resolution = mAlivcLivePushConfig.getResolution().toString().substring(11);
2582  args.st = mAlivcLivePushConfig.getAudioChannels() == 1 ? "single" : "dual";
2583  args.ao = mAlivcLivePushConfig.isAudioOnly();
2584  args.vo = mAlivcLivePushConfig.isVideoOnly();
2585  args.he = mAlivcLivePushConfig.getVideoEncodeMode().equals(Encode_MODE_HARD);//是否使用硬编
2586  args.wc = mAlivcLivePushConfig.getWaterMarkInfos().size();//水印
2587  args.pum = mAlivcLivePushConfig.isPushMirror();
2588  args.fps = mAlivcLivePushConfig.getFps();
2589  args.ivb = mAlivcLivePushConfig.getInitialVideoBitrate();
2590  args.mavb = mAlivcLivePushConfig.getTargetVideoBitrate();
2591  args.mivb = mAlivcLivePushConfig.getMinVideoBitrate();
2592  args.asr = mAlivcLivePushConfig.getAudioSampleRate().getAudioSampleRate();
2593  args.po = mAlivcLivePushConfig.getPreviewOrientation();
2594  args.ct = mAlivcLivePushConfig.getCameraType();
2595  args.flash = mAlivcLivePushConfig.isFlash();
2596  args.crmc = mAlivcLivePushConfig.getConnectRetryCount();
2597  args.cri = mAlivcLivePushConfig.getConnectRetryInterval();
2598  args.prm = mAlivcLivePushConfig.isPreviewMirror();
2599  args.gop = mAlivcLivePushConfig.getVideoEncodeGop();
2600  args.utm = (mAlivcLivePushConfig.getConnectRetryCount() * mAlivcLivePushConfig.getConnectRetryInterval()) / 1000;
2601 
2602  if (isRestart) {
2603  mLiveEventReporter.sendEvent(PusherRestartPushEvent.kTopicType, PusherRestartPushEvent.kTopicValue, PusherRestartPushEvent.getArgsStr(args));
2604  } else {
2605  mLiveEventReporter.sendEvent(PusherStartPushEvent.kTopicType, PusherStartPushEvent.kTopicValue, PusherStartPushEvent.getArgsStr(args));
2606  }
2607  }
2608  }
2609 
2610  private BroadcastReceiver mHeadsetPlugReceiver = new BroadcastReceiver() {
2611 
2612  @Override
2613  public void onReceive(Context context, Intent intent) {
2614 
2615  String action = intent.getAction();
2616  if (AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(action)) {
2617  AlivcLog.d("BluetoothHeadsetUtils", "ACTION_AUDIO_BECOMING_NOISY headset out");
2618  //拔出耳机
2619  mAudioManager.setMode(AudioManager.STREAM_VOICE_CALL);
2620  mAudioManager.setSpeakerphoneOn(true);
2621 
2622  LivePusherJNI.headSetOn = false;
2623  if (mNativeAlivcLivePusher != null) {
2624  mNativeAlivcLivePusher.setHeadSet(false);
2625  }
2626  } else if ("android.intent.action.HEADSET_PLUG".equals(action)) {// extra
2627  if (intent.hasExtra("state")) {
2628  if (intent.getIntExtra("state", 0) == 0) {
2629  AlivcLog.d("BluetoothHeadsetUtils", "headset out");
2630  //拔出耳机
2631  mAudioManager.setMode(AudioManager.STREAM_VOICE_CALL);
2632  mAudioManager.setSpeakerphoneOn(true);
2633 
2634  if (LivePusherJNI.headSetOn) {
2635  LivePusherJNI.headSetOn = false;
2636  if (mNativeAlivcLivePusher != null) {
2637  mNativeAlivcLivePusher.setHeadSet(false);
2638  }
2639  }
2640  } else if (intent.getIntExtra("state", 0) == 1) {
2641  //插上耳机
2642  AlivcLog.d("BluetoothHeadsetUtils", "headset in");
2643  mAudioManager.setSpeakerphoneOn(false);//
2644  LivePusherJNI.headSetOn = true;
2645  if (mNativeAlivcLivePusher != null) {
2646  mNativeAlivcLivePusher.setHeadSet(true);
2647  }
2648  }
2649  }
2650  }
2651  }
2652 
2653  };
2654 
2655  private void registerHeadsetPlugReceiver() {
2656  //for ear headset receiver, extra
2657  IntentFilter intentFilter = new IntentFilter();
2658  intentFilter.addAction("android.intent.action.HEADSET_PLUG");
2659  mContext.registerReceiver(mHeadsetPlugReceiver, intentFilter);
2660 
2661  IntentFilter intentFilter1 = new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
2662  mContext.registerReceiver(mHeadsetPlugReceiver, intentFilter1);
2663 
2664  registeredCallback = true;
2665  }
2666 
2667  private void registerTelephony() {
2668  mTelephonyUtil = new TelephonyUtil();
2669  mTelephonyUtil.register(mContext, new TelephonyListener() {
2670  @Override
2671  public void onCallStateIdle() {
2672  AlivcLog.i(TAG, "onCallStateIdle");
2673  if (mNativeAlivcLivePusher != null) {
2674  mNativeAlivcLivePusher.setMute(false);
2675  }
2676  }
2677 
2678  @Override
2679  public void onCallStateRinging() {
2680  AlivcLog.i(TAG, "onCallStateRinging");
2681  if (mNativeAlivcLivePusher != null) {
2682  mNativeAlivcLivePusher.setMute(true);
2683  }
2684  }
2685 
2686  @Override
2687  public void onCallStateOffHook() {
2688  AlivcLog.i(TAG, "onCallStateOffHook");
2689  if (mNativeAlivcLivePusher != null) {
2690  mNativeAlivcLivePusher.setMute(true);
2691  }
2692  }
2693  });
2694  }
2695 
2696  private void unregisterTelephony() {
2697  if (mTelephonyUtil != null) {
2698  mTelephonyUtil.unregister();
2699  }
2700  mTelephonyUtil = null;
2701  }
2702 
2703  private void LogWhenGoBackOrFront(Application app, boolean bind) {
2704  if(bind){
2705  mAppFrontBackHelper = new AppFrontBackHelper();
2706  mAppFrontBackHelper.bindApplication(app, new AppFrontBackHelper.OnAppStatusListener() {
2707  @Override
2708  public void onFront() {
2709  if (mNativeAlivcLivePusher != null) {
2710  AlivcLog.i(TAG, "applicationWillBecomeActive");
2711  mNativeAlivcLivePusher.setAppBackgroundState(false);
2712  }
2713  }
2714 
2715  @Override
2716  public void onBack() {
2717  if (mNativeAlivcLivePusher != null) {
2718  AlivcLog.i(TAG, "applicationWillResignActive");
2719  mNativeAlivcLivePusher.setAppBackgroundState(true);
2720  }
2721  }
2722  });
2723  } else {
2724  if(mAppFrontBackHelper != null){
2725  mAppFrontBackHelper.unBindApplication(app);
2726  mAppFrontBackHelper = null;
2727  }
2728  }
2729  }
2730 
2731  private void getNetworkTime() {
2732  new ScheduledThreadPoolExecutor(1, new ThreadFactory() {
2733  private AtomicInteger atoInteger = new AtomicInteger(0);
2734 
2735  @Override
2736  public Thread newThread(Runnable r) {
2737  Thread t = new Thread(r);
2738  t.setName("LivePusher-NTP-Time-Thread " + atoInteger.getAndIncrement());
2739  return t;
2740  }
2741  }).execute(new Runnable() {
2742  @Override
2743  public void run() {
2744  for (int i = 0; i < 3; i++) {
2745  mTimeStamp = getTimeFromNtpServer("time.pool.aliyun.com");
2746  if (mTimeStamp > 0) {
2747  mTimeStamp = mTimeStamp / 1000;
2748  break;
2749  }
2750  }
2751  if (mTimeStamp < 0) {
2752  mTimeStamp = System.currentTimeMillis() / 1000;
2753  }
2754  if (getTimestamp(mPushUrl) != -1) {
2755  mExpiryTime = (int) ((getTimestamp(mPushUrl) - mTimeStamp));
2756  }
2757  }
2758  });
2759  }
2760 
2761  private long getTimeFromNtpServer(String ntpHost) {
2762  AlivcLog.d("", "get time from " + ntpHost);
2763  SntpClient client = new SntpClient();
2764  boolean isSuccessful = client.requestTime(ntpHost, NTP_TIME_OUT_MILLISECOND);
2765  if (isSuccessful) {
2766  return client.getNtpTime();
2767  }
2768  return -1;
2769  }
2770 
2771  @Override
2772  public void addWaterMark(String path, float x, float y, float width) {
2773  AlivcLog.i(TAG, "[API-Pusher] addWaterMark: " + path + ", " + x + ", " + y + ", " + width);
2774  if (mNativeAlivcLivePusher == null || mAlivcLivePushConfig == null) {
2775  AlivcLog.e(TAG, "Illegal State, you should init first");
2776  return;
2777  }
2778  int[] widthHeight = getImageWidthHeight(path);
2779  if (mWatermarkCount >= AlivcLiveMaxWatermarkCount || widthHeight == null || widthHeight[0] == 0 || widthHeight[1] == 0) {
2780  return;
2781  }
2782 
2783  float w = width;
2784  float h = width * widthHeight[1] / widthHeight[0];
2785  if (mAlivcLivePushConfig.getPreviewOrientation() == AlivcPreviewOrientationEnum.ORIENTATION_LANDSCAPE_HOME_LEFT.getOrientation() ||
2786  mAlivcLivePushConfig.getPreviewOrientation() == AlivcPreviewOrientationEnum.ORIENTATION_LANDSCAPE_HOME_RIGHT.getOrientation()) {
2787  h = h * mAlivcLivePushConfig.getHeight() / mAlivcLivePushConfig.getWidth();
2788  } else {
2789  h = h * mAlivcLivePushConfig.getWidth() / mAlivcLivePushConfig.getHeight();
2790  }
2791  // 逻辑与IOS端同步
2792  mNativeAlivcLivePusher.addWaterMark(path, w, h, x + w / 2, y + h / 2);
2793  mWatermarkCount++;
2794  }
2795 
2796  @Override
2797  public void setWatermarkVisible(boolean visible) {
2798  AlivcLog.i(TAG, "[API-Pusher] setWatermarkVisible: " + visible);
2799  if (mNativeAlivcLivePusher == null) {
2800  AlivcLog.e(TAG, "Illegal State, you should init first");
2801  return;
2802  }
2803  if (mPushStatus != AlivcLivePushStats.PREVIEWED) {
2804  AlivcLog.e(TAG, "status error current state is " + AlivcLivePushStats.values()[mPushStatus.ordinal()]);
2805  return;
2806  }
2807  if (mWatermarkCount <= 0) {
2808  return;
2809  }
2810  mNativeAlivcLivePusher.setWaterMarkVisible(visible);
2811  }
2812 
2813  @Override
2814  public int startCamera(SurfaceView surfaceView) throws IllegalStateException {
2815  AlivcLog.i(TAG, "[API-Pusher] startCamera");
2816  if (mNativeAlivcLivePusher == null || mAlivcLivePushConfig == null) {
2817  AlivcLog.e(TAG, "Please execute init first ");
2818  return -1;
2819  }
2820  if (mAlivcLivePushConfig.getMediaProjectionPermissionResultData() == null) {
2821  AlivcLog.e(TAG, "Not in ScreenCapture Mode");
2822  return -1;
2823  }
2824  if (!ScreenRecordStatus.SCREEN_RECORD_NORMAL.equals(mScreenStatus)) {
2825  AlivcLog.e(TAG, "you should start push screen first");
2826  return -1;
2827  }
2828  Surface surface = null;
2829  if (surfaceView != null) {
2830  surface = surfaceView.getHolder().getSurface();
2831  }
2832  int ret = mNativeAlivcLivePusher.startCamera(surface);
2833  mScreenStatus = ScreenRecordStatus.SCREEN_RECORD_CAMERA_START;
2834  return ret;
2835  }
2836 
2837  @Override
2838  public void setScreenOrientation(int orientation) {
2839  AlivcLog.i(TAG, "[API-Pusher] setScreenOrientation: " + orientation);
2840  if (mNativeAlivcLivePusher == null || mAlivcLivePushConfig == null) {
2841  AlivcLog.e(TAG, "Please execute init first ");
2842  return;
2843  }
2844  if (mAlivcLivePushConfig.getMediaProjectionPermissionResultData() == null) {
2845  AlivcLog.e(TAG, "Not in ScreenCapture Mode");
2846  return;
2847  }
2848  mNativeAlivcLivePusher.setScreenOrientation(orientation);
2849  }
2850 
2851  @Override
2852  public void stopCamera() {
2853  AlivcLog.i(TAG, "[API-Pusher] stopCamera");
2854  if (mNativeAlivcLivePusher == null || mAlivcLivePushConfig == null) {
2855  AlivcLog.e(TAG, "Please execute init first ");
2856  return;
2857  }
2858  if (mAlivcLivePushConfig.getMediaProjectionPermissionResultData() == null) {
2859  AlivcLog.e(TAG, "Not in ScreenCapture Mode");
2860  return;
2861  }
2862  mNativeAlivcLivePusher.stopCamera();
2863  mScreenStatus = ScreenRecordStatus.SCREEN_RECORD_NORMAL;
2864  }
2865 
2866  @Override
2867  public int startCameraMix(float x, float y, float w, float h) {
2868  AlivcLog.i(TAG, "[API-Pusher] startCameraMix: " + x + ", " + y + ", " + w + ", " + h);
2869  if (mNativeAlivcLivePusher == null || mAlivcLivePushConfig == null) {
2870  AlivcLog.e(TAG, "Please execute init first ");
2871  return -1;
2872  }
2873  if (mAlivcLivePushConfig.getMediaProjectionPermissionResultData() == null) {
2874  AlivcLog.e(TAG, "Not in ScreenCapture Mode");
2875  return -1;
2876  }
2877  if (!mScreenStatus.equals(ScreenRecordStatus.SCREEN_RECORD_CAMERA_START)) {
2878  AlivcLog.e(TAG, "You should start camera first");
2879  return -1;
2880  }
2881  int ret = mNativeAlivcLivePusher.startCameraMix(x, y, w, h);
2882  mScreenStatus = ScreenRecordStatus.SCREEN_RECORD_CAMERA_MIX_START;
2883  return ret;
2884  }
2885 
2886  @Override
2887  public void stopCameraMix() {
2888  AlivcLog.i(TAG, "[API-Pusher] stopCameraMix");
2889  if (mNativeAlivcLivePusher == null || mAlivcLivePushConfig == null) {
2890  AlivcLog.e(TAG, "Please execute init first ");
2891  return;
2892  }
2893  if (mAlivcLivePushConfig.getMediaProjectionPermissionResultData() == null) {
2894  AlivcLog.e(TAG, "Not in ScreenCapture Mode");
2895  return;
2896  }
2897  mNativeAlivcLivePusher.stopCameraMix();
2898  mScreenStatus = ScreenRecordStatus.SCREEN_RECORD_CAMERA_START;
2899  }
2900 
2901  @Override
2902  public void changeResolution(AlivcResolutionEnum resolutionEnum) {
2903  AlivcLog.i(TAG, "[API-Pusher] changeResolution: " + resolutionEnum);
2904  if (mNativeAlivcLivePusher == null) {
2905  AlivcLog.e(TAG, "Please execute init first!");
2906  return;
2907  }
2908  if (mPushStatus != AlivcLivePushStats.PUSHED && mPushStatus != AlivcLivePushStats.PREVIEWED && mPushStatus != AlivcLivePushStats.INIT) {
2909  AlivcLog.e(TAG, "changeResolution can only be called in inited or previewed status");
2910  return;
2911  }
2912  mNativeAlivcLivePusher.changeResolution(AlivcResolutionEnum.GetResolutionWidth(resolutionEnum), AlivcResolutionEnum.GetResolutionHeight(resolutionEnum));
2913  }
2914 
2915  public int mixStreamRequireMain(int vid, boolean require) {
2916  if (mNativeAlivcLivePusher == null) {
2917  return -1;
2918  }
2919  return mNativeAlivcLivePusher.mixStreamRequireMain(vid, require);
2920  }
2921 
2922  public int mixStreamChangePosition(int vid, float x, float y, float w, float h) {
2923  if (mNativeAlivcLivePusher == null) {
2924  return -1;
2925  }
2926  return mNativeAlivcLivePusher.mixStreamChangePosition(vid, x, y, w, h);
2927  }
2928 
2929  public void mixStreamMirror(int vid, boolean mirror) {
2930  if (mNativeAlivcLivePusher == null) {
2931  return;
2932  }
2933  mNativeAlivcLivePusher.setMixStreamMirror(vid, mirror);
2934  }
2935 
2936  public int addMixVideo(AlivcImageFormat format, int width, int height, int rotation, float displayX, float displayY, float displayW, float displayH, boolean adjustHeight) {
2937  if (mNativeAlivcLivePusher == null) {
2938  return -1;
2939  }
2940  return mNativeAlivcLivePusher.addMixVideo(format.getAlivcImageFormat(), width, height, rotation, displayX, displayY, displayW, displayH, adjustHeight);
2941  }
2942 
2943  public void removeMixVideo(int handler) {
2944  if (mNativeAlivcLivePusher == null) {
2945  return;
2946  }
2947  mNativeAlivcLivePusher.removeMixVideo(handler);
2948  }
2949 
2950  public void inputMixTexture(int handler, int texture, int width, int height, long pts, int rotation) {
2951  if (mNativeAlivcLivePusher == null) {
2952  return;
2953  }
2954  mNativeAlivcLivePusher.inputMixTexture(handler, texture, width, height, pts, rotation);
2955  }
2956 
2957  public void inputMixVideoPtr(int handler, long dataptr, int width, int height, int stride, int size, long pts, int rotation) {
2958  if (mNativeAlivcLivePusher == null) {
2959  return;
2960  }
2961  mNativeAlivcLivePusher.inputMixVideoPtr(handler, dataptr, width, height, stride, size, pts, rotation);
2962  }
2963 
2964  public void inputMixVideoData(int handler, byte[] data, int width, int height, int stride, int size, long pts, int rotation) {
2965  if (mNativeAlivcLivePusher == null) {
2966  return;
2967  }
2968  mNativeAlivcLivePusher.inputMixVideoData(handler, data, width, height, stride, size, pts, rotation);
2969  }
2970 
2971  public int addMixAudio(int channels, AlivcSoundFormat format, int audioSample) {
2972  if (mNativeAlivcLivePusher == null) {
2973  return -1;
2974  }
2975  return mNativeAlivcLivePusher.addMixAudio(channels, format.getAlivcSoundFormat(), audioSample);
2976  }
2977 
2978  public void removeMixAudio(int handler) {
2979  if (mNativeAlivcLivePusher == null) {
2980  return;
2981  }
2982  mNativeAlivcLivePusher.removeMixAudio(handler);
2983  }
2984 
2985  public boolean inputMixAudioPtr(int handler, long dataptr, int size, long pts) {
2986  if (mNativeAlivcLivePusher == null) {
2987  return false;
2988  }
2989  return mNativeAlivcLivePusher.inputMixAudioPtr(handler, dataptr, size, pts);
2990  }
2991 
2992  public boolean inputMixAudioData(int handler, byte[] data, int size, long pts) {
2993  if (mNativeAlivcLivePusher == null) {
2994  return false;
2995  }
2996  return mNativeAlivcLivePusher.inputMixAudioData(handler, data, size, pts);
2997  }
2998 
2999  @Override
3000  public void inputStreamVideoPtr(long dataptr, int width, int height, int stride, int size, long pts, int rotation) {
3001  if (mNativeAlivcLivePusher == null) {
3002  return;
3003  }
3004  mNativeAlivcLivePusher.inputStreamVideoPtr(dataptr, width, height, stride, size, pts, rotation);
3005  }
3006 
3007  public void inputStreamTexture(int textureId, int width, int height, int stride, long pts, int rotation, long extra) {
3008  if (mNativeAlivcLivePusher == null) {
3009  return;
3010  }
3011  mNativeAlivcLivePusher.inputStreamTexture(textureId, width, height, stride, pts, rotation, extra);
3012  }
3013 
3014  @Override
3015  public void inputStreamVideoData(byte[] data, int width, int height, int stride, int size, long pts, int rotation) {
3016  if (mNativeAlivcLivePusher == null) {
3017  return;
3018  }
3019  mNativeAlivcLivePusher.inputStreamVideoData(data, width, height, stride, size, pts, rotation);
3020  }
3021 
3022  @Override
3023  public void inputStreamAudioPtr(long dataPtr, int size, int sampleRate, int channels, long pts) {
3024  if (mNativeAlivcLivePusher == null) {
3025  return;
3026  }
3027  mNativeAlivcLivePusher.inputStreamAudioPtr(dataPtr, size, sampleRate, channels, pts);
3028  }
3029 
3030  @Override
3031  public void inputStreamAudioData(byte[] data, int size, int sampleRate, int channels, long pts) {
3032  if (mNativeAlivcLivePusher == null) {
3033  return;
3034  }
3035  mNativeAlivcLivePusher.inputStreamAudioData(data, size, sampleRate, channels, pts);
3036  }
3037 
3038  @Override
3039  public int addDynamicsAddons(String path, float x, float y, float w, float h) throws IllegalArgumentException {
3040  AlivcLog.i(TAG, "[API-Pusher] addDynamicsAddons: " + path + ", " + x + ", " + y + ", " + w + ", " + h);
3041  if (mNativeAlivcLivePusher == null) {
3042  return -1;
3043  }
3044  if (x < TEXTURE_RANGE_MIN || x > TEXTURE_RANGE_MAX || y < TEXTURE_RANGE_MIN || y > TEXTURE_RANGE_MAX || w < TEXTURE_RANGE_MIN || w > TEXTURE_RANGE_MAX || h < TEXTURE_RANGE_MIN || h > TEXTURE_RANGE_MAX) {
3045  AlivcLog.e(TAG, "addDynamicsAddons failed! x, y, w, h should in range [0~1.0f]");
3046  return -1;
3047  }
3048  if (mDynamicAddsonCount >= MAX_DYNAMIC_ADDSON_COUNT) {
3049  return -1;
3050  }
3051  mDynamicAddsonCount++;
3052  return mNativeAlivcLivePusher.addDynamicsAddons(path, System.currentTimeMillis() * 1000, 0, x, y, w, h, 0, false);
3053  }
3054 
3055  @Override
3056  public void removeDynamicsAddons(int id) {
3057  AlivcLog.i(TAG, "[API-Pusher] removeDynamicsAddons: " + id);
3058  if (mNativeAlivcLivePusher == null) {
3059  return;
3060  }
3061  mDynamicAddsonCount--;
3062  mNativeAlivcLivePusher.removeDynamicsAddons(id);
3063  }
3064 
3065  public void setMainStreamPosition(float startX, float startY, float w, float h) {
3066  if (mNativeAlivcLivePusher == null) {
3067  return;
3068  }
3069  mNativeAlivcLivePusher.setMainStreamPosition(startX, startY, w, h);
3070  }
3071 
3072  private String getFormatString(String string) {
3073  String result = "";
3074  int index = string.indexOf(AUTH_KEY);
3075  if (index > 0) {
3076  String temp = string.substring(index);
3077  if (temp.indexOf("-") > 0) {
3078  result = temp.substring(AUTH_KEY.length(), temp.indexOf("-"));
3079  } else {
3080  result = temp.substring(AUTH_KEY.length());
3081  }
3082  }
3083  return result;
3084  }
3085 
3086  private int getTimestamp(String string) {
3087  int result = -1;
3088  String tempStamp = getFormatString(string);
3089  if (tempStamp.length() < 10) {
3090  return -1;
3091  }
3092  if (TextUtils.isDigitsOnly(tempStamp)) {
3093  return new Long(Long.valueOf(tempStamp)).intValue();
3094  }
3095 
3096  return result;
3097  }
3098 
3099  private AlivcSnapshotListener mInnerSnapshotListener = new AlivcSnapshotListener() {
3100  @Override
3101  public void onSnapshot(final Bitmap bmp) {
3102  if (mSnapshotListener != null) {
3103  mThreadPoolExecutor.execute(new Runnable() {
3104  @Override
3105  public void run() {
3106  mSnapshotListener.onSnapshot(bmp);
3107  }
3108  });
3109  }
3110  }
3111  };
3112 }
void onReconnectStart(AlivcLivePusher pusher)
void onFirstFramePreviewed(AlivcLivePusher pusher)
void onPushPaused(AlivcLivePusher pusher)
Live push surface status.
void onNetworkRecovery(AlivcLivePusher pusher)
void onPushStarted(AlivcLivePusher pusher)
void onConnectionLost(AlivcLivePusher pusher)
void onReconnectFail(AlivcLivePusher pusher)
void onPreviewStarted(AlivcLivePusher pusher)
void onPushRestarted(AlivcLivePusher pusher)
void onDropFrame(AlivcLivePusher pusher, int beforeCount, int afterCount)
String onPushURLAuthenticationOverdue(AlivcLivePusher pusher)
void setCameraType(AlivcLivePushCameraTypeEnum cameraType)
Enumeration of streaming encode mode.
void onReconnectSucceed(AlivcLivePusher pusher)
void onPushStopped(AlivcLivePusher pusher)
void onFirstFramePushed(AlivcLivePusher pusher)
void onSDKError(AlivcLivePusher livePusher, AlivcLivePushError error)
void onAdjustFps(AlivcLivePusher pusher, int currentFps, int targetFps)
void onSystemError(AlivcLivePusher livePusher, AlivcLivePushError error)
void onPushStatistics(AlivcLivePusher pusher, AlivcLivePushStatsInfo statistics)
void onSendDataTimeout(AlivcLivePusher pusher)
void onAdjustBitrate(AlivcLivePusher pusher, int currentBitrate, int targetBitrate)
Enumeration of streaming video camera type.
void onPreviewStopped(AlivcLivePusher pusher)
void onPushResumed(AlivcLivePusher pusher)
void onProgress(long progress, long duration)