opentok 3.0.3 → 4.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.github/workflows/metrics.yml +17 -0
- data/.travis.yml +3 -1
- data/CODE_OF_CONDUCT.md +128 -0
- data/README.md +312 -28
- data/lib/opentok/archive.rb +45 -4
- data/lib/opentok/archives.rb +73 -5
- data/lib/opentok/broadcast.rb +118 -0
- data/lib/opentok/broadcasts.rb +149 -0
- data/lib/opentok/client.rb +212 -7
- data/lib/opentok/connections.rb +28 -0
- data/lib/opentok/constants.rb +1 -1
- data/lib/opentok/exceptions.rb +6 -0
- data/lib/opentok/opentok.rb +44 -10
- data/lib/opentok/session.rb +5 -0
- data/lib/opentok/signals.rb +47 -0
- data/lib/opentok/sip.rb +33 -0
- data/lib/opentok/stream.rb +46 -0
- data/lib/opentok/stream_list.rb +18 -0
- data/lib/opentok/streams.rb +79 -0
- data/lib/opentok/version.rb +1 -1
- data/opentok.gemspec +9 -8
- data/sample/Broadcast/Gemfile +4 -0
- data/sample/Broadcast/README.md +201 -0
- data/sample/Broadcast/broadcast_sample.rb +97 -0
- data/sample/Broadcast/public/css/sample.css +64 -0
- data/sample/Broadcast/public/js/host.js +185 -0
- data/sample/Broadcast/public/js/participant.js +85 -0
- data/sample/Broadcast/views/host.erb +82 -0
- data/sample/Broadcast/views/index.erb +32 -0
- data/sample/Broadcast/views/layout.erb +29 -0
- data/sample/Broadcast/views/participant.erb +27 -0
- data/sample/HelloWorld/public/js/helloworld.js +4 -10
- data/sample/HelloWorld/views/index.erb +1 -3
- data/spec/cassettes/OpenTok_Archives/calls_layout_on_archive_object.yml +47 -0
- data/spec/cassettes/OpenTok_Archives/changes_the_layout_of_an_archive.yml +38 -0
- data/spec/cassettes/OpenTok_Archives/http_client_errors/.yml +34 -0
- data/spec/cassettes/OpenTok_Archives/should_create_archives.yml +3 -1
- data/spec/cassettes/OpenTok_Archives/should_create_audio_only_archives.yml +3 -1
- data/spec/cassettes/OpenTok_Archives/should_create_custom_layout_archives.yml +50 -0
- data/spec/cassettes/OpenTok_Archives/should_create_hd_archives.yml +54 -0
- data/spec/cassettes/OpenTok_Archives/should_create_individual_archives.yml +3 -1
- data/spec/cassettes/OpenTok_Archives/should_create_named_archives.yml +3 -1
- data/spec/cassettes/OpenTok_Archives/should_delete_an_archive_by_id.yml +3 -1
- data/spec/cassettes/OpenTok_Archives/should_find_archives_by_id.yml +3 -1
- data/spec/cassettes/OpenTok_Archives/should_find_archives_with_unknown_properties.yml +3 -1
- data/spec/cassettes/OpenTok_Archives/should_find_expired_archives.yml +3 -1
- data/spec/cassettes/OpenTok_Archives/should_find_paused_archives_by_id.yml +3 -1
- data/spec/cassettes/OpenTok_Archives/should_stop_archives.yml +3 -1
- data/spec/cassettes/OpenTok_Archives/when_many_archives_are_created/should_return_all_archives.yml +3 -1
- data/spec/cassettes/OpenTok_Archives/when_many_archives_are_created/should_return_archives_with_an_offset.yml +3 -1
- data/spec/cassettes/OpenTok_Archives/when_many_archives_are_created/should_return_count_number_of_archives.yml +3 -1
- data/spec/cassettes/OpenTok_Archives/when_many_archives_are_created/should_return_part_of_the_archives_when_using_offset_and_count.yml +3 -1
- data/spec/cassettes/OpenTok_Archives/when_many_archives_are_created/should_return_session_archives.yml +3 -1
- data/spec/cassettes/OpenTok_Broadcasts/calls_layout_on_broadcast_object.yml +57 -0
- data/spec/cassettes/OpenTok_Broadcasts/changes_the_layout_of_a_broadcast.yml +38 -0
- data/spec/cassettes/OpenTok_Broadcasts/fetches_a_hls_broadcast_url.yml +52 -0
- data/spec/cassettes/OpenTok_Broadcasts/finds_a_broadcast.yml +57 -0
- data/spec/cassettes/OpenTok_Broadcasts/starts_a_rtmp_broadcast.yml +61 -0
- data/spec/cassettes/OpenTok_Broadcasts/stops_a_broadcast.yml +47 -0
- data/spec/cassettes/OpenTok_Connections/forces_a_connection_to_be_terminated.yml +38 -0
- data/spec/cassettes/OpenTok_OpenTok/when_initialized_properly/_create_session/creates_always_archived_sessions.yml +3 -1
- data/spec/cassettes/OpenTok_OpenTok/when_initialized_properly/_create_session/creates_default_sessions.yml +3 -1
- data/spec/cassettes/OpenTok_OpenTok/when_initialized_properly/_create_session/creates_relayed_media_sessions.yml +3 -1
- data/spec/cassettes/OpenTok_OpenTok/when_initialized_properly/_create_session/creates_relayed_media_sessions_for_invalid_media_modes.yml +3 -1
- data/spec/cassettes/OpenTok_OpenTok/when_initialized_properly/_create_session/creates_relayed_media_sessions_with_a_location_hint.yml +3 -1
- data/spec/cassettes/OpenTok_OpenTok/when_initialized_properly/_create_session/creates_routed_media_sessions.yml +3 -1
- data/spec/cassettes/OpenTok_OpenTok/when_initialized_properly/_create_session/creates_routed_media_sessions_with_a_location_hint.yml +3 -1
- data/spec/cassettes/OpenTok_OpenTok/when_initialized_properly/_create_session/creates_sessions_with_a_location_hint.yml +3 -1
- data/spec/cassettes/OpenTok_OpenTok/when_initialized_properly/with_an_addendum_to_the_user_agent_string/should_append_the_addendum_to_the_user_agent_header.yml +3 -1
- data/spec/cassettes/OpenTok_Signals/receives_a_valid_response_for_a_connection.yml +39 -0
- data/spec/cassettes/OpenTok_Signals/receives_a_valid_response_for_all_connections.yml +39 -0
- data/spec/cassettes/OpenTok_Sip/receives_a_valid_response.yml +3 -1
- data/spec/cassettes/OpenTok_Streams/get_all_streams_information.yml +55 -0
- data/spec/cassettes/OpenTok_Streams/get_specific_stream_information.yml +44 -0
- data/spec/cassettes/OpenTok_Streams/layout_working_on_two_stream_list.yml +38 -0
- data/spec/opentok/archives_spec.rb +84 -1
- data/spec/opentok/broadcasts_spec.rb +171 -0
- data/spec/opentok/client_spec.rb +51 -0
- data/spec/opentok/connection_spec.rb +38 -0
- data/spec/opentok/opentok_spec.rb +21 -0
- data/spec/opentok/signal_spec.rb +50 -0
- data/spec/opentok/streams_spec.rb +75 -0
- data/spec/spec_helper.rb +2 -0
- metadata +84 -22
data/lib/opentok/client.rb
CHANGED
@@ -12,18 +12,20 @@ module OpenTok
|
|
12
12
|
class Client
|
13
13
|
include HTTParty
|
14
14
|
|
15
|
-
open_timeout 2 # Set HTTParty default timeout (open/read) to 2 seconds
|
16
|
-
|
17
15
|
# TODO: expose a setting for http debugging for developers
|
18
16
|
# debug_output $stdout
|
19
17
|
|
20
|
-
|
18
|
+
attr_accessor :api_key, :api_secret, :api_url, :ua_addendum, :timeout_length
|
19
|
+
|
20
|
+
def initialize(api_key, api_secret, api_url, ua_addendum='', opts={})
|
21
21
|
self.class.base_uri api_url
|
22
22
|
self.class.headers({
|
23
|
-
"User-Agent" => "OpenTok-Ruby-SDK/#{VERSION}" + "-Ruby-Version-#{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}" + (ua_addendum ? " #{ua_addendum}" : "")
|
23
|
+
"User-Agent" => "OpenTok-Ruby-SDK/#{VERSION}" + "-Ruby-Version-#{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}" + (ua_addendum ? " #{ua_addendum}" : "")
|
24
24
|
})
|
25
25
|
@api_key = api_key
|
26
26
|
@api_secret = api_secret
|
27
|
+
@timeout_length = opts[:timeout_length] || 2
|
28
|
+
self.class.open_timeout @timeout_length
|
27
29
|
end
|
28
30
|
|
29
31
|
def generate_jwt(api_key, api_secret)
|
@@ -164,6 +166,72 @@ module OpenTok
|
|
164
166
|
raise OpenTokError, "Failed to connect to OpenTok. Response code: #{e.message}"
|
165
167
|
end
|
166
168
|
|
169
|
+
def layout_archive(archive_id, opts)
|
170
|
+
opts.extend(HashExtensions)
|
171
|
+
response = self.class.put("/v2/project/#{@api_key}/archive/#{archive_id}/layout", {
|
172
|
+
:body => opts.camelize_keys!.to_json,
|
173
|
+
:headers => generate_headers("Content-Type" => "application/json")
|
174
|
+
})
|
175
|
+
case response.code
|
176
|
+
when 200
|
177
|
+
response
|
178
|
+
when 400
|
179
|
+
raise OpenTokArchiveError, "Setting the layout failed. The request was invalid or invalid layout options were given."
|
180
|
+
when 403
|
181
|
+
raise OpenTokAuthenticationError, "Authentication failed. API Key: #{@api_key}"
|
182
|
+
when 500
|
183
|
+
raise OpenTokError, "Setting the layout failed. OpenTok server error."
|
184
|
+
else
|
185
|
+
raise OpenTokArchiveError, "Setting the layout failed."
|
186
|
+
end
|
187
|
+
rescue StandardError => e
|
188
|
+
raise OpenTokError, "Failed to connect to OpenTok. Response code: #{e.message}"
|
189
|
+
end
|
190
|
+
|
191
|
+
def forceDisconnect(session_id, connection_id)
|
192
|
+
response = self.class.delete("/v2/project/#{@api_key}/session/#{session_id}/connection/#{connection_id}", {
|
193
|
+
:headers => generate_headers("Content-Type" => "application/json")
|
194
|
+
})
|
195
|
+
case response.code
|
196
|
+
when 204
|
197
|
+
response
|
198
|
+
when 400
|
199
|
+
raise ArgumentError, "Force disconnect failed. Connection ID #{connection_id} or Session ID #{session_id} is invalid"
|
200
|
+
when 403
|
201
|
+
raise OpenTokAuthenticationError, "You are not authorized to forceDisconnect, check your authentication credentials or token type is non-moderator"
|
202
|
+
when 404
|
203
|
+
raise OpenTokConnectionError, "The client specified by the connection ID: #{connection_id} is not connected to the session"
|
204
|
+
end
|
205
|
+
rescue StandardError => e
|
206
|
+
raise OpenTokError, "Failed to connect to OpenTok. Response code: #{e.message}"
|
207
|
+
end
|
208
|
+
|
209
|
+
def signal(session_id, connection_id, opts)
|
210
|
+
opts.extend(HashExtensions)
|
211
|
+
connectionPath = connection_id.to_s.empty? ? "" : "/connection/#{connection_id}"
|
212
|
+
url = "/v2/project/#{@api_key}/session/#{session_id}#{connectionPath}/signal"
|
213
|
+
response = self.class.post(url, {
|
214
|
+
:body => opts.camelize_keys!.to_json,
|
215
|
+
:headers => generate_headers("Content-Type" => "application/json")
|
216
|
+
})
|
217
|
+
case response.code
|
218
|
+
when 204
|
219
|
+
response
|
220
|
+
when 400
|
221
|
+
raise ArgumentError, "One of the signal properties — data, type, sessionId or connectionId — is invalid."
|
222
|
+
when 403
|
223
|
+
raise OpenTokAuthenticationError, "You are not authorized to send the signal. Check your authentication credentials."
|
224
|
+
when 404
|
225
|
+
raise OpenTokError, "The client specified by the connectionId property is not connected to the session."
|
226
|
+
when 413
|
227
|
+
raise OpenTokError, "The type string exceeds the maximum length (128 bytes), or the data string exceeds the maximum size (8 kB)."
|
228
|
+
else
|
229
|
+
raise OpenTokError, "The signal could not be send."
|
230
|
+
end
|
231
|
+
rescue StandardError => e
|
232
|
+
raise OpenTokError, "Failed to connect to OpenTok. Response code: #{e.message}"
|
233
|
+
end
|
234
|
+
|
167
235
|
def dial(session_id, token, sip_uri, opts)
|
168
236
|
opts.extend(HashExtensions)
|
169
237
|
body = { "sessionId" => session_id,
|
@@ -179,14 +247,151 @@ module OpenTok
|
|
179
247
|
when 200
|
180
248
|
response
|
181
249
|
when 403
|
182
|
-
raise OpenTokAuthenticationError, "Authentication failed while dialing a
|
250
|
+
raise OpenTokAuthenticationError, "Authentication failed while dialing a SIP session. API Key: #{@api_key}"
|
183
251
|
when 404
|
184
|
-
raise OpenTokSipError, "The
|
252
|
+
raise OpenTokSipError, "The SIP session could not be dialed. The Session ID does not exist: #{session_id}"
|
253
|
+
else
|
254
|
+
raise OpenTokSipError, "The SIP session could not be dialed"
|
255
|
+
end
|
256
|
+
rescue StandardError => e
|
257
|
+
raise OpenTokError, "Failed to connect to OpenTok. Response code: #{e.message}"
|
258
|
+
end
|
259
|
+
|
260
|
+
def info_stream(session_id, stream_id)
|
261
|
+
streamId = stream_id.to_s.empty? ? '' : "/#{stream_id}"
|
262
|
+
url = "/v2/project/#{@api_key}/session/#{session_id}/stream#{streamId}"
|
263
|
+
response = self.class.get(url,
|
264
|
+
headers: generate_headers('Content-Type' => 'application/json'))
|
265
|
+
case response.code
|
266
|
+
when 200
|
267
|
+
response
|
268
|
+
when 400
|
269
|
+
raise ArgumentError, 'Invalid request. You did not pass in a valid session ID or stream ID.'
|
270
|
+
when 403
|
271
|
+
raise OpenTokAuthenticationError, 'Check your authentication credentials. You passed in an invalid OpenTok API key.'
|
272
|
+
when 408
|
273
|
+
raise ArgumentError, 'You passed in an invalid stream ID.'
|
274
|
+
when 500
|
275
|
+
raise OpenTokError, 'OpenTok server error.'
|
185
276
|
else
|
186
|
-
raise
|
277
|
+
raise OpenTokError, 'Could not fetch the stream information.'
|
187
278
|
end
|
188
279
|
rescue StandardError => e
|
189
280
|
raise OpenTokError, "Failed to connect to OpenTok. Response code: #{e.message}"
|
190
281
|
end
|
282
|
+
|
283
|
+
def layout_streams(session_id, opts)
|
284
|
+
opts.extend(HashExtensions)
|
285
|
+
response = self.class.put("/v2/project/#{@api_key}/session/#{session_id}/stream", {
|
286
|
+
:body => opts.camelize_keys!.to_json,
|
287
|
+
:headers => generate_headers("Content-Type" => "application/json")
|
288
|
+
})
|
289
|
+
case response.code
|
290
|
+
when 200
|
291
|
+
response
|
292
|
+
when 400
|
293
|
+
raise OpenTokStreamLayoutError, "Setting the layout failed. The request was invalid or invalid layout options were given."
|
294
|
+
when 403
|
295
|
+
raise OpenTokAuthenticationError, "Authentication failed. API Key: #{@api_key}"
|
296
|
+
when 500
|
297
|
+
raise OpenTokError, "Setting the layout failed. OpenTok server error."
|
298
|
+
else
|
299
|
+
raise OpenTokStreamLayoutError, "Setting the layout failed."
|
300
|
+
end
|
301
|
+
rescue StandardError => e
|
302
|
+
raise OpenTokError, "Failed to connect to OpenTok. Response code: #{e.message}"
|
303
|
+
end
|
304
|
+
|
305
|
+
def start_broadcast(session_id, opts)
|
306
|
+
opts.extend(HashExtensions)
|
307
|
+
body = { :sessionId => session_id }.merge(opts.camelize_keys!)
|
308
|
+
response = self.class.post("/v2/project/#{@api_key}/broadcast", {
|
309
|
+
:body => body.to_json,
|
310
|
+
:headers => generate_headers("Content-Type" => "application/json")
|
311
|
+
})
|
312
|
+
case response.code
|
313
|
+
when 200
|
314
|
+
response
|
315
|
+
when 400
|
316
|
+
raise OpenTokBroadcastError, "The broadcast could not be started. The request was invalid or invalid layout options or exceeded the limit of five simultaneous RTMP streams."
|
317
|
+
when 403
|
318
|
+
raise OpenTokAuthenticationError, "Authentication failed while starting a broadcast. API Key: #{@api_key}"
|
319
|
+
when 409
|
320
|
+
raise OpenTokBroadcastError, "The broadcast has already been started for this session."
|
321
|
+
when 500
|
322
|
+
raise OpenTokError, "OpenTok server error."
|
323
|
+
else
|
324
|
+
raise OpenTokBroadcastError, "The broadcast could not be started"
|
325
|
+
end
|
326
|
+
rescue StandardError => e
|
327
|
+
raise OpenTokError, "Failed to connect to OpenTok. Response code: #{e.message}"
|
328
|
+
end
|
329
|
+
|
330
|
+
def get_broadcast(broadcast_id)
|
331
|
+
response = self.class.get("/v2/project/#{@api_key}/broadcast/#{broadcast_id}", {
|
332
|
+
:headers => generate_headers
|
333
|
+
})
|
334
|
+
case response.code
|
335
|
+
when 200
|
336
|
+
response
|
337
|
+
when 400
|
338
|
+
raise OpenTokBroadcastError, "The request was invalid."
|
339
|
+
when 403
|
340
|
+
raise OpenTokAuthenticationError, "Authentication failed while getting a broadcast. API Key: #{@api_key}"
|
341
|
+
when 404
|
342
|
+
raise OpenTokBroadcastError, "No matching broadcast found (with the specified ID)"
|
343
|
+
when 500
|
344
|
+
raise OpenTokError, "OpenTok server error."
|
345
|
+
else
|
346
|
+
raise OpenTokBroadcastError, "Could not fetch broadcast information."
|
347
|
+
end
|
348
|
+
rescue StandardError => e
|
349
|
+
raise OpenTokError, "Failed to connect to OpenTok. Response code: #{e.message}"
|
350
|
+
end
|
351
|
+
|
352
|
+
def stop_broadcast(broadcast_id)
|
353
|
+
response = self.class.post("/v2/project/#{@api_key}/broadcast/#{broadcast_id}/stop", {
|
354
|
+
:headers => generate_headers
|
355
|
+
})
|
356
|
+
case response.code
|
357
|
+
when 200
|
358
|
+
response
|
359
|
+
when 400
|
360
|
+
raise OpenTokBroadcastError, "The request was invalid."
|
361
|
+
when 403
|
362
|
+
raise OpenTokAuthenticationError, "Authentication failed while stopping a broadcast. API Key: #{@api_key}"
|
363
|
+
when 404
|
364
|
+
raise OpenTokBroadcastError, "No matching broadcast found (with the specified ID) or it is already stopped"
|
365
|
+
when 500
|
366
|
+
raise OpenTokError, "OpenTok server error."
|
367
|
+
else
|
368
|
+
raise OpenTokBroadcastError, "The broadcast could not be stopped."
|
369
|
+
end
|
370
|
+
rescue StandardError => e
|
371
|
+
raise OpenTokError, "Failed to connect to OpenTok. Response code: #{e.message}"
|
372
|
+
end
|
373
|
+
|
374
|
+
def layout_broadcast(broadcast_id, opts)
|
375
|
+
opts.extend(HashExtensions)
|
376
|
+
response = self.class.put("/v2/project/#{@api_key}/broadcast/#{broadcast_id}/layout", {
|
377
|
+
:body => opts.camelize_keys!.to_json,
|
378
|
+
:headers => generate_headers("Content-Type" => "application/json")
|
379
|
+
})
|
380
|
+
case response.code
|
381
|
+
when 200
|
382
|
+
response
|
383
|
+
when 400
|
384
|
+
raise OpenTokBroadcastError, "The layout operation could not be performed. The request was invalid or invalid layout options."
|
385
|
+
when 403
|
386
|
+
raise OpenTokAuthenticationError, "Authentication failed for broadcast layout. API Key: #{@api_key}"
|
387
|
+
when 500
|
388
|
+
raise OpenTokError, "OpenTok server error."
|
389
|
+
else
|
390
|
+
raise OpenTokBroadcastError, "The broadcast layout could not be performed."
|
391
|
+
end
|
392
|
+
rescue StandardError => e
|
393
|
+
raise OpenTokError, "Failed to connect to OpenTok. Response code: #{e.message}"
|
394
|
+
end
|
395
|
+
|
191
396
|
end
|
192
397
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module OpenTok
|
2
|
+
# A class for working with OpenTok connections.
|
3
|
+
class Connections
|
4
|
+
# @private
|
5
|
+
def initialize(client)
|
6
|
+
@client = client
|
7
|
+
end
|
8
|
+
|
9
|
+
# Force a client to disconnect from an OpenTok session.
|
10
|
+
#
|
11
|
+
# A client must be actively connected to the OpenTok session for you to disconnect it.
|
12
|
+
#
|
13
|
+
# @param [String] session_id The session ID of the OpenTok session.
|
14
|
+
# @param [String] connection_id The connection ID of the client in the session.
|
15
|
+
#
|
16
|
+
# @raise [ArgumentError] The connection_id or session_id is invalid.
|
17
|
+
# @raise [OpenTokAuthenticationError] You are not authorized to disconnect the connection. Check your authentication credentials.
|
18
|
+
# @raise [OpenTokConnectionError] The client specified by the connection_id property is not connected to the session.
|
19
|
+
#
|
20
|
+
def forceDisconnect(session_id, connection_id )
|
21
|
+
raise ArgumentError, "session_id not provided" if session_id.to_s.empty?
|
22
|
+
raise ArgumentError, "connection_id not provided" if connection_id.to_s.empty?
|
23
|
+
response = @client.forceDisconnect(session_id, connection_id)
|
24
|
+
(200..300).include? response.code
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
data/lib/opentok/constants.rb
CHANGED
@@ -2,6 +2,6 @@ module OpenTok
|
|
2
2
|
API_URL = "https://api.opentok.com"
|
3
3
|
TOKEN_SENTINEL = "T1=="
|
4
4
|
ROLES = { subscriber: "subscriber", publisher: "publisher", moderator: "moderator" }
|
5
|
-
ARCHIVE_MODES = Set.new([:manual, :always])
|
5
|
+
ARCHIVE_MODES = ::Set.new([:manual, :always])
|
6
6
|
AUTH_EXPIRE = 300
|
7
7
|
end
|
data/lib/opentok/exceptions.rb
CHANGED
@@ -8,5 +8,11 @@ module OpenTok
|
|
8
8
|
class OpenTokSipError < OpenTokError; end
|
9
9
|
# Defines errors raised when you attempt an operation using an invalid OpenTok API key or secret.
|
10
10
|
class OpenTokAuthenticationError < OpenTokError; end
|
11
|
+
# Defines errors raised when you attempt a force disconnect a client and it is not connected to the session.
|
12
|
+
class OpenTokConnectionError < OpenTokError; end
|
13
|
+
# Defines errors raised when you attempt set layout classes to a stream.
|
14
|
+
class OpenTokStreamLayoutError < OpenTokError; end
|
15
|
+
# Defines errors raised when you perform Broadcast operations.
|
16
|
+
class OpenTokBroadcastError < OpenTokError; end
|
11
17
|
|
12
18
|
end
|
data/lib/opentok/opentok.rb
CHANGED
@@ -2,17 +2,24 @@ require "opentok/constants"
|
|
2
2
|
require "opentok/session"
|
3
3
|
require "opentok/client"
|
4
4
|
require "opentok/token_generator"
|
5
|
+
require "opentok/connections"
|
5
6
|
require "opentok/archives"
|
6
7
|
require "opentok/sip"
|
8
|
+
require "opentok/streams"
|
9
|
+
require "opentok/signals"
|
10
|
+
require "opentok/broadcasts"
|
7
11
|
|
8
12
|
require "resolv"
|
9
13
|
require "set"
|
10
14
|
|
11
15
|
module OpenTok
|
12
|
-
# Contains methods for creating OpenTok sessions
|
16
|
+
# Contains methods for creating OpenTok sessions and generating tokens. It also includes
|
17
|
+
# methods for returning object that let you work with archives, work with live streaming
|
18
|
+
# broadcasts, using SIP interconnect, sending signals to sessions, disconnecting clients from
|
19
|
+
# sessions, and setting the layout classes for streams.
|
13
20
|
#
|
14
21
|
# To create a new OpenTok object, call the OpenTok constructor with your OpenTok API key
|
15
|
-
# and the API secret
|
22
|
+
# and the API secret for your {https://tokbox.com/account OpenTok project}. Do not
|
16
23
|
# publicly share your API secret. You will use it with the OpenTok constructor (only on your web
|
17
24
|
# server) to create OpenTok sessions.
|
18
25
|
#
|
@@ -20,7 +27,7 @@ module OpenTok
|
|
20
27
|
# @attr_reader [String] api_key @private The OpenTok API key.
|
21
28
|
#
|
22
29
|
#
|
23
|
-
# @!method generate_token(options)
|
30
|
+
# @!method generate_token(session_id, options)
|
24
31
|
# Generates a token for a given session.
|
25
32
|
#
|
26
33
|
# @param [String] session_id The session ID of the session to be accessed by the client using
|
@@ -45,6 +52,11 @@ module OpenTok
|
|
45
52
|
# end-user. For example, you can pass the user ID, name, or other data describing the
|
46
53
|
# end-user. The length of the string is limited to 1000 characters. This data cannot be
|
47
54
|
# updated once it is set.
|
55
|
+
# @option options [Array] :initial_layout_class_list
|
56
|
+
# An array of class names (strings) to be used as the initial layout classes for streams
|
57
|
+
# published by the client. Layout classes are used in customizing the layout of videos in
|
58
|
+
# {https://tokbox.com/developer/guides/broadcast/live-streaming/ live streaming broadcasts}
|
59
|
+
# and {https://tokbox.com/developer/guides/archiving/layout-control.html composed archives}.
|
48
60
|
# @return [String] The token string.
|
49
61
|
class OpenTok
|
50
62
|
|
@@ -57,19 +69,21 @@ module OpenTok
|
|
57
69
|
# @private
|
58
70
|
# don't want these to be mutable, may cause bugs related to inconsistency since these values are
|
59
71
|
# cached in objects that this can create
|
60
|
-
attr_reader :api_key, :api_secret, :api_url, :ua_addendum
|
72
|
+
attr_reader :api_key, :api_secret, :timeout_length, :api_url, :ua_addendum
|
61
73
|
|
62
74
|
##
|
63
75
|
# Create a new OpenTok object.
|
64
76
|
#
|
65
|
-
# @param [String] api_key
|
66
|
-
#
|
77
|
+
# @param [String] api_key The OpenTok API key for your
|
78
|
+
# {https://tokbox.com/account OpenTok project}.
|
67
79
|
# @param [String] api_secret Your OpenTok API key.
|
68
80
|
# @option opts [Symbol] :api_url Do not set this parameter. It is for internal use by TokBox.
|
69
81
|
# @option opts [Symbol] :ua_addendum Do not set this parameter. It is for internal use by TokBox.
|
82
|
+
# @option opts [Symbol] :timeout_length Custom timeout in seconds. If not provided, defaults to 2 seconds.
|
70
83
|
def initialize(api_key, api_secret, opts={})
|
71
84
|
@api_key = api_key.to_s()
|
72
85
|
@api_secret = api_secret
|
86
|
+
@timeout_length = opts[:timeout_length] || 2
|
73
87
|
@api_url = opts[:api_url] || API_URL
|
74
88
|
@ua_addendum = opts[:ua_addendum]
|
75
89
|
end
|
@@ -89,8 +103,8 @@ module OpenTok
|
|
89
103
|
# Check the error message for details.
|
90
104
|
#
|
91
105
|
# You can also create a session using the OpenTok REST API (see
|
92
|
-
# http://www.tokbox.com/opentok/api/#session_id_production) or
|
93
|
-
#
|
106
|
+
# http://www.tokbox.com/opentok/api/#session_id_production) or at your
|
107
|
+
# {https://tokbox.com/account OpenTok account page}.
|
94
108
|
#
|
95
109
|
# @param [Hash] opts (Optional) This hash defines options for the session.
|
96
110
|
#
|
@@ -173,14 +187,34 @@ module OpenTok
|
|
173
187
|
@archives ||= Archives.new client
|
174
188
|
end
|
175
189
|
|
190
|
+
# A Broadcasts object, which lets you work with OpenTok live streaming broadcasts.
|
191
|
+
def broadcasts
|
192
|
+
@broadcasts ||= Broadcasts.new client
|
193
|
+
end
|
194
|
+
|
195
|
+
# A Sip object, which lets you use the OpenTok SIP gateway.
|
176
196
|
def sip
|
177
197
|
@sip ||= Sip.new client
|
178
198
|
end
|
179
199
|
|
180
|
-
|
200
|
+
# A Streams object, which lets you work with OpenTok live streaming broadcasts.
|
201
|
+
def streams
|
202
|
+
@streams ||= Streams.new client
|
203
|
+
end
|
181
204
|
|
205
|
+
# A Signals object, which lets you send signals to OpenTok sessions.
|
206
|
+
def signals
|
207
|
+
@signals ||= Signals.new client
|
208
|
+
end
|
209
|
+
|
210
|
+
# A Connections object, which lets disconnect clients from an OpenTok session.
|
211
|
+
def connections
|
212
|
+
@connections ||= Connections.new client
|
213
|
+
end
|
214
|
+
|
215
|
+
protected
|
182
216
|
def client
|
183
|
-
@client ||= Client.new api_key, api_secret, api_url, ua_addendum
|
217
|
+
@client ||= Client.new api_key, api_secret, api_url, ua_addendum, timeout_length: @timeout_length
|
184
218
|
end
|
185
219
|
|
186
220
|
end
|
data/lib/opentok/session.rb
CHANGED
@@ -42,6 +42,11 @@ module OpenTok
|
|
42
42
|
# end-user. For example, you can pass the user ID, name, or other data describing the
|
43
43
|
# end-user. The length of the string is limited to 1000 characters. This data cannot be
|
44
44
|
# updated once it is set.
|
45
|
+
# @option options [Array] :initial_layout_class_list
|
46
|
+
# An array of class names (strings) to be used as the initial layout classes for streams
|
47
|
+
# published by the client. Layout classes are used in customizing the layout of videos in
|
48
|
+
# {https://tokbox.com/developer/guides/broadcast/live-streaming/ live streaming broadcasts}
|
49
|
+
# and {https://tokbox.com/developer/guides/archiving/layout-control.html composed archives}.
|
45
50
|
# @return [String] The token string.
|
46
51
|
class Session
|
47
52
|
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module OpenTok
|
2
|
+
# A class for working with OpenTok signals.
|
3
|
+
class Signals
|
4
|
+
# @private
|
5
|
+
def initialize(client)
|
6
|
+
@client = client
|
7
|
+
end
|
8
|
+
|
9
|
+
# Sends a signal to clients connected to an OpenTok session.
|
10
|
+
#
|
11
|
+
# You can send a signal to all valid connections in a session or to a specific connection of
|
12
|
+
# a session.
|
13
|
+
#
|
14
|
+
# For more information on signaling, see
|
15
|
+
# {https://tokbox.com/developer/rest/#send_signal}.
|
16
|
+
#
|
17
|
+
# @param [String] session_id The session ID of the OpenTok session.
|
18
|
+
#
|
19
|
+
# @param [String] connection_id
|
20
|
+
# When a connection_id is specified, only that connection recieves the signal.
|
21
|
+
# Otherwise, the signal is sent to all clients connected to the session.
|
22
|
+
#
|
23
|
+
# @option options [String] :type This is the type of the signal. You can use this
|
24
|
+
# field to group and filter signals. It is a property of the Signal object received by
|
25
|
+
# the client(s).
|
26
|
+
#
|
27
|
+
# @option options [String] :data This is the data within the signal or the payload.
|
28
|
+
# Contains the main information to be sent in the signal. It is a property of the Signal object
|
29
|
+
# received by the client(s).
|
30
|
+
#
|
31
|
+
# @raise [ArgumentError]
|
32
|
+
# One of the signal properties — data, type, session_id, or connection_id — is invalid.
|
33
|
+
# @raise [OpenTokAuthenticationError]
|
34
|
+
# You are not authorized to send the signal. Check your authentication credentials.
|
35
|
+
# @raise [OpenTokError]
|
36
|
+
# The client specified by the connection_id property is not connected to the session.
|
37
|
+
# @raise [OpenTokError]
|
38
|
+
# The type string exceeds the maximum length (128 bytes), or the data string exceeds
|
39
|
+
# the maximum size (8 kB).
|
40
|
+
def send(session_id, connectionId = "", options = {})
|
41
|
+
raise ArgumentError, "session_id not provided" if session_id.to_s.empty?
|
42
|
+
response = @client.signal(session_id, connectionId, options)
|
43
|
+
(200..300).include? response.code
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|