@@ -53,19 +53,37 @@ class LiveStreamingEntry : UIViewController
5353}
5454
5555class LiveStreamingMain : BaseViewController {
56- var localVideo = Bundle . loadView ( fromNib: " VideoView " , withType: VideoView . self)
57- var remoteVideo = Bundle . loadView ( fromNib: " VideoView " , withType: VideoView . self)
58- @IBOutlet weak var localVideoContainer : UIView !
59- @IBOutlet weak var remoteVideoContainer : UIView !
56+ var foregroundVideo = Bundle . loadView ( fromNib: " VideoView " , withType: VideoView . self)
57+ var backgroundVideo = Bundle . loadView ( fromNib: " VideoView " , withType: VideoView . self)
58+ @IBOutlet weak var foregroundVideoContainer : UIView !
59+ @IBOutlet weak var backgroundVideoContainer : UIView !
60+ @IBOutlet weak var clientRoleToggleView : UIView !
61+ @IBOutlet weak var ultraLowLatencyToggleView : UIView !
6062 @IBOutlet weak var clientRoleToggle : UISwitch !
6163 @IBOutlet weak var ultraLowLatencyToggle : UISwitch !
64+ var remoteUid : UInt ? {
65+ didSet {
66+ foregroundVideoContainer. isHidden = !( role == . broadcaster && remoteUid != nil )
67+ }
68+ }
6269 var agoraKit : AgoraRtcEngineKit !
6370 var role : AgoraClientRole = . broadcaster {
6471 didSet {
65- localVideoContainer . isHidden = role != . broadcaster
72+ foregroundVideoContainer . isHidden = ! ( role == . broadcaster && remoteUid != nil )
6673 ultraLowLatencyToggle. isEnabled = role == . audience
6774 }
6875 }
76+ var isLocalVideoForeground = false {
77+ didSet {
78+ if isLocalVideoForeground {
79+ foregroundVideo. setPlaceholder ( text: " Local Host " . localized)
80+ backgroundVideo. setPlaceholder ( text: " Remote Host " . localized)
81+ } else {
82+ foregroundVideo. setPlaceholder ( text: " Remote Host " . localized)
83+ backgroundVideo. setPlaceholder ( text: " Local Host " . localized)
84+ }
85+ }
86+ }
6987 var isUltraLowLatencyOn : Bool = false
7088
7189 // indicate if current instance has joined channel
@@ -75,12 +93,10 @@ class LiveStreamingMain: BaseViewController {
7593 super. viewDidLoad ( )
7694
7795 // layout render view
78- localVideoContainer. addSubview ( localVideo)
79- remoteVideoContainer. addSubview ( remoteVideo)
80- localVideo. setPlaceholder ( text: " Local Host " . localized)
81- localVideo. bindFrameToSuperviewBounds ( )
82- remoteVideo. setPlaceholder ( text: " Remote Host " . localized)
83- remoteVideo. bindFrameToSuperviewBounds ( )
96+ foregroundVideoContainer. addSubview ( foregroundVideo)
97+ backgroundVideoContainer. addSubview ( backgroundVideo)
98+ foregroundVideo. bindFrameToSuperviewBounds ( )
99+ backgroundVideo. bindFrameToSuperviewBounds ( )
84100
85101 // set up agora instance when view loadedlet config = AgoraRtcEngineConfig()
86102 let config = AgoraRtcEngineConfig ( )
@@ -92,6 +108,12 @@ class LiveStreamingMain: BaseViewController {
92108 guard let channelName = configs [ " channelName " ] as? String ,
93109 let role = configs [ " role " ] as? AgoraClientRole else { return }
94110
111+ // for audience put local video in foreground
112+ isLocalVideoForeground = role == . audience
113+ // if inital role is broadcaster, do not show audience options
114+ clientRoleToggleView. isHidden = role == . broadcaster
115+ ultraLowLatencyToggleView. isHidden = role == . broadcaster
116+
95117 // make this room live broadcasting room
96118 agoraKit. setChannelProfile ( . liveBroadcasting)
97119 updateClientRole ( role)
@@ -108,7 +130,7 @@ class LiveStreamingMain: BaseViewController {
108130 // 2. If app certificate is turned on at dashboard, token is needed
109131 // when joining channel. The channel name and uid used to calculate
110132 // the token has to match the ones used for channel join
111- let result = agoraKit. joinChannel ( byToken: nil , channelId: channelName, info: nil , uid: SCREEN_SHARE_BROADCASTER_UID ) { [ unowned self] ( channel, uid, elapsed) -> Void in
133+ let result = agoraKit. joinChannel ( byToken: nil , channelId: channelName, info: nil , uid: 0 ) { [ unowned self] ( channel, uid, elapsed) -> Void in
112134 self . isJoined = true
113135 LogUtils . log ( message: " Join \( channel) with uid \( uid) elapsed \( elapsed) ms " , level: . info)
114136 }
@@ -138,7 +160,7 @@ class LiveStreamingMain: BaseViewController {
138160 let videoCanvas = AgoraRtcVideoCanvas ( )
139161 videoCanvas. uid = 0
140162 // the view to be binded
141- videoCanvas. view = localVideo . videoView
163+ videoCanvas. view = localVideoCanvas ( )
142164 videoCanvas. renderMode = . hidden
143165 agoraKit. setupLocalVideo ( videoCanvas)
144166
@@ -159,6 +181,33 @@ class LiveStreamingMain: BaseViewController {
159181 agoraKit. setClientRole ( . audience, options: options)
160182 }
161183
184+ func localVideoCanvas( ) -> UIView {
185+ return isLocalVideoForeground ? foregroundVideo. videoView : backgroundVideo. videoView
186+ }
187+
188+ func remoteVideoCanvas( ) -> UIView {
189+ return isLocalVideoForeground ? backgroundVideo. videoView : foregroundVideo. videoView
190+ }
191+
192+ @IBAction func onTapForegroundVideo( _ sender: UIGestureRecognizer ) {
193+ isLocalVideoForeground = !isLocalVideoForeground
194+
195+ let localVideoCanvas = AgoraRtcVideoCanvas ( )
196+ localVideoCanvas. uid = 0
197+ localVideoCanvas. renderMode = . hidden
198+ localVideoCanvas. view = self . localVideoCanvas ( )
199+
200+ let remoteVideoCanvas = AgoraRtcVideoCanvas ( )
201+ remoteVideoCanvas. renderMode = . hidden
202+ remoteVideoCanvas. view = self . remoteVideoCanvas ( )
203+
204+ agoraKit. setupLocalVideo ( localVideoCanvas)
205+ if let uid = remoteUid {
206+ remoteVideoCanvas. uid = uid
207+ agoraKit. setupRemoteVideo ( remoteVideoCanvas)
208+ }
209+ }
210+
162211 @IBAction func onToggleClientRole( _ sender: UISwitch ) {
163212 let role : AgoraClientRole = sender. isOn ? . broadcaster : . audience
164213 updateClientRole ( role)
@@ -227,13 +276,16 @@ extension LiveStreamingMain: AgoraRtcEngineDelegate {
227276 func rtcEngine( _ engine: AgoraRtcEngineKit , didJoinedOfUid uid: UInt , elapsed: Int ) {
228277 LogUtils . log ( message: " remote user join: \( uid) \( elapsed) ms " , level: . info)
229278
279+ //record remote uid
280+ remoteUid = uid
281+
230282 // Only one remote video view is available for this
231283 // tutorial. Here we check if there exists a surface
232284 // view tagged as this uid.
233285 let videoCanvas = AgoraRtcVideoCanvas ( )
234286 videoCanvas. uid = uid
235287 // the view to be binded
236- videoCanvas. view = remoteVideo . videoView
288+ videoCanvas. view = remoteVideoCanvas ( )
237289 videoCanvas. renderMode = . hidden
238290 agoraKit. setupRemoteVideo ( videoCanvas)
239291 }
@@ -245,6 +297,11 @@ extension LiveStreamingMain: AgoraRtcEngineDelegate {
245297 func rtcEngine( _ engine: AgoraRtcEngineKit , didOfflineOfUid uid: UInt , reason: AgoraUserOfflineReason ) {
246298 LogUtils . log ( message: " remote user left: \( uid) reason \( reason) " , level: . info)
247299
300+ //clear remote uid
301+ if ( remoteUid == uid) {
302+ remoteUid = nil
303+ }
304+
248305 // to unlink your view from sdk, so that your view reference will be released
249306 // note the video will stay at its last frame, to completely remove it
250307 // you will need to remove the EAGL sublayer from your binded view
0 commit comments