-
Notifications
You must be signed in to change notification settings - Fork 0
/
ViewController.m
279 lines (239 loc) · 7.76 KB
/
ViewController.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
//
// ViewController.m
// Lets-Build-TBExamplePublisher
//
// Copyright (c) 2013 TokBox, Inc. All rights reserved.
//
#import "ViewController.h"
#import <OpenTok/OpenTok.h>
#import "TBExamplePublisher.h"
#import "TBExampleSubscriber.h"
@interface ViewController ()
<OTSessionDelegate, OTSubscriberKitDelegate, OTPublisherDelegate>
@end
@implementation ViewController {
OTSession* _session;
TBExamplePublisher* _publisher;
TBExampleSubscriber* _subscriber;
}
static double widgetHeight = 240;
static double widgetWidth = 320;
// *** Fill the following variables using your own Project info ***
// *** https://dashboard.tokbox.com/projects ***
// Replace with your OpenTok API key
static NSString* const kApiKey = @"";
// Replace with your generated session ID
static NSString* const kSessionId = @"";
// Replace with your generated token
static NSString* const kToken = @"";
// Change to NO to subscribe to streams other than your own.
static bool subscribeToSelf = YES;
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
// Step 1: As the view comes into the foreground, initialize a new instance
// of OTSession and begin the connection process.
_session = [[OTSession alloc] initWithApiKey:kApiKey
sessionId:kSessionId
delegate:self];
[self doConnect];
}
- (BOOL)prefersStatusBarHidden
{
return YES;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:
(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
if (UIUserInterfaceIdiomPhone == [[UIDevice currentDevice]
userInterfaceIdiom])
{
return NO;
} else {
return YES;
}
}
#pragma mark - OpenTok methods
/**
* Asynchronously begins the session connect process. Some time later, we will
* expect a delegate method to call us back with the results of this action.
*/
- (void)doConnect
{
OTError *error;
[_session connectWithToken:kToken error:&error];
if (error)
{
[self showAlert:[error localizedDescription]];
}
}
/**
* Sets up an instance of OTPublisher to use with this session. OTPubilsher
* binds to the device camera and microphone, and will provide A/V streams
* to the OpenTok session.
*/
- (void)doPublish
{
_publisher = [[TBExamplePublisher alloc]
initWithDelegate:self
name:[[UIDevice currentDevice] name]];
OTError *error;
[_session publish:_publisher error:&error];
if (error)
{
[self showAlert:[error localizedDescription]];
}
[_publisher.view setFrame:CGRectMake(0, 0, widgetWidth, widgetHeight)];
[self.view addSubview:_publisher.view];
}
/**
* Cleans up the publisher and its view. At this point, the publisher should not
* be attached to the session any more.
*/
- (void)cleanupPublisher {
[_publisher.view removeFromSuperview];
_publisher = nil;
// this is a good place to notify the end-user that publishing has stopped.
}
/**
* Instantiates a subscriber for the given stream and asynchronously begins the
* process to begin receiving A/V content for this stream. Unlike doPublish,
* this method does not add the subscriber to the view hierarchy. Instead, we
* add the subscriber only after it has connected and begins receiving data.
*/
- (void)doSubscribe:(OTStream*)stream
{
_subscriber = [[TBExampleSubscriber alloc] initWithStream:stream
delegate:self];
OTError *error;
[_session subscribe:_subscriber error:&error];
if (error)
{
[self showAlert:[error localizedDescription]];
}
}
/**
* Cleans the subscriber from the view hierarchy, if any.
* NB: You do *not* have to call unsubscribe in your controller in response to
* a streamDestroyed event. Any subscribers (or the publisher) for a stream will
* be automatically removed from the session during cleanup of the stream.
*/
- (void)cleanupSubscriber
{
[_subscriber.view removeFromSuperview];
_subscriber = nil;
}
# pragma mark - OTSession delegate callbacks
- (void)sessionDidConnect:(OTSession*)session
{
NSLog(@"sessionDidConnect (%@)", session.sessionId);
// Step 2: We have successfully connected, now instantiate a publisher and
// begin pushing A/V streams into OpenTok.
[self doPublish];
}
- (void)sessionDidDisconnect:(OTSession*)session
{
NSString* alertMessage =
[NSString stringWithFormat:@"Session disconnected: (%@)",
session.sessionId];
NSLog(@"sessionDidDisconnect (%@)", alertMessage);
}
- (void)session:(OTSession*)mySession
streamCreated:(OTStream *)stream
{
NSLog(@"session streamCreated (%@)", stream.streamId);
// Step 3a: (if NO == subscribeToSelf): Begin subscribing to a stream we
// have seen on the OpenTok session.
if (nil == _subscriber && !subscribeToSelf)
{
[self doSubscribe:stream];
}
}
- (void)session:(OTSession*)session
streamDestroyed:(OTStream *)stream
{
NSLog(@"session streamDestroyed (%@)", stream.streamId);
if ([_subscriber.stream.streamId isEqualToString:stream.streamId])
{
[self cleanupSubscriber];
}
}
- (void) session:(OTSession *)session
connectionCreated:(OTConnection *)connection
{
NSLog(@"session connectionCreated (%@)", connection.connectionId);
}
- (void) session:(OTSession *)session
connectionDestroyed:(OTConnection *)connection
{
NSLog(@"session connectionDestroyed (%@)", connection.connectionId);
if ([_subscriber.stream.connection.connectionId
isEqualToString:connection.connectionId])
{
[self cleanupSubscriber];
}
}
- (void) session:(OTSession*)session
didFailWithError:(OTError*)error
{
NSLog(@"didFailWithError: (%@)", error);
}
# pragma mark - OTSubscriber delegate callbacks
- (void)subscriberDidConnectToStream:(OTSubscriberKit*)subscriber
{
NSLog(@"subscriberDidConnectToStream (%@)",
subscriber.stream.connection.connectionId);
[_subscriber.view setFrame:CGRectMake(0, widgetHeight, widgetWidth,
widgetHeight)];
[self.view addSubview:_subscriber.view];
}
- (void)subscriber:(OTSubscriberKit*)subscriber
didFailWithError:(OTError*)error
{
NSLog(@"subscriber %@ didFailWithError %@",
subscriber.stream.streamId,
error);
}
# pragma mark - OTPublisher delegate callbacks
- (void)publisher:(OTPublisherKit *)publisher
streamCreated:(OTStream *)stream
{
// Step 3b: (if YES == subscribeToSelf): Our own publisher is now visible to
// all participants in the OpenTok session. We will attempt to subscribe to
// our own stream. Expect to see a slight delay in the subscriber video and
// an echo of the audio coming from the device microphone.
if (nil == _subscriber && subscribeToSelf)
{
[self doSubscribe:stream];
}
}
- (void)publisher:(OTPublisherKit*)publisher
streamDestroyed:(OTStream *)stream
{
if ([_subscriber.stream.streamId isEqualToString:stream.streamId])
{
[self cleanupSubscriber];
}
[self cleanupPublisher];
}
- (void)publisher:(OTPublisherKit*)publisher
didFailWithError:(OTError*) error
{
NSLog(@"publisher didFailWithError %@", error);
[self cleanupPublisher];
}
- (void)showAlert:(NSString *)string
{
// show alertview on main UI
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"OTError"
message:string
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil] ;
[alert show];
});
}
@end