opentok 4.7.0 → 4.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '019bb7945d8571c4805cab88854fd49914fac7fbb7169b2b1351fa393237ea46'
4
- data.tar.gz: 9f167173216875bbc1b52bd2239c7fff7e9ff49c4aa92c28e6541d9fb178782d
3
+ metadata.gz: fc3a44c807492ac56f39fe6abed609c15c1627c3e2651f5d9a01cb8745dafa07
4
+ data.tar.gz: 6970f77ecb445dae4096bfbd440a9beebf3047b5a7fa0de6ff7343a726fb4c1f
5
5
  SHA512:
6
- metadata.gz: e24be36a973fd9fe2ed63a620dbff3f0cb2fa24939318fd0f353a76374c8c09e4e46c8c920e223015c6b536dfbeddc2d94e75909f6cc3fbb54e6b39f85077402
7
- data.tar.gz: 29b06c9529e61f19208d0c875ddf0caba12652afaaa4f87f59760a3c664a69b6a1686f200f1793a730b8518ec1d2f99cbd0ea7a29ee7ab2c5bcc7d42cb2b2af6
6
+ metadata.gz: 47fd19211b5616ce0d0862c69096a42c5de69285f2ee02be6873bcb84ace57a8c4631479bdef1420675c23283e834c353bcefc1a712984d1e639287c11b83e41
7
+ data.tar.gz: 93ce88395b8133e9d3d2cbb0e32740cd520827450987e278ba901234d18f49fdfb3197506f72fbadd981b303fb0c215b16b2c25ceaf361f3c3b2933d78dee360
data/CHANGES.md CHANGED
@@ -1,3 +1,11 @@
1
+ # 4.8.0
2
+
3
+ * Add support for Captions API [#267](https://github.com/opentok/OpenTok-Ruby-SDK/pull/267)
4
+
5
+ # 4.7.1
6
+
7
+ * Updates docs comments for `Broadcasts` and `Sip` [#266](https://github.com/opentok/OpenTok-Ruby-SDK/pull/266)
8
+
1
9
  # 4.7.0
2
10
 
3
11
  * Adds support for the End-to-end encryption (E2EE) feature [#259](https://github.com/opentok/OpenTok-Ruby-SDK/pull/259)
@@ -19,6 +19,15 @@ module OpenTok
19
19
  # @attr [int] updated_at
20
20
  # For this start method, this timestamp matches the createdAt timestamp.
21
21
  #
22
+ # @attr [int] maxBitRate
23
+ # The maximum bitrate for the broadcast stream(s), in bits per second.
24
+ #
25
+ # @attr [boolean] hasAudio
26
+ # The broadcast has audio enabled
27
+ #
28
+ # @attr [boolean] hasVideo
29
+ # The broadcast has video enabled
30
+ #
22
31
  # @attr [string] resolution
23
32
  # The resolution of the broadcast: either "640x480" (SD landscape, the default), "1280x720" (HD landscape),
24
33
  # "1920x1080" (FHD landscape), "480x640" (SD portrait), "720x1280" (HD portrait), or "1080x1920" (FHD portrait).
@@ -33,6 +42,12 @@ module OpenTok
33
42
  # You can include HLS, RTMP, or both as broadcast streams. If you include RTMP streaming,
34
43
  # you can specify up to five target RTMP streams (or just one).
35
44
  # The (<code>:hls</code>) property is set to an empty [Hash] object. The HLS URL is returned in the response.
45
+ # The `hlsStatus` property is set to one of the following:
46
+ # - "connecting" — The OpenTok server is in the process of starting transcoders. This is the initial state.
47
+ # - "ready" — The OpenTok server has succesfully initialized but the CDN is not consuming media.
48
+ # - "live" — The OpenTok server has succesfully initialized and the CDN is consuming media.
49
+ # - "ended" — The source stream has ended. If DVR is enabled and pre-recorded media is requested, then the status will transition to "live".
50
+ # - "error" — There is an error in the OpenTok platform.
36
51
  # The (<code>:rtmp</code>) property is set to an [Array] of Rtmp [Hash] properties.
37
52
  # For each RTMP stream, specify (<code>:serverUrl</code>) for the RTMP server URL,
38
53
  # (<code>:streamName</code>) such as the YouTube Live stream name or the Facebook stream key),
@@ -37,12 +37,16 @@ module OpenTok
37
37
  # If you do not specify an initial layout type, the broadcast uses the best fit
38
38
  # layout type.
39
39
  #
40
- # @option options [String] :multiBroadcastTag (Optional) Set this to support multiple broadcasts for the same session simultaneously.
41
- # Set this to a unique string for each simultaneous broadcast of an ongoing session. Note that the `multiBroadcastTag` value is *not* included
42
- # in the response for the methods to {https://tokbox.com/developer/rest/#list_broadcasts list live streaming broadcasts} and
43
- # {https://tokbox.com/developer/rest/#get_info_broadcast get information about a live streaming broadcast}.
40
+ # @option options [String] :multiBroadcastTag (Optional) Set this to support multiple broadcasts for the same session simultaneously.
41
+ # Set this to a unique string for each simultaneous broadcast of an ongoing session. Note that the `multiBroadcastTag` value is *not* included
42
+ # in the response for the methods to {https://tokbox.com/developer/rest/#list_broadcasts list live streaming broadcasts} and
43
+ # {https://tokbox.com/developer/rest/#get_info_broadcast get information about a live streaming broadcast}.
44
44
  # {https://tokbox.com/developer/guides/broadcast/live-streaming#simultaneous-broadcasts See Simultaneous broadcasts}.
45
45
  #
46
+ # @option options [int] maxBitRate
47
+ # The maximum bitrate for the broadcast stream(s), in bits per second.
48
+ # The minimum value is 100,000 and the maximum is 6,000,000.
49
+ #
46
50
  # @option options [int] maxDuration
47
51
  # The maximum duration for the broadcast, in seconds. The broadcast will automatically stop when
48
52
  # the maximum duration is reached. You can set the maximum duration to a value from 60 (60 seconds) to 36000 (10 hours).
@@ -95,6 +99,10 @@ module OpenTok
95
99
  # on {https://tokbox.com/developer/guides/archive-broadcast-layout/#stream-prioritization-rules stream prioritization rules}.
96
100
  # Important: this feature is currently available in the Standard environment only.
97
101
  #
102
+ # @option options [Boolean] :hasAudio Whether the broadcast has audio (default `true`)
103
+ #
104
+ # @option options [Boolean] :hasVideo Whether the broadcast has video (default `true`)
105
+ #
98
106
  # @return [Broadcast] The broadcast object, which includes properties defining the broadcast,
99
107
  # including the broadcast ID.
100
108
  #
@@ -0,0 +1,61 @@
1
+ module OpenTok
2
+ # A class for working with OpenTok captions.
3
+ class Captions
4
+ # @private
5
+ def initialize(client)
6
+ @client = client
7
+ end
8
+
9
+ # Starts live captions for the specified OpenTok session.
10
+ # See the {https://tokbox.com/developer/guides/live-captions/ OpenTok Live Captions developer guide}.
11
+ #
12
+ # @example
13
+ # opts = { "language_code" => "en-GB",
14
+ # "max_duration" => 5000,
15
+ # "partial_captions" => false,
16
+ # "status_callback_url" => status_callback_url
17
+ # }
18
+ # response = opentok.captions.start(session_id, token, opts)
19
+ #
20
+ # @param [String] session_id The session ID corresponding to the session for which captions will start.
21
+ # @param [String] token The token for the session ID with which the SIP user will use to connect.
22
+ # @param [Hash] options A hash defining options for the captions. For example:
23
+ # @option options [String] :language_code The BCP-47 code for a spoken language used on this call.
24
+ # The default value is "en-US". The following language codes are supported:
25
+ # - "en-AU" (English, Australia)
26
+ # - "en-GB" (Englsh, UK)
27
+ # - "es-US" (English, US)
28
+ # - "zh-CN” (Chinese, Simplified)
29
+ # - "fr-FR" (French)
30
+ # - "fr-CA" (French, Canadian)
31
+ # - "de-DE" (German)
32
+ # - "hi-IN" (Hindi, Indian)
33
+ # - "it-IT" (Italian)
34
+ # - "ja-JP" (Japanese)
35
+ # - "ko-KR" (Korean)
36
+ # - "pt-BR" (Portuguese, Brazilian)
37
+ # - "th-TH" (Thai)
38
+ # @option options [Integer] :max_duration The maximum duration for the audio captioning, in seconds.
39
+ # The default value is 14,400 seconds (4 hours), the maximum duration allowed.
40
+ # @option options [Boolean] :partial_captions Whether to enable this to faster captioning at the cost of some
41
+ # degree of inaccuracies. The default value is `true`.
42
+ # @option options [String] :status_callback_url A publicly reachable URL controlled by the customer and capable
43
+ # of generating the content to be rendered without user intervention. The minimum length of the URL is 15
44
+ # characters and the maximum length is 2048 characters.
45
+ # For more information, see {https://tokbox.com/developer/guides/live-captions/#live-caption-status-updates Live Caption status updates}.
46
+ def start(session_id, token, options = {})
47
+ @client.start_live_captions(session_id, token, options)
48
+ end
49
+
50
+ # Starts live captions for the specified OpenTok session.
51
+ # See the {https://tokbox.com/developer/guides/live-captions/ OpenTok Live Captions developer guide}.
52
+ #
53
+ # @example
54
+ # response = opentok.captions.stop(captions_id)
55
+ #
56
+ # @param [String] captions_id The ID for the captions to be stopped (returned from the `start` request).
57
+ def stop(captions_id)
58
+ @client.stop_live_captions(captions_id)
59
+ end
60
+ end
61
+ end
@@ -62,6 +62,8 @@ module OpenTok
62
62
  raise OpenTokError, "Failed to connect to OpenTok. Response code: #{e.message}"
63
63
  end
64
64
 
65
+ # Archives methods
66
+
65
67
  def start_archive(session_id, opts)
66
68
  opts.extend(HashExtensions)
67
69
  body = { "sessionId" => session_id }.merge(opts.camelize_keys!)
@@ -215,463 +217,526 @@ module OpenTok
215
217
  raise OpenTokError, "Failed to connect to OpenTok. Response code: #{e.message}"
216
218
  end
217
219
 
218
- def forceDisconnect(session_id, connection_id)
219
- response = self.class.delete("/v2/project/#{@api_key}/session/#{session_id}/connection/#{connection_id}", {
220
+ # Broadcasts methods
221
+
222
+ def start_broadcast(session_id, opts)
223
+ opts.extend(HashExtensions)
224
+ body = { :sessionId => session_id }.merge(opts.camelize_keys!)
225
+ response = self.class.post("/v2/project/#{@api_key}/broadcast", {
226
+ :body => body.to_json,
220
227
  :headers => generate_headers("Content-Type" => "application/json")
221
228
  })
222
229
  case response.code
223
- when 204
230
+ when 200
224
231
  response
225
232
  when 400
226
- raise ArgumentError, "Force disconnect failed. Connection ID #{connection_id} or Session ID #{session_id} is invalid"
233
+ 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."
227
234
  when 403
228
- raise OpenTokAuthenticationError, "You are not authorized to forceDisconnect, check your authentication credentials or token type is non-moderator"
235
+ raise OpenTokAuthenticationError, "Authentication failed while starting a broadcast. API Key: #{@api_key}"
236
+ when 409
237
+ raise OpenTokBroadcastError, "The broadcast has already been started for this session."
238
+ when 500
239
+ raise OpenTokError, "OpenTok server error."
240
+ else
241
+ raise OpenTokBroadcastError, "The broadcast could not be started"
242
+ end
243
+ rescue StandardError => e
244
+ raise OpenTokError, "Failed to connect to OpenTok. Response code: #{e.message}"
245
+ end
246
+
247
+ def get_broadcast(broadcast_id)
248
+ response = self.class.get("/v2/project/#{@api_key}/broadcast/#{broadcast_id}", {
249
+ :headers => generate_headers
250
+ })
251
+ case response.code
252
+ when 200
253
+ response
254
+ when 400
255
+ raise OpenTokBroadcastError, "The request was invalid."
256
+ when 403
257
+ raise OpenTokAuthenticationError, "Authentication failed while getting a broadcast. API Key: #{@api_key}"
229
258
  when 404
230
- raise OpenTokConnectionError, "The client specified by the connection ID: #{connection_id} is not connected to the session"
259
+ raise OpenTokBroadcastError, "No matching broadcast found (with the specified ID)"
260
+ when 500
261
+ raise OpenTokError, "OpenTok server error."
262
+ else
263
+ raise OpenTokBroadcastError, "Could not fetch broadcast information."
231
264
  end
232
265
  rescue StandardError => e
233
266
  raise OpenTokError, "Failed to connect to OpenTok. Response code: #{e.message}"
234
267
  end
235
268
 
236
- def force_mute_stream(session_id, stream_id)
237
- response = self.class.post("/v2/project/#{@api_key}/session/#{session_id}/stream/#{stream_id}/mute", {
238
- :headers => generate_headers("Content-Type" => "application/json")
269
+ def stop_broadcast(broadcast_id)
270
+ response = self.class.post("/v2/project/#{@api_key}/broadcast/#{broadcast_id}/stop", {
271
+ :headers => generate_headers
239
272
  })
240
273
  case response.code
241
274
  when 200
242
275
  response
243
276
  when 400
244
- raise ArgumentError, "Force mute failed. Stream ID #{stream_id} or Session ID #{session_id} is invalid"
277
+ raise OpenTokBroadcastError, "The request was invalid."
245
278
  when 403
246
- raise OpenTokAuthenticationError, "Authentication failed. API Key: #{@api_key}"
279
+ raise OpenTokAuthenticationError, "Authentication failed while stopping a broadcast. API Key: #{@api_key}"
247
280
  when 404
248
- raise OpenTokConnectionError, "Either Stream ID #{stream_id} or Session ID #{session_id} is invalid"
281
+ raise OpenTokBroadcastError, "No matching broadcast found (with the specified ID) or it is already stopped"
282
+ when 500
283
+ raise OpenTokError, "OpenTok server error."
284
+ else
285
+ raise OpenTokBroadcastError, "The broadcast could not be stopped."
249
286
  end
250
287
  rescue StandardError => e
251
288
  raise OpenTokError, "Failed to connect to OpenTok. Response code: #{e.message}"
252
289
  end
253
290
 
254
- def force_mute_session(session_id, opts)
291
+ def list_broadcasts(offset, count, session_id)
292
+ query = Hash.new
293
+ query[:offset] = offset unless offset.nil?
294
+ query[:count] = count unless count.nil?
295
+ query[:sessionId] = session_id unless session_id.nil?
296
+ response = self.class.get("/v2/project/#{@api_key}/broadcast", {
297
+ :query => query.empty? ? nil : query,
298
+ :headers => generate_headers,
299
+ })
300
+ case response.code
301
+ when 200
302
+ response
303
+ when 403
304
+ raise OpenTokAuthenticationError,
305
+ "Authentication failed while retrieving broadcasts. API Key: #{@api_key}"
306
+ else
307
+ raise OpenTokBroadcastError, "The broadcasts could not be retrieved."
308
+ end
309
+ rescue StandardError => e
310
+ raise OpenTokError, "Failed to connect to OpenTok. Response code: #{e.message}"
311
+ end
312
+
313
+ def layout_broadcast(broadcast_id, opts)
255
314
  opts.extend(HashExtensions)
256
- body = opts.camelize_keys!
257
- response = self.class.post("/v2/project/#{@api_key}/session/#{session_id}/mute", {
258
- :body => body.to_json,
315
+ response = self.class.put("/v2/project/#{@api_key}/broadcast/#{broadcast_id}/layout", {
316
+ :body => opts.camelize_keys!.to_json,
259
317
  :headers => generate_headers("Content-Type" => "application/json")
260
318
  })
261
319
  case response.code
262
320
  when 200
263
321
  response
264
322
  when 400
265
- raise ArgumentError, "Force mute failed. The request could not be processed due to a bad request"
323
+ raise OpenTokBroadcastError, "The layout operation could not be performed. The request was invalid or invalid layout options."
266
324
  when 403
267
- raise OpenTokAuthenticationError, "Authentication failed. API Key: #{@api_key}"
268
- when 404
269
- raise OpenTokConnectionError, "Session ID #{session_id} is invalid"
325
+ raise OpenTokAuthenticationError, "Authentication failed for broadcast layout. API Key: #{@api_key}"
326
+ when 500
327
+ raise OpenTokError, "OpenTok server error."
328
+ else
329
+ raise OpenTokBroadcastError, "The broadcast layout could not be performed."
270
330
  end
271
331
  rescue StandardError => e
272
332
  raise OpenTokError, "Failed to connect to OpenTok. Response code: #{e.message}"
273
333
  end
274
334
 
275
- def signal(session_id, connection_id, opts)
335
+ def select_streams_for_broadcast(broadcast_id, opts)
276
336
  opts.extend(HashExtensions)
277
- connectionPath = connection_id.to_s.empty? ? "" : "/connection/#{connection_id}"
278
- url = "/v2/project/#{@api_key}/session/#{session_id}#{connectionPath}/signal"
279
- response = self.class.post(url, {
280
- :body => opts.camelize_keys!.to_json,
337
+ body = opts.camelize_keys!
338
+ response = self.class.patch("/v2/project/#{@api_key}/broadcast/#{broadcast_id}/streams", {
339
+ :body => body.to_json,
281
340
  :headers => generate_headers("Content-Type" => "application/json")
282
341
  })
283
342
  case response.code
284
343
  when 204
285
344
  response
286
345
  when 400
287
- raise ArgumentError, "One of the signal properties — data, type, sessionId or connectionId — is invalid."
346
+ raise OpenTokBroadcastError, "The request was invalid."
288
347
  when 403
289
- raise OpenTokAuthenticationError, "You are not authorized to send the signal. Check your authentication credentials."
348
+ raise OpenTokAuthenticationError, "Authentication failed. API Key: #{@api_key}"
290
349
  when 404
291
- raise OpenTokError, "The client specified by the connectionId property is not connected to the session."
292
- when 413
293
- raise OpenTokError, "The type string exceeds the maximum length (128 bytes), or the data string exceeds the maximum size (8 kB)."
350
+ raise OpenTokBroadcastError, "No matching broadcast found with the specified ID: #{broadcast_id}"
351
+ when 405
352
+ raise OpenTokBroadcastError, "The broadcast was started with streamMode set to 'auto', which does not support stream manipulation."
353
+ when 500
354
+ raise OpenTokError, "OpenTok server error."
294
355
  else
295
- raise OpenTokError, "The signal could not be send."
356
+ raise OpenTokBroadcastError, "The broadcast streams could not be updated."
296
357
  end
297
358
  rescue StandardError => e
298
359
  raise OpenTokError, "Failed to connect to OpenTok. Response code: #{e.message}"
299
360
  end
300
361
 
301
- def connect_websocket(session_id, token, websocket_uri, opts)
302
- opts.extend(HashExtensions)
362
+ # Captions methods
363
+
364
+ def start_live_captions(session_id, token, options)
365
+ options.extend(HashExtensions)
303
366
  body = { "sessionId" => session_id,
304
367
  "token" => token,
305
- "websocket" => { "uri" => websocket_uri }.merge(opts.camelize_keys!)
306
- }
368
+ }.merge(options.camelize_keys!)
307
369
 
308
- response = self.class.post("/v2/project/#{@api_key}/connect", {
370
+ response = self.class.post("/v2/project/#{@api_key}/captions", {
309
371
  :body => body.to_json,
310
372
  :headers => generate_headers("Content-Type" => "application/json")
311
373
  })
312
374
  case response.code
313
- when 200
375
+ when 202
314
376
  response
315
377
  when 400
316
- raise ArgumentError, "One of the properties is invalid."
378
+ raise OpenTokCaptionsError, "The request was invalid."
317
379
  when 403
318
- raise OpenTokAuthenticationError, "You are not authorized to start the call, check your authentication information."
380
+ raise OpenTokAuthenticationError, "Authentication failed while starting captions. API Key: #{@api_key}"
319
381
  when 409
320
- raise OpenTokWebSocketError, "Conflict. Only routed sessions are allowed to initiate Connect Calls."
382
+ raise OpenTokCaptionsError, "Live captions have already started for this OpenTok Session: #{session_id}"
321
383
  when 500
322
384
  raise OpenTokError, "OpenTok server error."
323
385
  else
324
- raise OpenTokWebSocketError, "The WebSocket could not be connected"
386
+ raise OpenTokCaptionsError, "Captions could not be started"
325
387
  end
326
388
  rescue StandardError => e
327
389
  raise OpenTokError, "Failed to connect to OpenTok. Response code: #{e.message}"
328
390
  end
329
391
 
330
- def dial(session_id, token, sip_uri, opts)
331
- opts.extend(HashExtensions)
332
- body = { "sessionId" => session_id,
333
- "token" => token,
334
- "sip" => { "uri" => sip_uri }.merge(opts.camelize_keys!)
335
- }
336
-
337
- response = self.class.post("/v2/project/#{@api_key}/dial", {
338
- :body => body.to_json,
392
+ def stop_live_captions(captions_id)
393
+ response = self.class.post("/v2/project/#{@api_key}/captions/#{captions_id}/stop", {
339
394
  :headers => generate_headers("Content-Type" => "application/json")
340
395
  })
341
396
  case response.code
342
- when 200
397
+ when 202
343
398
  response
344
399
  when 403
345
- raise OpenTokAuthenticationError, "Authentication failed while dialing a SIP session. API Key: #{@api_key}"
400
+ raise OpenTokAuthenticationError, "Authentication failed while starting captions. API Key: #{@api_key}"
346
401
  when 404
347
- raise OpenTokSipError, "The SIP session could not be dialed. The Session ID does not exist: #{session_id}"
402
+ raise OpenTokCaptionsError, "No matching captions_id was found: #{captions_id}"
403
+ when 500
404
+ raise OpenTokError, "OpenTok server error."
348
405
  else
349
- raise OpenTokSipError, "The SIP session could not be dialed"
406
+ raise OpenTokCaptionsError, "Captions could not be stopped"
350
407
  end
351
408
  rescue StandardError => e
352
409
  raise OpenTokError, "Failed to connect to OpenTok. Response code: #{e.message}"
353
410
  end
354
411
 
355
- def play_dtmf_to_connection(session_id, connection_id, dtmf_digits)
356
- body = { "digits" => dtmf_digits }
412
+ # Connections methods
357
413
 
358
- response = self.class.post("/v2/project/#{@api_key}/session/#{session_id}/connection/#{connection_id}/play-dtmf", {
359
- :body => body.to_json,
360
- :headers => generate_headers("Content-Type" => "application/json")
414
+ def forceDisconnect(session_id, connection_id)
415
+ response = self.class.delete("/v2/project/#{@api_key}/session/#{session_id}/connection/#{connection_id}", {
416
+ :headers => generate_headers("Content-Type" => "application/json")
361
417
  })
362
418
  case response.code
363
- when 200
419
+ when 204
364
420
  response
365
421
  when 400
366
- raise ArgumentError, "One of the properties dtmf_digits #{dtmf_digits} or session_id #{session_id} is invalid."
422
+ raise ArgumentError, "Force disconnect failed. Connection ID #{connection_id} or Session ID #{session_id} is invalid"
367
423
  when 403
368
- raise OpenTokAuthenticationError, "Authentication failed. This can occur if you use an invalid OpenTok API key or an invalid JSON web token. API Key: #{@api_key}"
424
+ raise OpenTokAuthenticationError, "You are not authorized to forceDisconnect, check your authentication credentials or token type is non-moderator"
369
425
  when 404
370
- raise OpenTokError, "The specified session #{session_id} does not exist or the client specified by the #{connection_id} property is not connected to the session."
371
- else
372
- raise OpenTokError, "An error occurred when attempting to play DTMF digits to the session"
426
+ raise OpenTokConnectionError, "The client specified by the connection ID: #{connection_id} is not connected to the session"
373
427
  end
374
428
  rescue StandardError => e
375
429
  raise OpenTokError, "Failed to connect to OpenTok. Response code: #{e.message}"
376
430
  end
377
431
 
378
- def play_dtmf_to_session(session_id, dtmf_digits)
379
- body = { "digits" => dtmf_digits }
432
+ # Renders methods
380
433
 
381
- response = self.class.post("/v2/project/#{@api_key}/session/#{session_id}/play-dtmf", {
382
- :body => body.to_json,
383
- :headers => generate_headers("Content-Type" => "application/json")
434
+ def start_render(session_id, opts)
435
+ opts.extend(HashExtensions)
436
+ body = { :sessionId => session_id }.merge(opts.camelize_keys!)
437
+ response = self.class.post("/v2/project/#{@api_key}/render", {
438
+ :body => body.to_json,
439
+ :headers => generate_headers("Content-Type" => "application/json")
384
440
  })
385
441
  case response.code
386
- when 200
442
+ when 202
387
443
  response
388
444
  when 400
389
- raise ArgumentError, "One of the properties dtmf_digits #{dtmf_digits} or session_id #{session_id} — is invalid."
445
+ raise OpenTokRenderError, "The render could not be started. The request was invalid."
390
446
  when 403
391
- raise OpenTokAuthenticationError, "Authentication failed. This can occur if you use an invalid OpenTok API key or an invalid JSON web token. API Key: #{@api_key}"
392
- when 404
393
- raise OpenTokError, "The specified session does not exist. Session ID: #{session_id}"
447
+ raise OpenTokAuthenticationError, "Authentication failed while starting a render. API Key: #{@api_key}"
448
+ when 500
449
+ raise OpenTokError, "OpenTok server error."
394
450
  else
395
- raise OpenTokError, "An error occurred when attempting to play DTMF digits to the session"
451
+ raise OpenTokRenderError, "The render could not be started"
396
452
  end
397
453
  rescue StandardError => e
398
454
  raise OpenTokError, "Failed to connect to OpenTok. Response code: #{e.message}"
399
455
  end
400
456
 
401
- def info_stream(session_id, stream_id)
402
- streamId = stream_id.to_s.empty? ? '' : "/#{stream_id}"
403
- url = "/v2/project/#{@api_key}/session/#{session_id}/stream#{streamId}"
404
- response = self.class.get(url,
405
- headers: generate_headers('Content-Type' => 'application/json'))
457
+ def get_render(render_id)
458
+ response = self.class.get("/v2/project/#{@api_key}/render/#{render_id}", {
459
+ :headers => generate_headers
460
+ })
406
461
  case response.code
407
462
  when 200
408
463
  response
409
464
  when 400
410
- raise ArgumentError, 'Invalid request. You did not pass in a valid session ID or stream ID.'
465
+ raise OpenTokRenderError, "The request was invalid."
411
466
  when 403
412
- raise OpenTokAuthenticationError, 'Check your authentication credentials. You passed in an invalid OpenTok API key.'
413
- when 408
414
- raise ArgumentError, 'You passed in an invalid stream ID.'
467
+ raise OpenTokAuthenticationError, "Authentication failed while getting a render. API Key: #{@api_key}"
468
+ when 404
469
+ raise OpenTokRenderError, "No matching render found (with the specified ID)"
415
470
  when 500
416
- raise OpenTokError, 'OpenTok server error.'
471
+ raise OpenTokError, "OpenTok server error."
417
472
  else
418
- raise OpenTokError, 'Could not fetch the stream information.'
473
+ raise OpenTokRenderError, "Could not fetch render information."
419
474
  end
420
475
  rescue StandardError => e
421
476
  raise OpenTokError, "Failed to connect to OpenTok. Response code: #{e.message}"
422
477
  end
423
478
 
424
- def layout_streams(session_id, opts)
425
- opts.extend(HashExtensions)
426
- response = self.class.put("/v2/project/#{@api_key}/session/#{session_id}/stream", {
427
- :body => opts.camelize_keys!.to_json,
428
- :headers => generate_headers("Content-Type" => "application/json")
479
+ def stop_render(render_id)
480
+ response = self.class.delete("/v2/project/#{@api_key}/render/#{render_id}", {
481
+ :headers => generate_headers
429
482
  })
430
483
  case response.code
431
- when 200
484
+ when 204
432
485
  response
433
486
  when 400
434
- raise OpenTokStreamLayoutError, "Setting the layout failed. The request was invalid or invalid layout options were given."
487
+ raise OpenTokRenderError, "The request was invalid."
435
488
  when 403
436
- raise OpenTokAuthenticationError, "Authentication failed. API Key: #{@api_key}"
489
+ raise OpenTokAuthenticationError, "Authentication failed while stopping a render. API Key: #{@api_key}"
490
+ when 404
491
+ raise OpenTokRenderError, "No matching render found (with the specified ID) or it is already stopped"
437
492
  when 500
438
- raise OpenTokError, "Setting the layout failed. OpenTok server error."
493
+ raise OpenTokError, "OpenTok server error."
439
494
  else
440
- raise OpenTokStreamLayoutError, "Setting the layout failed."
495
+ raise OpenTokRenderError, "The render could not be stopped."
441
496
  end
442
497
  rescue StandardError => e
443
498
  raise OpenTokError, "Failed to connect to OpenTok. Response code: #{e.message}"
444
499
  end
445
500
 
446
- def start_broadcast(session_id, opts)
447
- opts.extend(HashExtensions)
448
- body = { :sessionId => session_id }.merge(opts.camelize_keys!)
449
- response = self.class.post("/v2/project/#{@api_key}/broadcast", {
450
- :body => body.to_json,
451
- :headers => generate_headers("Content-Type" => "application/json")
501
+ def list_renders(offset, count)
502
+ query = Hash.new
503
+ query[:offset] = offset unless offset.nil?
504
+ query[:count] = count unless count.nil?
505
+ response = self.class.get("/v2/project/#{@api_key}/render", {
506
+ :query => query.empty? ? nil : query,
507
+ :headers => generate_headers,
452
508
  })
453
509
  case response.code
454
510
  when 200
455
511
  response
456
- when 400
457
- 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."
458
512
  when 403
459
- raise OpenTokAuthenticationError, "Authentication failed while starting a broadcast. API Key: #{@api_key}"
460
- when 409
461
- raise OpenTokBroadcastError, "The broadcast has already been started for this session."
513
+ raise OpenTokAuthenticationError,
514
+ "Authentication failed while retrieving renders. API Key: #{@api_key}"
462
515
  when 500
463
516
  raise OpenTokError, "OpenTok server error."
464
517
  else
465
- raise OpenTokBroadcastError, "The broadcast could not be started"
518
+ raise OpenTokRenderError, "The renders could not be retrieved."
466
519
  end
467
520
  rescue StandardError => e
468
521
  raise OpenTokError, "Failed to connect to OpenTok. Response code: #{e.message}"
469
522
  end
470
523
 
471
- def get_broadcast(broadcast_id)
472
- response = self.class.get("/v2/project/#{@api_key}/broadcast/#{broadcast_id}", {
473
- :headers => generate_headers
524
+ # Sip methods
525
+
526
+ def dial(session_id, token, sip_uri, opts)
527
+ opts.extend(HashExtensions)
528
+ body = { "sessionId" => session_id,
529
+ "token" => token,
530
+ "sip" => { "uri" => sip_uri }.merge(opts.camelize_keys!)
531
+ }
532
+
533
+ response = self.class.post("/v2/project/#{@api_key}/dial", {
534
+ :body => body.to_json,
535
+ :headers => generate_headers("Content-Type" => "application/json")
474
536
  })
475
537
  case response.code
476
538
  when 200
477
539
  response
478
- when 400
479
- raise OpenTokBroadcastError, "The request was invalid."
480
540
  when 403
481
- raise OpenTokAuthenticationError, "Authentication failed while getting a broadcast. API Key: #{@api_key}"
541
+ raise OpenTokAuthenticationError, "Authentication failed while dialing a SIP session. API Key: #{@api_key}"
482
542
  when 404
483
- raise OpenTokBroadcastError, "No matching broadcast found (with the specified ID)"
484
- when 500
485
- raise OpenTokError, "OpenTok server error."
543
+ raise OpenTokSipError, "The SIP session could not be dialed. The Session ID does not exist: #{session_id}"
486
544
  else
487
- raise OpenTokBroadcastError, "Could not fetch broadcast information."
545
+ raise OpenTokSipError, "The SIP session could not be dialed"
488
546
  end
489
547
  rescue StandardError => e
490
548
  raise OpenTokError, "Failed to connect to OpenTok. Response code: #{e.message}"
491
549
  end
492
550
 
493
- def stop_broadcast(broadcast_id)
494
- response = self.class.post("/v2/project/#{@api_key}/broadcast/#{broadcast_id}/stop", {
495
- :headers => generate_headers
551
+ def play_dtmf_to_connection(session_id, connection_id, dtmf_digits)
552
+ body = { "digits" => dtmf_digits }
553
+
554
+ response = self.class.post("/v2/project/#{@api_key}/session/#{session_id}/connection/#{connection_id}/play-dtmf", {
555
+ :body => body.to_json,
556
+ :headers => generate_headers("Content-Type" => "application/json")
496
557
  })
497
558
  case response.code
498
559
  when 200
499
560
  response
500
561
  when 400
501
- raise OpenTokBroadcastError, "The request was invalid."
562
+ raise ArgumentError, "One of the properties — dtmf_digits #{dtmf_digits} or session_id #{session_id} — is invalid."
502
563
  when 403
503
- raise OpenTokAuthenticationError, "Authentication failed while stopping a broadcast. API Key: #{@api_key}"
564
+ raise OpenTokAuthenticationError, "Authentication failed. This can occur if you use an invalid OpenTok API key or an invalid JSON web token. API Key: #{@api_key}"
504
565
  when 404
505
- raise OpenTokBroadcastError, "No matching broadcast found (with the specified ID) or it is already stopped"
506
- when 500
507
- raise OpenTokError, "OpenTok server error."
566
+ raise OpenTokError, "The specified session #{session_id} does not exist or the client specified by the #{connection_id} property is not connected to the session."
508
567
  else
509
- raise OpenTokBroadcastError, "The broadcast could not be stopped."
568
+ raise OpenTokError, "An error occurred when attempting to play DTMF digits to the session"
510
569
  end
511
570
  rescue StandardError => e
512
571
  raise OpenTokError, "Failed to connect to OpenTok. Response code: #{e.message}"
513
572
  end
514
573
 
515
- def list_broadcasts(offset, count, session_id)
516
- query = Hash.new
517
- query[:offset] = offset unless offset.nil?
518
- query[:count] = count unless count.nil?
519
- query[:sessionId] = session_id unless session_id.nil?
520
- response = self.class.get("/v2/project/#{@api_key}/broadcast", {
521
- :query => query.empty? ? nil : query,
522
- :headers => generate_headers,
574
+ def play_dtmf_to_session(session_id, dtmf_digits)
575
+ body = { "digits" => dtmf_digits }
576
+
577
+ response = self.class.post("/v2/project/#{@api_key}/session/#{session_id}/play-dtmf", {
578
+ :body => body.to_json,
579
+ :headers => generate_headers("Content-Type" => "application/json")
523
580
  })
524
581
  case response.code
525
582
  when 200
526
583
  response
584
+ when 400
585
+ raise ArgumentError, "One of the properties — dtmf_digits #{dtmf_digits} or session_id #{session_id} — is invalid."
527
586
  when 403
528
- raise OpenTokAuthenticationError,
529
- "Authentication failed while retrieving broadcasts. API Key: #{@api_key}"
587
+ raise OpenTokAuthenticationError, "Authentication failed. This can occur if you use an invalid OpenTok API key or an invalid JSON web token. API Key: #{@api_key}"
588
+ when 404
589
+ raise OpenTokError, "The specified session does not exist. Session ID: #{session_id}"
530
590
  else
531
- raise OpenTokBroadcastError, "The broadcasts could not be retrieved."
591
+ raise OpenTokError, "An error occurred when attempting to play DTMF digits to the session"
532
592
  end
533
593
  rescue StandardError => e
534
594
  raise OpenTokError, "Failed to connect to OpenTok. Response code: #{e.message}"
535
595
  end
536
596
 
537
- def layout_broadcast(broadcast_id, opts)
538
- opts.extend(HashExtensions)
539
- response = self.class.put("/v2/project/#{@api_key}/broadcast/#{broadcast_id}/layout", {
540
- :body => opts.camelize_keys!.to_json,
541
- :headers => generate_headers("Content-Type" => "application/json")
542
- })
597
+ # Streams methods
598
+
599
+ def info_stream(session_id, stream_id)
600
+ streamId = stream_id.to_s.empty? ? '' : "/#{stream_id}"
601
+ url = "/v2/project/#{@api_key}/session/#{session_id}/stream#{streamId}"
602
+ response = self.class.get(url,
603
+ headers: generate_headers('Content-Type' => 'application/json'))
543
604
  case response.code
544
605
  when 200
545
606
  response
546
607
  when 400
547
- raise OpenTokBroadcastError, "The layout operation could not be performed. The request was invalid or invalid layout options."
608
+ raise ArgumentError, 'Invalid request. You did not pass in a valid session ID or stream ID.'
548
609
  when 403
549
- raise OpenTokAuthenticationError, "Authentication failed for broadcast layout. API Key: #{@api_key}"
610
+ raise OpenTokAuthenticationError, 'Check your authentication credentials. You passed in an invalid OpenTok API key.'
611
+ when 408
612
+ raise ArgumentError, 'You passed in an invalid stream ID.'
550
613
  when 500
551
- raise OpenTokError, "OpenTok server error."
614
+ raise OpenTokError, 'OpenTok server error.'
552
615
  else
553
- raise OpenTokBroadcastError, "The broadcast layout could not be performed."
616
+ raise OpenTokError, 'Could not fetch the stream information.'
554
617
  end
555
618
  rescue StandardError => e
556
619
  raise OpenTokError, "Failed to connect to OpenTok. Response code: #{e.message}"
557
620
  end
558
621
 
559
- def select_streams_for_broadcast(broadcast_id, opts)
622
+ def layout_streams(session_id, opts)
560
623
  opts.extend(HashExtensions)
561
- body = opts.camelize_keys!
562
- response = self.class.patch("/v2/project/#{@api_key}/broadcast/#{broadcast_id}/streams", {
563
- :body => body.to_json,
624
+ response = self.class.put("/v2/project/#{@api_key}/session/#{session_id}/stream", {
625
+ :body => opts.camelize_keys!.to_json,
564
626
  :headers => generate_headers("Content-Type" => "application/json")
565
627
  })
566
628
  case response.code
567
- when 204
629
+ when 200
568
630
  response
569
631
  when 400
570
- raise OpenTokBroadcastError, "The request was invalid."
632
+ raise OpenTokStreamLayoutError, "Setting the layout failed. The request was invalid or invalid layout options were given."
571
633
  when 403
572
634
  raise OpenTokAuthenticationError, "Authentication failed. API Key: #{@api_key}"
573
- when 404
574
- raise OpenTokBroadcastError, "No matching broadcast found with the specified ID: #{broadcast_id}"
575
- when 405
576
- raise OpenTokBroadcastError, "The broadcast was started with streamMode set to 'auto', which does not support stream manipulation."
577
635
  when 500
578
- raise OpenTokError, "OpenTok server error."
636
+ raise OpenTokError, "Setting the layout failed. OpenTok server error."
579
637
  else
580
- raise OpenTokBroadcastError, "The broadcast streams could not be updated."
638
+ raise OpenTokStreamLayoutError, "Setting the layout failed."
581
639
  end
582
640
  rescue StandardError => e
583
641
  raise OpenTokError, "Failed to connect to OpenTok. Response code: #{e.message}"
584
642
  end
585
643
 
586
- def start_render(session_id, opts)
587
- opts.extend(HashExtensions)
588
- body = { :sessionId => session_id }.merge(opts.camelize_keys!)
589
- response = self.class.post("/v2/project/#{@api_key}/render", {
590
- :body => body.to_json,
644
+ def force_mute_stream(session_id, stream_id)
645
+ response = self.class.post("/v2/project/#{@api_key}/session/#{session_id}/stream/#{stream_id}/mute", {
591
646
  :headers => generate_headers("Content-Type" => "application/json")
592
647
  })
593
648
  case response.code
594
- when 202
649
+ when 200
595
650
  response
596
651
  when 400
597
- raise OpenTokRenderError, "The render could not be started. The request was invalid."
652
+ raise ArgumentError, "Force mute failed. Stream ID #{stream_id} or Session ID #{session_id} is invalid"
598
653
  when 403
599
- raise OpenTokAuthenticationError, "Authentication failed while starting a render. API Key: #{@api_key}"
600
- when 500
601
- raise OpenTokError, "OpenTok server error."
602
- else
603
- raise OpenTokRenderError, "The render could not be started"
654
+ raise OpenTokAuthenticationError, "Authentication failed. API Key: #{@api_key}"
655
+ when 404
656
+ raise OpenTokConnectionError, "Either Stream ID #{stream_id} or Session ID #{session_id} is invalid"
604
657
  end
605
658
  rescue StandardError => e
606
659
  raise OpenTokError, "Failed to connect to OpenTok. Response code: #{e.message}"
607
660
  end
608
661
 
609
- def get_render(render_id)
610
- response = self.class.get("/v2/project/#{@api_key}/render/#{render_id}", {
611
- :headers => generate_headers
662
+ def force_mute_session(session_id, opts)
663
+ opts.extend(HashExtensions)
664
+ body = opts.camelize_keys!
665
+ response = self.class.post("/v2/project/#{@api_key}/session/#{session_id}/mute", {
666
+ :body => body.to_json,
667
+ :headers => generate_headers("Content-Type" => "application/json")
612
668
  })
613
669
  case response.code
614
670
  when 200
615
671
  response
616
672
  when 400
617
- raise OpenTokRenderError, "The request was invalid."
673
+ raise ArgumentError, "Force mute failed. The request could not be processed due to a bad request"
618
674
  when 403
619
- raise OpenTokAuthenticationError, "Authentication failed while getting a render. API Key: #{@api_key}"
675
+ raise OpenTokAuthenticationError, "Authentication failed. API Key: #{@api_key}"
620
676
  when 404
621
- raise OpenTokRenderError, "No matching render found (with the specified ID)"
622
- when 500
623
- raise OpenTokError, "OpenTok server error."
624
- else
625
- raise OpenTokRenderError, "Could not fetch render information."
677
+ raise OpenTokConnectionError, "Session ID #{session_id} is invalid"
626
678
  end
627
679
  rescue StandardError => e
628
680
  raise OpenTokError, "Failed to connect to OpenTok. Response code: #{e.message}"
629
681
  end
630
682
 
631
- def stop_render(render_id)
632
- response = self.class.delete("/v2/project/#{@api_key}/render/#{render_id}", {
633
- :headers => generate_headers
683
+ # Signals methods
684
+
685
+ def signal(session_id, connection_id, opts)
686
+ opts.extend(HashExtensions)
687
+ connectionPath = connection_id.to_s.empty? ? "" : "/connection/#{connection_id}"
688
+ url = "/v2/project/#{@api_key}/session/#{session_id}#{connectionPath}/signal"
689
+ response = self.class.post(url, {
690
+ :body => opts.camelize_keys!.to_json,
691
+ :headers => generate_headers("Content-Type" => "application/json")
634
692
  })
635
693
  case response.code
636
694
  when 204
637
695
  response
638
696
  when 400
639
- raise OpenTokRenderError, "The request was invalid."
697
+ raise ArgumentError, "One of the signal properties — data, type, sessionId or connectionId — is invalid."
640
698
  when 403
641
- raise OpenTokAuthenticationError, "Authentication failed while stopping a render. API Key: #{@api_key}"
699
+ raise OpenTokAuthenticationError, "You are not authorized to send the signal. Check your authentication credentials."
642
700
  when 404
643
- raise OpenTokRenderError, "No matching render found (with the specified ID) or it is already stopped"
644
- when 500
645
- raise OpenTokError, "OpenTok server error."
701
+ raise OpenTokError, "The client specified by the connectionId property is not connected to the session."
702
+ when 413
703
+ raise OpenTokError, "The type string exceeds the maximum length (128 bytes), or the data string exceeds the maximum size (8 kB)."
646
704
  else
647
- raise OpenTokRenderError, "The render could not be stopped."
705
+ raise OpenTokError, "The signal could not be send."
648
706
  end
649
707
  rescue StandardError => e
650
708
  raise OpenTokError, "Failed to connect to OpenTok. Response code: #{e.message}"
651
709
  end
652
710
 
653
- def list_renders(offset, count)
654
- query = Hash.new
655
- query[:offset] = offset unless offset.nil?
656
- query[:count] = count unless count.nil?
657
- response = self.class.get("/v2/project/#{@api_key}/render", {
658
- :query => query.empty? ? nil : query,
659
- :headers => generate_headers,
711
+ # WebSocket methods
712
+
713
+ def connect_websocket(session_id, token, websocket_uri, opts)
714
+ opts.extend(HashExtensions)
715
+ body = { "sessionId" => session_id,
716
+ "token" => token,
717
+ "websocket" => { "uri" => websocket_uri }.merge(opts.camelize_keys!)
718
+ }
719
+
720
+ response = self.class.post("/v2/project/#{@api_key}/connect", {
721
+ :body => body.to_json,
722
+ :headers => generate_headers("Content-Type" => "application/json")
660
723
  })
661
724
  case response.code
662
725
  when 200
663
726
  response
727
+ when 400
728
+ raise ArgumentError, "One of the properties is invalid."
664
729
  when 403
665
- raise OpenTokAuthenticationError,
666
- "Authentication failed while retrieving renders. API Key: #{@api_key}"
730
+ raise OpenTokAuthenticationError, "You are not authorized to start the call, check your authentication information."
731
+ when 409
732
+ raise OpenTokWebSocketError, "Conflict. Only routed sessions are allowed to initiate Connect Calls."
667
733
  when 500
668
734
  raise OpenTokError, "OpenTok server error."
669
735
  else
670
- raise OpenTokRenderError, "The renders could not be retrieved."
736
+ raise OpenTokWebSocketError, "The WebSocket could not be connected"
671
737
  end
672
738
  rescue StandardError => e
673
739
  raise OpenTokError, "Failed to connect to OpenTok. Response code: #{e.message}"
674
740
  end
675
-
676
741
  end
677
742
  end
@@ -18,4 +18,6 @@ module OpenTok
18
18
  class OpenTokWebSocketError < OpenTokError; end
19
19
  # Defines errors raised when you perform Experience Composer render operations.
20
20
  class OpenTokRenderError < OpenTokError; end
21
+ # Defines errors raised when you perform Captions operations.
22
+ class OpenTokCaptionsError < OpenTokError; end
21
23
  end
@@ -12,6 +12,7 @@ require "opentok/streams"
12
12
  require "opentok/signals"
13
13
  require "opentok/broadcasts"
14
14
  require "opentok/renders"
15
+ require "opentok/captions"
15
16
 
16
17
  module OpenTok
17
18
  # Contains methods for creating OpenTok sessions and generating tokens. It also includes
@@ -214,6 +215,16 @@ module OpenTok
214
215
  @broadcasts ||= Broadcasts.new client
215
216
  end
216
217
 
218
+ # A Captions object, which lets you start and stop live captions for an OpenTok session.
219
+ def captions
220
+ @captions ||= Captions.new client
221
+ end
222
+
223
+ # A Connections object, which lets you disconnect clients from an OpenTok session.
224
+ def connections
225
+ @connections ||= Connections.new client
226
+ end
227
+
217
228
  # A Renders object, which lets you work with OpenTok Experience Composer renders.
218
229
  def renders
219
230
  @renders ||= Renders.new client
@@ -234,11 +245,6 @@ module OpenTok
234
245
  @signals ||= Signals.new client
235
246
  end
236
247
 
237
- # A Connections object, which lets you disconnect clients from an OpenTok session.
238
- def connections
239
- @connections ||= Connections.new client
240
- end
241
-
242
248
  # A WebSocket object, which lets you connect OpenTok streams to a WebSocket URI.
243
249
  def websocket
244
250
  @websocket ||= WebSocket.new client
data/lib/opentok/sip.rb CHANGED
@@ -38,13 +38,15 @@ module OpenTok
38
38
  # @option opts [true, false] :secure Whether the media must be transmitted
39
39
  # encrypted (​true​) or not (​false​, the default).
40
40
  # @option opts [true, false] :video Whether the SIP call will include
41
- # video (​true​) or not (​false​, the default). With video included, the SIP
42
- # client's video is included in the OpenTok stream that is sent to the
43
- # OpenTok session. The SIP client will receive a single composed video of
44
- # the published streams in the OpenTok session.
41
+ # video (​true​) or not (​false​, the default). With video included, the SIP
42
+ # client's video is included in the OpenTok stream that is sent to the
43
+ # OpenTok session. The SIP client will receive a single composed video of
44
+ # the published streams in the OpenTok session.
45
45
  # @option opts [true, false] :observe_force_mute Whether the SIP end point
46
- # observes {https://tokbox.com/developer/guides/moderation/#force_mute force mute moderation}
47
- # (true) or not (false, the default).
46
+ # observes {https://tokbox.com/developer/guides/moderation/#force_mute force mute moderation}
47
+ # (true) or not (false, the default).
48
+ # @option opts [Array] :streams An array of stream IDs for streams to include in the SIP call.
49
+ # If you do not set this property, all streams in the session are included in the call.
48
50
  def dial(session_id, token, sip_uri, opts)
49
51
  response = @client.dial(session_id, token, sip_uri, opts)
50
52
  end
@@ -1,4 +1,4 @@
1
1
  module OpenTok
2
2
  # @private
3
- VERSION = '4.7.0'
3
+ VERSION = '4.8.0'
4
4
  end
@@ -0,0 +1,44 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://api.opentok.com/v2/project/123456/captions
6
+ body:
7
+ encoding: UTF-8
8
+ string: '{"sessionId":"SESSIONID","token":"TOKENID"}'
9
+ headers:
10
+ User-Agent:
11
+ - OpenTok-Ruby-SDK/<%= version %>
12
+ X-Opentok-Auth:
13
+ - eyJpc3QiOiJwcm9qZWN0IiwiYWxnIjoiSFMyNTYifQ.eyJpc3MiOiIxMjM0NTYiLCJpYXQiOjE0OTI1MTA2NjAsImV4cCI6MTQ5MjUxMDk2MH0.BplMVhJWx4ld7KLKXqEmow6MjNPPFw9W8IHCMfeb120
14
+ Content-Type:
15
+ - application/json
16
+ Accept-Encoding:
17
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
18
+ Accept:
19
+ - "*/*"
20
+ response:
21
+ status:
22
+ code: 202
23
+ message: Accepted
24
+ headers:
25
+ Date:
26
+ - Tue, 05 Sep 2023 11:32:49 GMT
27
+ Content-Type:
28
+ - application/json; charset=utf-8
29
+ Transfer-Encoding:
30
+ - chunked
31
+ Connection:
32
+ - keep-alive
33
+ Set-Cookie:
34
+ - AWSALBTG=V0iIksb77idvUqENJbP7kHbxorCidH5rXzTdrmAq244qBgmkoAZJ+QZE0gPn/fKjmIEtO29S43zhxzH3X5Ao8Nf/8KMvioOduANad0cg6/rMMbSKhWdxNJkcePyrYLO/6voP37Lk8LamlXqv3QK6lj9SCvA+/wyUB6CV+i1JY8XSc1ba/+s=;
35
+ Expires=Tue, 12 Sep 2023 11:32:49 GMT; Path=/
36
+ - AWSALBTGCORS=V0iIksb77idvUqENJbP7kHbxorCidH5rXzTdrmAq244qBgmkoAZJ+QZE0gPn/fKjmIEtO29S43zhxzH3X5Ao8Nf/8KMvioOduANad0cg6/rMMbSKhWdxNJkcePyrYLO/6voP37Lk8LamlXqv3QK6lj9SCvA+/wyUB6CV+i1JY8XSc1ba/+s=;
37
+ Expires=Tue, 12 Sep 2023 11:32:49 GMT; Path=/; SameSite=None; Secure
38
+ X-Opentok-Trace:
39
+ - f=unknown&s=cerberus&u=B8FAC1E2-3DCE-40A9-9CC3-866750E7C7A5
40
+ body:
41
+ encoding: UTF-8
42
+ string: '{ "captionsId": "7c0680fc-6274-4de5-a66f-d0648e8d3ac2" }'
43
+ recorded_at: Tue, 18 Apr 2017 10:17:40 GMT
44
+ recorded_with: VCR 6.0.0
@@ -0,0 +1,44 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://api.opentok.com/v2/project/123456/captions
6
+ body:
7
+ encoding: UTF-8
8
+ string: '{"sessionId":"SESSIONID","token":"TOKENID","languageCode":"en-GB","maxDuration":5000,"partialCaptions":false,"statusCallbackUrl":"https://example.com/captions/status"}'
9
+ headers:
10
+ User-Agent:
11
+ - OpenTok-Ruby-SDK/<%= version %>
12
+ X-Opentok-Auth:
13
+ - eyJpc3QiOiJwcm9qZWN0IiwiYWxnIjoiSFMyNTYifQ.eyJpc3MiOiIxMjM0NTYiLCJpYXQiOjE0OTI1MTA2NjAsImV4cCI6MTQ5MjUxMDk2MH0.BplMVhJWx4ld7KLKXqEmow6MjNPPFw9W8IHCMfeb120
14
+ Content-Type:
15
+ - application/json
16
+ Accept-Encoding:
17
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
18
+ Accept:
19
+ - "*/*"
20
+ response:
21
+ status:
22
+ code: 202
23
+ message: Accepted
24
+ headers:
25
+ Date:
26
+ - Tue, 05 Sep 2023 12:05:23 GMT
27
+ Content-Type:
28
+ - application/json; charset=utf-8
29
+ Transfer-Encoding:
30
+ - chunked
31
+ Connection:
32
+ - keep-alive
33
+ Set-Cookie:
34
+ - AWSALBTG=Qam0XgGzqhEaBC7TB9UprWCTZ6omkQZDorQLpkU8Kb3+iSIJsINH6Rh13nWnaLryAUc08wZEEc0VAi6ZXVa5gVLE/5YeIvMT9WP8VzJLFyvQ/bMe7TIDvp/QronHO4tohNGpvrFQxCC5LElWX5JnN3sCr5WpUHqEPQr0jz9TtUmKJYIh0So=;
35
+ Expires=Tue, 12 Sep 2023 12:05:23 GMT; Path=/
36
+ - AWSALBTGCORS=Qam0XgGzqhEaBC7TB9UprWCTZ6omkQZDorQLpkU8Kb3+iSIJsINH6Rh13nWnaLryAUc08wZEEc0VAi6ZXVa5gVLE/5YeIvMT9WP8VzJLFyvQ/bMe7TIDvp/QronHO4tohNGpvrFQxCC5LElWX5JnN3sCr5WpUHqEPQr0jz9TtUmKJYIh0So=;
37
+ Expires=Tue, 12 Sep 2023 12:05:23 GMT; Path=/; SameSite=None; Secure
38
+ X-Opentok-Trace:
39
+ - f=unknown&s=cerberus&u=5DB017B0-6FC7-444F-BDE9-20D3CBA7B2EA
40
+ body:
41
+ encoding: UTF-8
42
+ string: '{ "captionsId": "7c0680fc-6274-4de5-a66f-d0648e8d3ac2" }'
43
+ recorded_at: Tue, 18 Apr 2017 10:17:40 GMT
44
+ recorded_with: VCR 6.0.0
@@ -0,0 +1,44 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://api.opentok.com/v2/project/123456/captions/CAPTIONSID/stop
6
+ body:
7
+ encoding: UTF-8
8
+ string: ''
9
+ headers:
10
+ User-Agent:
11
+ - OpenTok-Ruby-SDK/<%= version %>
12
+ X-Opentok-Auth:
13
+ - eyJpc3QiOiJwcm9qZWN0IiwiYWxnIjoiSFMyNTYifQ.eyJpc3MiOiIxMjM0NTYiLCJpYXQiOjE0OTI1MTA2NjAsImV4cCI6MTQ5MjUxMDk2MH0.BplMVhJWx4ld7KLKXqEmow6MjNPPFw9W8IHCMfeb120
14
+ Content-Type:
15
+ - application/json
16
+ Accept-Encoding:
17
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
18
+ Accept:
19
+ - "*/*"
20
+ response:
21
+ status:
22
+ code: 202
23
+ message: Accepted
24
+ headers:
25
+ Date:
26
+ - Tue, 05 Sep 2023 11:30:55 GMT
27
+ Content-Type:
28
+ - application/json; charset=utf-8
29
+ Transfer-Encoding:
30
+ - chunked
31
+ Connection:
32
+ - keep-alive
33
+ Set-Cookie:
34
+ - AWSALBTG=LJIybl0y9LXphBJqNdoYf94M2EQTLnT/IhYp4UD+lzvSSZfKfdshtXSXDJ+gplgMuZ+3zg7mtnQoUF7ZhM2IRiL6VYJq88ltUPP075OdNgDwWRpYLq+doFLXeee4skbljcUpgTAWkCp1MReHhYdiTO8G36cgW9hPyWE9/jIMcfhN6HzVv5Q=;
35
+ Expires=Tue, 12 Sep 2023 11:30:55 GMT; Path=/
36
+ - AWSALBTGCORS=LJIybl0y9LXphBJqNdoYf94M2EQTLnT/IhYp4UD+lzvSSZfKfdshtXSXDJ+gplgMuZ+3zg7mtnQoUF7ZhM2IRiL6VYJq88ltUPP075OdNgDwWRpYLq+doFLXeee4skbljcUpgTAWkCp1MReHhYdiTO8G36cgW9hPyWE9/jIMcfhN6HzVv5Q=;
37
+ Expires=Tue, 12 Sep 2023 11:30:55 GMT; Path=/; SameSite=None; Secure
38
+ X-Opentok-Trace:
39
+ - f=unknown&s=cerberus&u=22ECEF08-1EBD-4554-BF7B-04857DE8616A
40
+ body:
41
+ encoding: UTF-8
42
+ string: ''
43
+ recorded_at: Tue, 18 Apr 2017 10:17:40 GMT
44
+ recorded_with: VCR 6.0.0
@@ -0,0 +1,44 @@
1
+ require "opentok/opentok"
2
+ require "opentok/captions"
3
+ require "opentok/version"
4
+ require "spec_helper"
5
+
6
+ describe OpenTok::Captions do
7
+ before(:each) do
8
+ now = Time.parse("2017-04-18 20:17:40 +1000")
9
+ allow(Time).to receive(:now) { now }
10
+ end
11
+
12
+ let(:api_key) { "123456" }
13
+ let(:api_secret) { "1234567890abcdef1234567890abcdef1234567890" }
14
+ let(:session_id) { "SESSIONID" }
15
+ let(:captions_id) { "CAPTIONSID" }
16
+ let(:expiring_token) { "TOKENID" }
17
+ let(:status_callback_url) { "https://example.com/captions/status" }
18
+ let(:opentok) { OpenTok::OpenTok.new api_key, api_secret }
19
+ let(:captions) { opentok.captions }
20
+ subject { captions }
21
+
22
+ it "receives a valid response when starting captions", :vcr => { :erb => { :version => OpenTok::VERSION + "-Ruby-Version-#{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}"} } do
23
+ response = captions.start(session_id, expiring_token)
24
+ expect(response).not_to be_nil
25
+ expect(response.code).to eq(202)
26
+ end
27
+
28
+ it "receives a valid response when starting captions with options", :vcr => { :erb => { :version => OpenTok::VERSION + "-Ruby-Version-#{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}"} } do
29
+ opts = { "language_code" => "en-GB",
30
+ "max_duration" => 5000,
31
+ "partial_captions" => false,
32
+ "status_callback_url" => status_callback_url
33
+ }
34
+
35
+ response = captions.start(session_id, expiring_token, opts)
36
+ expect(response).not_to be_nil
37
+ expect(response.code).to eq(202)
38
+ end
39
+
40
+ it "receives a valid response when stopping captions", :vcr => { :erb => { :version => OpenTok::VERSION + "-Ruby-Version-#{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}"} } do
41
+ response = captions.stop(captions_id)
42
+ expect(response.code).to eq(202)
43
+ end
44
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opentok
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.7.0
4
+ version: 4.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stijn Mathysen
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2023-06-20 00:00:00.000000000 Z
15
+ date: 2023-09-06 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: bundler
@@ -189,6 +189,7 @@ files:
189
189
  - lib/opentok/broadcast.rb
190
190
  - lib/opentok/broadcast_list.rb
191
191
  - lib/opentok/broadcasts.rb
192
+ - lib/opentok/captions.rb
192
193
  - lib/opentok/client.rb
193
194
  - lib/opentok/connections.rb
194
195
  - lib/opentok/constants.rb
@@ -280,6 +281,9 @@ files:
280
281
  - spec/cassettes/OpenTok_Broadcasts/starts_a_broadcast_with_a_specified_multiBroadcastTag.yml
281
282
  - spec/cassettes/OpenTok_Broadcasts/starts_a_rtmp_broadcast.yml
282
283
  - spec/cassettes/OpenTok_Broadcasts/stops_a_broadcast.yml
284
+ - spec/cassettes/OpenTok_Captions/receives_a_valid_response_when_starting_captions.yml
285
+ - spec/cassettes/OpenTok_Captions/receives_a_valid_response_when_starting_captions_with_options.yml
286
+ - spec/cassettes/OpenTok_Captions/receives_a_valid_response_when_stopping_captions.yml
283
287
  - spec/cassettes/OpenTok_Connections/forces_a_connection_to_be_terminated.yml
284
288
  - spec/cassettes/OpenTok_OpenTok/when_initialized_properly/_create_session/creates_always_archived_sessions.yml
285
289
  - spec/cassettes/OpenTok_OpenTok/when_initialized_properly/_create_session/creates_always_archived_sessions_with_a_set_archive_name.yml
@@ -317,6 +321,7 @@ files:
317
321
  - spec/matchers/token.rb
318
322
  - spec/opentok/archives_spec.rb
319
323
  - spec/opentok/broadcasts_spec.rb
324
+ - spec/opentok/captions_spec.rb
320
325
  - spec/opentok/client_spec.rb
321
326
  - spec/opentok/connection_spec.rb
322
327
  - spec/opentok/opentok_spec.rb
@@ -396,6 +401,9 @@ test_files:
396
401
  - spec/cassettes/OpenTok_Broadcasts/starts_a_broadcast_with_a_specified_multiBroadcastTag.yml
397
402
  - spec/cassettes/OpenTok_Broadcasts/starts_a_rtmp_broadcast.yml
398
403
  - spec/cassettes/OpenTok_Broadcasts/stops_a_broadcast.yml
404
+ - spec/cassettes/OpenTok_Captions/receives_a_valid_response_when_starting_captions.yml
405
+ - spec/cassettes/OpenTok_Captions/receives_a_valid_response_when_starting_captions_with_options.yml
406
+ - spec/cassettes/OpenTok_Captions/receives_a_valid_response_when_stopping_captions.yml
399
407
  - spec/cassettes/OpenTok_Connections/forces_a_connection_to_be_terminated.yml
400
408
  - spec/cassettes/OpenTok_OpenTok/when_initialized_properly/_create_session/creates_always_archived_sessions.yml
401
409
  - spec/cassettes/OpenTok_OpenTok/when_initialized_properly/_create_session/creates_always_archived_sessions_with_a_set_archive_name.yml
@@ -433,6 +441,7 @@ test_files:
433
441
  - spec/matchers/token.rb
434
442
  - spec/opentok/archives_spec.rb
435
443
  - spec/opentok/broadcasts_spec.rb
444
+ - spec/opentok/captions_spec.rb
436
445
  - spec/opentok/client_spec.rb
437
446
  - spec/opentok/connection_spec.rb
438
447
  - spec/opentok/opentok_spec.rb