简介
移动直播TXLiteAVSDK有两个基本组件
- TXLivePusher 上行推流
- TXLivePlayer 下行拉流
您可以为 LivePusher 对象绑定一个TXLivePushListener,之后 SDK 的内部推流状态信息均会通过 onPushEvent(事件通知) 和 onNetStatus(状态反馈)通知给您
为TXLivePlayer 对象绑定一个TXLivePlayListener,之后 SDK 的内部播放状态信息均会通过 onPlayEvent(事件通知) 和 onNetStatus(状态反馈)通知给您
场景
用户在直播过程中,可能会遇到以下情况,如拉流一直不成功、因网络波动导致无法拉到流。App 一般都会在 UI 上通过一些提示语来提示关注。我们移动直播 SDK 有完整的事件回调,开发者可以根据不同事件回调来提示观众。
解决方案
Android
1、实现 ITXLivePlayListener 接口 并实现 onPlayEvent()
和 onNetStatus()
方法
2、在onPlayEvent()
监听拉流事件
public class LivePlayerActivity extends Activity implements ITXLivePlayListener{
private TXLivePlayer mLivePlayer;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mLivePlayer = new TXLivePlayer(this);
//TODO
}
//点击开始播放,拉流组件绑定监听
private boolean startPlay() {
mLivePlayer.setPlayListener(this);
//TODO
mLivePlayer.startPlay(url,type);
}
@Override
public void onPlayEvent(int event, Bundle param) {
String playEventLog = "receive event: " event ", " param.getString(TXLiveConstants.EVT_DESCRIPTION);
Log.d(TAG, playEventLog);
if (event == TXLiveConstants.PLAY_EVT_PLAY_BEGIN) {
// 视频播放开始, 停止 loading 状态的动画
stopLoadingAnimation();
Log.d("AutoMonitor", "PlayFirstRender,cost=" (System.currentTimeMillis()-mStartPlayTS));
} else if (event == TXLiveConstants.PLAY_ERR_NET_DISCONNECT) {
// 可能主播关播,也有可能是主播网络出现波动
stopPlay();
} else if (event == TXLiveConstants.PLAY_EVT_PLAY_LOADING){
// 视频数据缓冲中……
startLoadingAnimation();
} else if (event == TXLiveConstants.PLAY_EVT_RCV_FIRST_I_FRAME) {
// 网络接收到首个可渲染的视频数据包(IDR)
stopLoadingAnimation();
} else if (event == TXLiveConstants.PLAY_EVT_CHANGE_RESOLUTION) {
// 直播流的分辨率改变
streamRecord(false);
} else if (event == TXLiveConstants.PLAY_EVT_CHANGE_ROTATION) {
// 主播改变推流的方向
return;
}
if (event < 0) {
Toast.makeText(getApplicationContext(), param.getString(TXLiveConstants.EVT_DESCRIPTION), Toast.LENGTH_SHORT).show();
}
}
@Override
public void onNetStatus(Bundle status) {
//TODO
}
}
iOS
1、实现 ITXLivePlayListener 接口 并实现 onPlayEvent()
和 onNetStatus()
方法
2、在onPlayEvent()
监听拉流事件
#pragma ###TXLivePlayListener
-(void) onPlayEvent:(int)EvtID withParam:(NSDictionary*)param
{
NSDictionary* dict = param;
dispatch_async(dispatch_get_main_queue(), ^{
if (EvtID == PLAY_EVT_RCV_FIRST_I_FRAME) {
// _publishParam = nil;
}
if (EvtID == PLAY_EVT_PLAY_BEGIN) {
[self stopLoadingAnimation];
long long playDelay = [[NSDate date]timeIntervalSince1970]*1000 - _startPlayTS;
AppDemoLog(@"AutoMonitor:PlayFirstRender,cost=%lld", playDelay);
} else if (EvtID == PLAY_ERR_NET_DISCONNECT ) {
[self stopRtmp];
NSString* Msg = (NSString*)[dict valueForKey:EVT_MSG];
[self toastTip:Msg];
} else if (EvtID == PLAY_EVT_PLAY_LOADING){
[self startLoadingAnimation];
}
else if (EvtID == PLAY_EVT_CONNECT_SUCC) {
BOOL isWifi = [AFNetworkReachabilityManager sharedManager].reachableViaWiFi;
if (!isWifi) {
__weak __typeof(self) weakSelf = self;
[[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
if (_playUrl.length == 0) {
return;
}
if (status == AFNetworkReachabilityStatusReachableViaWiFi) {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@""
message:@"您要切换到Wifi再观看吗?"
preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"是" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[alert dismissViewControllerAnimated:YES completion:nil];
[weakSelf stopRtmp];
[weakSelf startRtmp];
}]];
[alert addAction:[UIAlertAction actionWithTitle:@"否" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
[alert dismissViewControllerAnimated:YES completion:nil];
}]];
[weakSelf presentViewController:alert animated:YES completion:nil];
}
}];
}
}else if (EvtID == PLAY_EVT_CHANGE_ROTATION) {
return;
}
});
}
原理
使用移动直播 SDK 拉流成功, SDK 回调事件如下:
使用移动直播 SDK 拉流成功,但是过段时间因网络波动导致拉不到流,SDK 重连三次依然无法播放。SDK 回调事件如下:
移动直播 SDK 中拉流对象 TXLivePlayer 的内部原理,如下图
其他
如果您想了解更多的事件处理,见移动直播官网的事件处理文档
如果您想查看 SDK 中完整的事件回调, 见文档