123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385 |
- //
- // LiveRoomViewController.m
- // OpenLive
- //
- // Created by GongYuhua on 2016/9/12.
- // Copyright © 2016年 Agora. All rights reserved.
- //
- #import "LiveRoomViewController.h"
- #import "VideoSession.h"
- #import "VideoViewLayouter.h"
- #import "KeyCenter.h"
- #import "Reachability/Reachability.h"
- @interface LiveRoomViewController () <AgoraRtcEngineDelegate>
- /*标题*/
- @property (weak, nonatomic) IBOutlet UILabel *roomNameLabel;
- /*视图 远程容器视图*/
- @property (weak, nonatomic) IBOutlet UIView *remoteContainerView;
- /*左下角第一个按钮*/
- @property (weak, nonatomic) IBOutlet UIButton *broadcastButton;
- /*左下角第二个按钮*/
- @property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *sessionButtons;
- /*左下角第三个按钮*/
- @property (weak, nonatomic) IBOutlet UIButton *audioMuteButton;
- /*没用的按钮*/
- @property (weak, nonatomic) IBOutlet UIButton *enhancerButton;
- /*猜测_直播相关类*/
- @property (strong, nonatomic) AgoraRtcEngineKit *rtcEngine;
- @property (assign, nonatomic) BOOL isBroadcaster;
- @property (assign, nonatomic) BOOL isMuted;
- @property (assign, nonatomic) BOOL shouldEnhancer;
- /*分屏*/
- @property (strong, nonatomic) NSMutableArray<VideoSession *> *videoSessions;
- @property (strong, nonatomic) VideoSession *mySession;
- /*猜不透*/
- @property (strong, nonatomic) VideoSession *fullSession;
- /*猜不透2*/
- @property (strong, nonatomic) VideoViewLayouter *viewLayouter;
- /*网络监听*/
- @property (nonatomic, strong) Reachability *hostReachability;
- @property(assign,nonatomic) BOOL isReachability;
- /*失败显示*/
- @property(nonatomic,strong) UILabel *lostNetwork;
- @end
- @implementation LiveRoomViewController
- /*懒加载*/
- -(UILabel *)lostNetwork{
- if (!_lostNetwork) {
- _lostNetwork=[[UILabel alloc]initWithFrame:self.view.bounds];
- _lostNetwork.text=@"网络连接失败";
- _lostNetwork.textAlignment=NSTextAlignmentCenter;
- }
- return _lostNetwork;
- }
- /*成员属性*/
- - (BOOL)isBroadcaster {
- NSLog(@"isBroadcaster");
- return self.clientRole == AgoraRtc_ClientRole_Broadcaster;
- //return self.clientRole=AgoraRtc_ClientRole_Audience;
- }
- - (VideoViewLayouter *)viewLayouter {
- if (!_viewLayouter) {
- _viewLayouter = [[VideoViewLayouter alloc] init];
- }
- return _viewLayouter;
- }
- /*设置角色*/
- - (void)setClientRole:(AgoraRtcClientRole)clientRole {
- _clientRole = clientRole;
-
- if (self.isBroadcaster) {
- self.shouldEnhancer = YES;
- }
- [self updateButtonsVisiablity];
- }
- - (void)setIsMuted:(BOOL)isMuted {
- _isMuted = isMuted;
- [self.rtcEngine muteLocalAudioStream:isMuted];
- [self.audioMuteButton setImage:[UIImage imageNamed:(isMuted ? @"btn_mute_cancel" : @"btn_mute")] forState:UIControlStateNormal];
- }
- - (void)setVideoSessions:(NSMutableArray<VideoSession *> *)videoSessions {
- _videoSessions = videoSessions;
- if (self.remoteContainerView) {
- [self updateInterfaceWithAnimation:YES];
- }
- }
- - (void)setFullSession:(VideoSession *)fullSession {
- _fullSession = fullSession;
- if (self.remoteContainerView) {
- [self updateInterfaceWithAnimation:YES];
- }
- }
- /*生命周期*/
- - (void)viewDidLoad {
- [super viewDidLoad];
- self.videoSessions = [[NSMutableArray alloc] init];
-
- self.roomNameLabel.text = self.roomName;
- [self updateButtonsVisiablity];
- //当网络改变后,有网络之后重新推流
-
- [self network];
-
- }
- /*网络重连*/
- -(void)network{
- /**网络连接*/
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(reachabilityChanged:)
- name: kReachabilityChangedNotification
- object: nil];
- NSString *remoteHostName = @"www.baidu.com";
- NSString *remoteHostLabelFormatString = NSLocalizedString(@"Remote Host: %@", @"Remote host label format string");
- UILabel *remoteHostLabel = [[UILabel alloc] init];
- remoteHostLabel.text = [NSString stringWithFormat:remoteHostLabelFormatString, remoteHostName];
- self.hostReachability = [Reachability reachabilityWithHostName:remoteHostName];
- [self.hostReachability startNotifier];
- }
- -(void)reachabilityChanged:(NSNotification*)no{
- Reachability* curReach = [no object];
- NSParameterAssert([curReach isKindOfClass: [Reachability class]]);
- NetworkStatus status = [curReach currentReachabilityStatus];
- if(status!=NotReachable){
- [self.lostNetwork removeFromSuperview];
- NSLog(@"可以联网");
- //测试删除
-
- if (NO==self.isReachability) {
- NSLog(@"可以联网");
- // [self.rtcEngine switchCamera];//转换后置
- [self loadAgoraKit];
- self.isReachability=YES;
- }
- }else{
- [self.view addSubview:self.lostNetwork];
- if(self.mySession){
- [self.mySession.hostingView removeFromSuperview];
- [self.videoSessions removeObject:self.mySession];
- }
- self.isReachability=NO;
- NSLog(@"联网失败");
- }
- }
- /*转换摄像头*/
- - (IBAction)doSwitchCameraPressed:(UIButton *)sender {
- [self.rtcEngine switchCamera];
- }
- /*是否有声音*/
- - (IBAction)doMutePressed:(UIButton *)sender {
- // self.isMuted = !self.isMuted;
- //删除
- self.isMuted =YES;
- }
- /*最小化摄像*/
- - (IBAction)doBroadcastPressed:(UIButton *)sender {
- if (self.isBroadcaster) {
- self.clientRole = AgoraRtc_ClientRole_Audience;
- if (self.fullSession.uid == 0) {
- self.fullSession = nil;
- }
- } else {
- self.clientRole = AgoraRtc_ClientRole_Broadcaster;
- }
-
- [self.rtcEngine setClientRole:self.clientRole withKey:nil];
- [self updateInterfaceWithAnimation:YES];
- }
- /*轻击*/
- - (IBAction)doDoubleTapped:(UITapGestureRecognizer *)sender {
- if (!self.fullSession) {
- VideoSession *tappedSession = [self.viewLayouter responseSessionOfGesture:sender inSessions:self.videoSessions inContainerView:self.remoteContainerView];
- if (tappedSession) {
- self.fullSession = tappedSession;
- }
- } else {
- self.fullSession = nil;
- }
- }
- //关闭
- - (IBAction)doLeavePressed:(UIButton *)sender {
- // [self.rtcEngine switchCamera];
- [self leaveChannel];
- }
- - (void)updateButtonsVisiablity {
- [self.broadcastButton setImage:[UIImage imageNamed:self.isBroadcaster ? @"btn_join_cancel" : @"btn_join"] forState:UIControlStateNormal];
- for (UIButton *button in self.sessionButtons) {
- button.hidden = !self.isBroadcaster;
- }
- }
- /*离开频道*/
- - (void)leaveChannel {
- [self setIdleTimerActive:YES];
-
- [self.rtcEngine setupLocalVideo:nil];
- [self.rtcEngine leaveChannel:nil];
- if (self.isBroadcaster) {
- [self.rtcEngine stopPreview];
- }
-
- for (VideoSession *session in self.videoSessions) {
- [session.hostingView removeFromSuperview];
- }
- [self.videoSessions removeAllObjects];
-
- if ([self.delegate respondsToSelector:@selector(liveVCNeedClose:)]) {
- [self.delegate liveVCNeedClose:self];
- }
- }
- //是否自动锁屏
- - (void)setIdleTimerActive:(BOOL)active {
- [UIApplication sharedApplication].idleTimerDisabled = !active;
- }
- /*弹出alert框*/
- - (void)alertString:(NSString *)string {
- if (!string.length) {
- return;
- }
-
- UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:string preferredStyle:UIAlertControllerStyleAlert];
- [alert addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleCancel handler:nil]];
- [self presentViewController:alert animated:YES completion:nil];
- }
- //带动画更新
- - (void)updateInterfaceWithAnimation:(BOOL)animation {
- if (animation) {
- [UIView animateWithDuration:0.3 animations:^{
- [self updateInterface];
- //如果,有需要刷新的标记,立即调用layoutSubviews进行布局(如果没有标记,不会调用layoutSubviews)
- [self.view layoutIfNeeded];
- }];
- } else {
- [self updateInterface];
- }
- }
- /*更新界面*/
- - (void)updateInterface {
- NSArray *displaySessions;
- if (!self.isBroadcaster && self.videoSessions.count) {
- displaySessions = [self.videoSessions subarrayWithRange:NSMakeRange(1, self.videoSessions.count - 1)];
- } else {
- displaySessions = [self.videoSessions copy];
- }
-
- [self.viewLayouter layoutSessions:displaySessions fullSession:self.fullSession inContainer:self.remoteContainerView];
- [self setStreamTypeForSessions:displaySessions fullSession:self.fullSession];
- }
- /*更新界面时调用*/
- - (void)setStreamTypeForSessions:(NSArray<VideoSession *> *)sessions fullSession:(VideoSession *)fullSession {
- if (fullSession) {
- for (VideoSession *session in sessions) {
- [self.rtcEngine setRemoteVideoStream:session.uid type:(session == self.fullSession ? AgoraRtc_VideoStream_High : AgoraRtc_VideoStream_Low)];
- }
- } else {
- for (VideoSession *session in sessions) {
- [self.rtcEngine setRemoteVideoStream:session.uid type:AgoraRtc_VideoStream_High];
- }
- }
- }
- - (void)addLocalSession {
- VideoSession *localSession = [VideoSession localSession];
- self.mySession=localSession;
- [self.videoSessions addObject:localSession];
- //设置显示画面
- [self.rtcEngine setupLocalVideo:localSession.canvas];
- [self updateInterfaceWithAnimation:YES];
- }
- - (VideoSession *)fetchSessionOfUid:(NSUInteger)uid {
- for (VideoSession *session in self.videoSessions) {
- if (session.uid == uid) {
- return session;
- }
- }
- return nil;
- }
- - (VideoSession *)videoSessionOfUid:(NSUInteger)uid {
- VideoSession *fetchedSession = [self fetchSessionOfUid:uid];
- if (fetchedSession) {
- return fetchedSession;
- } else {
- VideoSession *newSession = [[VideoSession alloc] initWithUid:uid];
- [self.videoSessions addObject:newSession];
- [self updateInterfaceWithAnimation:YES];
- return newSession;
- }
- }
- //MARK: - Agora Media SDK
- - (void)loadAgoraKit {
- NSLog(@"%s",__FUNCTION__);
- //单例
- self.rtcEngine = [AgoraRtcEngineKit sharedEngineWithAppId:[KeyCenter AppId] delegate:self];
- //开启静音模式 删除
- [self.rtcEngine muteAllRemoteAudioStreams:YES];
-
- [self.rtcEngine setChannelProfile:AgoraRtc_ChannelProfile_LiveBroadcasting];//直播模式
- [self.rtcEngine enableDualStreamMode:YES];//双流
- [self.rtcEngine enableVideo];
- [self.rtcEngine setVideoProfile:self.videoProfile swapWidthAndHeight:YES];
- [self.rtcEngine setClientRole:self.clientRole withKey:nil];
-
- if (self.isBroadcaster) {
- //开始视频预览
- [self.rtcEngine startPreview];
- }
- //添加会话
- [self addLocalSession];
- [self.rtcEngine enableWebSdkInteroperability:YES];
- // [self.rtcEngine switchCamera];//转换后置
- //这儿好像不对。。。
- int code = [self.rtcEngine joinChannelByKey:nil channelName:self.roomName info:nil uid:self.uid joinSuccess:^(NSString *channel, NSUInteger uid, NSInteger elapsed) {
-
- NSLog(@"加入成功");
- }];
- if (code == 0) {
- [self setIdleTimerActive:NO];
- } else {
- dispatch_async(dispatch_get_main_queue(), ^{
- [self alertString:[NSString stringWithFormat:@"Join channel failed: %d", code]];
- });
- }
-
- if (self.isBroadcaster) {
- self.shouldEnhancer = YES;
- }
- }
- //有主播加入时,调用该方法
- - (void)rtcEngine:(AgoraRtcEngineKit *)engine didJoinedOfUid:(NSUInteger)uid elapsed:(NSInteger)elapsed {
- VideoSession *userSession = [self videoSessionOfUid:uid];
- NSLog(@"%s __%li",__FUNCTION__,uid);
- [self.rtcEngine setupRemoteVideo:userSession.canvas];
- }
- //本地显示首帧调用
- - (void)rtcEngine:(AgoraRtcEngineKit *)engine firstLocalVideoFrameWithSize:(CGSize)size elapsed:(NSInteger)elapsed {
- NSLog(@"%s",__FUNCTION__);
- if (self.videoSessions.count) {
- [self updateInterfaceWithAnimation:NO];
- }
- }
- //主播离线回调
- - (void)rtcEngine:(AgoraRtcEngineKit *)engine didOfflineOfUid:(NSUInteger)uid reason:(AgoraRtcUserOfflineReason)reason {
- NSLog(@"%s__uid:%li",__FUNCTION__,uid);
- VideoSession *deleteSession;
- for (VideoSession *session in self.videoSessions) {
- if (session.uid == uid) {
- deleteSession = session;
- }
- }
-
- if (deleteSession) {
- [self.videoSessions removeObject:deleteSession];
- [deleteSession.hostingView removeFromSuperview];
- [self updateInterfaceWithAnimation:YES];
-
- if (deleteSession == self.fullSession) {
- self.fullSession = nil;
- }
- }
- }
- - (void)rtcEngine:(AgoraRtcEngineKit *)engine didOccurError:(AgoraRtcErrorCode)errorCode{
- NSLog(@"engine:%@",engine);
- NSLog(@"errorCode:%li",errorCode);
- }
- @end
|