1
+ // create Agora client
2
+ var client = AgoraRTC . createClient ( { mode : "rtc" , codec : "vp8" } ) ;
3
+
4
+ var localTracks = {
5
+ videoTrack : null ,
6
+ audioTrack : null
7
+ } ;
8
+
9
+ var localTrackState = {
10
+ videoTrackEnabled : true ,
11
+ audioTrackEnabled : true
12
+ }
13
+
14
+ var remoteUsers = { } ;
15
+ // Agora client options
16
+ var options = {
17
+ appid : null ,
18
+ channel : null ,
19
+ uid : null ,
20
+ token : null
21
+ } ;
22
+
23
+ // the demo can auto join channel with params in url
24
+ $ ( ( ) => {
25
+ var urlParams = new URL ( location . href ) . searchParams ;
26
+ options . appid = urlParams . get ( "appid" ) ;
27
+ options . channel = urlParams . get ( "channel" ) ;
28
+ options . token = urlParams . get ( "token" ) ;
29
+ if ( options . appid && options . channel ) {
30
+ $ ( "#appid" ) . val ( options . appid ) ;
31
+ $ ( "#token" ) . val ( options . token ) ;
32
+ $ ( "#channel" ) . val ( options . channel ) ;
33
+ $ ( "#join-form" ) . submit ( ) ;
34
+ }
35
+
36
+ } )
37
+
38
+ $ ( "#join-form" ) . submit ( async function ( e ) {
39
+ e . preventDefault ( ) ;
40
+ $ ( "#join" ) . attr ( "disabled" , true ) ;
41
+ try {
42
+ options . appid = $ ( "#appid" ) . val ( ) ;
43
+ options . token = $ ( "#token" ) . val ( ) ;
44
+ options . channel = $ ( "#channel" ) . val ( ) ;
45
+ await join ( ) ;
46
+ if ( options . token ) {
47
+ $ ( "#success-alert-with-token" ) . css ( "display" , "block" ) ;
48
+ } else {
49
+ $ ( "#success-alert a" ) . attr ( "href" , `index.html?appid=${ options . appid } &channel=${ options . channel } &token=${ options . token } ` ) ;
50
+ $ ( "#success-alert" ) . css ( "display" , "block" ) ;
51
+ }
52
+ } catch ( error ) {
53
+ console . error ( error ) ;
54
+ } finally {
55
+ $ ( "#leave" ) . attr ( "disabled" , false ) ;
56
+ }
57
+ } ) ;
58
+
59
+ $ ( "#leave" ) . click ( function ( e ) {
60
+ leave ( ) ;
61
+ } ) ;
62
+
63
+ $ ( "#mute-audio" ) . click ( function ( e ) {
64
+ if ( localTrackState . audioTrackEnabled ) {
65
+ muteAudio ( ) ;
66
+ } else {
67
+ unmuteAudio ( ) ;
68
+ }
69
+ } ) ;
70
+
71
+ $ ( "#mute-video" ) . click ( function ( e ) {
72
+ if ( localTrackState . videoTrackEnabled ) {
73
+ muteVideo ( ) ;
74
+ } else {
75
+ unmuteVideo ( ) ;
76
+ }
77
+ } )
78
+
79
+ async function join ( ) {
80
+ // add event listener to play remote tracks when remote users join, publish and leave.
81
+ client . on ( "user-published" , handleUserPublished ) ;
82
+ client . on ( "user-joined" , handleUserJoined ) ;
83
+ client . on ( "user-left" , handleUserLeft ) ;
84
+
85
+ // join a channel and create local tracks, we can use Promise.all to run them concurrently
86
+ [ options . uid , localTracks . audioTrack , localTracks . videoTrack ] = await Promise . all ( [
87
+ // join the channel
88
+ client . join ( options . appid , options . channel , options . token || null ) ,
89
+ // create local tracks, using microphone and camera
90
+ AgoraRTC . createMicrophoneAudioTrack ( ) ,
91
+ AgoraRTC . createCameraVideoTrack ( )
92
+ ] ) ;
93
+
94
+ showMuteButton ( ) ;
95
+
96
+ // play local video track
97
+ localTracks . videoTrack . play ( "local-player" ) ;
98
+ $ ( "#local-player-name" ) . text ( `localVideo(${ options . uid } )` ) ;
99
+
100
+ // publish local tracks to channel
101
+ await client . publish ( Object . values ( localTracks ) ) ;
102
+ console . log ( "publish success" ) ;
103
+ }
104
+
105
+ async function leave ( ) {
106
+ for ( trackName in localTracks ) {
107
+ var track = localTracks [ trackName ] ;
108
+ if ( track ) {
109
+ track . stop ( ) ;
110
+ track . close ( ) ;
111
+ localTracks [ trackName ] = undefined ;
112
+ }
113
+ }
114
+
115
+ // remove remote users and player views
116
+ remoteUsers = { } ;
117
+ $ ( "#remote-playerlist" ) . html ( "" ) ;
118
+
119
+ // leave the channel
120
+ await client . leave ( ) ;
121
+
122
+ $ ( "#local-player-name" ) . text ( "" ) ;
123
+ $ ( "#join" ) . attr ( "disabled" , false ) ;
124
+ $ ( "#leave" ) . attr ( "disabled" , true ) ;
125
+ hideMuteButton ( ) ;
126
+ console . log ( "client leaves channel success" ) ;
127
+ }
128
+
129
+ async function subscribe ( user , mediaType ) {
130
+ const uid = user . uid ;
131
+ // subscribe to a remote user
132
+ await client . subscribe ( user , mediaType ) ;
133
+ console . log ( "subscribe success" ) ;
134
+
135
+ // if the video wrapper element is not exist, create it.
136
+ if ( mediaType === 'video' ) {
137
+ if ( $ ( `#player-wrapper-${ uid } ` ) . length === 0 ) {
138
+ const player = $ ( `
139
+ <div id="player-wrapper-${ uid } ">
140
+ <p class="player-name">remoteUser(${ uid } )</p>
141
+ <div id="player-${ uid } " class="player"></div>
142
+ </div>
143
+ ` ) ;
144
+ $ ( "#remote-playerlist" ) . append ( player ) ;
145
+ }
146
+
147
+ // play the remote video.
148
+ user . videoTrack . play ( `player-${ uid } ` ) ;
149
+ }
150
+ if ( mediaType === 'audio' ) {
151
+ user . audioTrack . play ( ) ;
152
+ }
153
+ }
154
+
155
+ function handleUserJoined ( user ) {
156
+ const id = user . uid ;
157
+ remoteUsers [ id ] = user ;
158
+ }
159
+
160
+ function handleUserLeft ( user ) {
161
+ const id = user . uid ;
162
+ delete remoteUsers [ id ] ;
163
+ $ ( `#player-wrapper-${ id } ` ) . remove ( ) ;
164
+ }
165
+
166
+ function handleUserPublished ( user , mediaType ) {
167
+ subscribe ( user , mediaType ) ;
168
+ }
169
+
170
+ function hideMuteButton ( ) {
171
+ $ ( "#mute-video" ) . css ( "display" , "none" ) ;
172
+ $ ( "#mute-audio" ) . css ( "display" , "none" ) ;
173
+ }
174
+
175
+ function showMuteButton ( ) {
176
+ $ ( "#mute-video" ) . css ( "display" , "inline-block" ) ;
177
+ $ ( "#mute-audio" ) . css ( "display" , "inline-block" ) ;
178
+ }
179
+
180
+ async function muteAudio ( ) {
181
+ if ( ! localTracks . audioTrack ) return ;
182
+ await localTracks . audioTrack . setEnabled ( false ) ;
183
+ localTrackState . audioTrackEnabled = false ;
184
+ $ ( "#mute-audio" ) . text ( "Unmute Audio" ) ;
185
+ }
186
+
187
+ async function muteVideo ( ) {
188
+ if ( ! localTracks . videoTrack ) return ;
189
+ await localTracks . videoTrack . setEnabled ( false ) ;
190
+ localTrackState . videoTrackEnabled = false ;
191
+ $ ( "#mute-video" ) . text ( "Unmute Video" ) ;
192
+ }
193
+
194
+ async function unmuteAudio ( ) {
195
+ if ( ! localTracks . audioTrack ) return ;
196
+ await localTracks . audioTrack . setEnabled ( true ) ;
197
+ localTrackState . audioTrackEnabled = true ;
198
+ $ ( "#mute-audio" ) . text ( "Mute Audio" ) ;
199
+ }
200
+
201
+ async function unmuteVideo ( ) {
202
+ if ( ! localTracks . videoTrack ) return ;
203
+ await localTracks . videoTrack . setEnabled ( true ) ;
204
+ localTrackState . videoTrackEnabled = true ;
205
+ $ ( "#mute-video" ) . text ( "Mute Video" ) ;
206
+ }
0 commit comments