产品要求:3分钟内如果由于网络原因中断需要实现重连。
接口要求,每次重连时,需要先获取一下,推送地址,如果3分钟后获取 推送地址,将返回相关的错误信息(比如直播已过期请重新创建直播)等。
Reconnection1.png/**
* Restart streaming notification.
* <p>
*
* When the network-connection is broken, {@link StreamingState#DISCONNECTED} will notified first,
* and then invoked this method if the environment of restart streaming is ready.
*
* <p>
* SDK won't limit the number of invocation.
*
* @param code error code. <b>Unspecified now</b>.
*
* @return true means you handled the event; otherwise, given up and then {@link StreamingState#SHUTDOWN}
* will be notified.
*
* */
boolean onRestartStreamingHandled(int code);
经测试该方法运行在子线程中.
实现上述需求,使用java的 awit 和nofityAll 即可完成,代码如下图
/**
* 直播是否过期
*/
public volatile boolean isLiveExpired = false;
private volatile boolean waitSign = false;
/**
* 重新启动流式通知。
* 当网络连接断开时,{@link StreamingState#DISCONNECTED }将首先通知,然后在重新启动流环境准备就绪的情况下调用此方法。
* SDK不会限制调用次数。
* @param code 参数代码错误代码。 <b>现在未指定</ b>。
* @return return true表示您已处理事件; 否则,放弃,然后{@link StreamingState#SHUTDOWN}
*/
@Override
public boolean onRestartStreamingHandled(int code) {
/**
* When the network-connection is broken, StreamingState#DISCONNECTED will notified first,
* and then invoked this method if the environment of restart streaming is ready.
*
* @return true means you handled the event; otherwise, given up and then StreamingState#SHUTDOWN
* will be notified.
*/
if (getMediaStreamingManager() != null){
waitSign = false;
synchronized (StreamingBaseActivity.this) {
while (!waitSign) {
try {
getPlayStream(getLiveId());
StreamingBaseActivity.this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
boolean isSuccess = getMediaStreamingManager().startStreaming();
return !isLiveExpired && isSuccess; //直播没过期
}else {
return false;
}
}
private void getPlayStream(String liveId) {
IApi<JSONObject> api = new ApiLivePlayStream(liveId);
JsonWarpperApi<PlayStreamResult> warpperApi = new JsonWarpperApi<>(api);
warpperApi.excute(new Callback<PlayStreamResult>() {
@Override
public void onUIResult(RootResult<PlayStreamResult> data) {
dismissLoadingDialog();
if (!isFinishing() && RootResult.isBusinessOk(data)) {
try {
mProfile.setPublishUrl(data.mData.getUrl());
getMediaStreamingManager().setStreamingProfile(mProfile);
} catch (URISyntaxException e) {
e.printStackTrace();
}
} else if (RootResult.getErrorCode(data).equals("2")){ //状态码2,提示信息:直播已过期请重新创建直播
isLiveExpired = true;
if (expiredDialog != null && expiredDialog.isShowing()){
expiredDialog.dismiss();
}
expiredDialog = CustomListDialog.showCustomListDialogWithOneBtn(mActivity, "直播已过期请重新创建直播", R.string.sure, new View.OnClickListener() {
@Override
public void onClick(View v) {
getBackView().performClick();
}
});
}else{
JXToast.showShort(RootResult.getErrorMessage(data));
}
synchronized (StreamingBaseActivity.this){
waitSign=true;
StreamingBaseActivity.this.notifyAll();
}
}
@Override
public void onUIError(int errorCode, String errorMsg) {
synchronized (StreamingBaseActivity.this){
waitSign=true;
StreamingBaseActivity.this.notifyAll();
}
}
}, PlayStreamResult.class);
}
注意点:
wait:调用会导致当前线程释放锁,处理等待状态,直到另一个线程调用该对象的notify()方法或notifyAll()方法。
wait和notify必须配合synchronized使用,而且wait必须在notify前用,wait后就会进入notify所在的线程,notify后唤醒wait所在的线程,但是wait所在的线程仍然没有获取锁,需要等待notify所在的线程释放锁。
参考项目:
PLDroidMediaStreaming
直播云 > SDK > 推流端 >Android 推流端 SDK >开发准备
关注我的github
https://github.com/fuyuguang
带你了解更多项目实践中的bug
网友评论