opentok 0.1.3 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +16 -2
- data/.travis.yml +6 -0
- data/.yardopts +1 -0
- data/CONTRIBUTING.md +47 -0
- data/DEVELOPING.md +91 -0
- data/LICENSE +19 -5
- data/README.md +170 -53
- data/Rakefile +10 -5
- data/doc/OpenTok.html +411 -0
- data/doc/OpenTok/Archive.html +1320 -0
- data/doc/OpenTok/ArchiveList.html +216 -0
- data/doc/OpenTok/Archives.html +1028 -0
- data/doc/OpenTok/Client.html +695 -0
- data/doc/OpenTok/OpenTok.html +1046 -0
- data/doc/OpenTok/OpenTokArchiveError.html +142 -0
- data/doc/OpenTok/OpenTokAuthenticationError.html +143 -0
- data/doc/OpenTok/OpenTokError.html +138 -0
- data/doc/OpenTok/Session.html +665 -0
- data/doc/OpenTok/TokenGenerator.html +204 -0
- data/doc/OpenTok/TokenGenerator/ClassMethods.html +187 -0
- data/doc/README.md +15 -0
- data/doc/_index.html +182 -0
- data/doc/class_list.html +54 -0
- data/doc/css/common.css +1 -0
- data/doc/css/full_list.css +57 -0
- data/doc/css/style.css +339 -0
- data/doc/file.README.html +87 -0
- data/doc/file_list.html +56 -0
- data/doc/frames.html +26 -0
- data/doc/index.html +87 -0
- data/doc/js/app.js +219 -0
- data/doc/js/full_list.js +178 -0
- data/doc/js/jquery.js +4 -0
- data/doc/method_list.html +227 -0
- data/doc/top-level-namespace.html +112 -0
- data/lib/opentok.rb +3 -14
- data/lib/opentok/archive.rb +92 -0
- data/lib/opentok/archive_list.rb +17 -0
- data/lib/opentok/archives.rb +120 -0
- data/lib/opentok/client.rb +125 -0
- data/lib/opentok/constants.rb +5 -0
- data/lib/opentok/exceptions.rb +10 -0
- data/lib/opentok/opentok.rb +174 -0
- data/lib/opentok/session.rb +76 -0
- data/lib/opentok/token_generator.rb +101 -0
- data/lib/opentok/version.rb +4 -0
- data/opentok.gemspec +29 -22
- data/sample/Archiving/Gemfile +4 -0
- data/sample/Archiving/README.md +212 -0
- data/sample/Archiving/archiving_sample.rb +80 -0
- data/sample/Archiving/public/css/sample.css +22 -0
- data/sample/Archiving/public/img/archiving-off.png +0 -0
- data/sample/Archiving/public/img/archiving-on-idle.png +0 -0
- data/sample/Archiving/public/img/archiving-on-message.png +0 -0
- data/sample/Archiving/public/js/host.js +37 -0
- data/sample/Archiving/public/js/participant.js +13 -0
- data/sample/Archiving/views/history.erb +65 -0
- data/sample/Archiving/views/host.erb +69 -0
- data/sample/Archiving/views/index.erb +48 -0
- data/sample/Archiving/views/layout.erb +29 -0
- data/sample/Archiving/views/participant.erb +55 -0
- data/sample/HelloWorld/Gemfile +4 -0
- data/sample/HelloWorld/README.md +123 -0
- data/sample/HelloWorld/hello_world.rb +27 -0
- data/sample/HelloWorld/public/js/helloworld.js +32 -0
- data/sample/HelloWorld/views/index.erb +21 -0
- data/spec/cassettes/OpenTok_Archives/should_create_archives.yml +48 -0
- data/spec/cassettes/OpenTok_Archives/should_create_named_archives.yml +49 -0
- data/spec/cassettes/OpenTok_Archives/should_delete_an_archive_by_id.yml +32 -0
- data/spec/cassettes/OpenTok_Archives/should_find_archives_by_id.yml +46 -0
- data/spec/cassettes/OpenTok_Archives/should_stop_archives.yml +48 -0
- data/spec/cassettes/OpenTok_Archives/when_many_archives_are_created/should_return_all_archives.yml +104 -0
- data/spec/cassettes/OpenTok_Archives/when_many_archives_are_created/should_return_archives_with_an_offset.yml +71 -0
- data/spec/cassettes/OpenTok_Archives/when_many_archives_are_created/should_return_count_number_of_archives.yml +60 -0
- data/spec/cassettes/OpenTok_Archives/when_many_archives_are_created/should_return_part_of_the_archives_when_using_offset_and_count.yml +82 -0
- data/spec/cassettes/OpenTok_OpenTok/when_initialized_properly/_create_session/creates_default_sessions.yml +39 -0
- data/spec/cassettes/OpenTok_OpenTok/when_initialized_properly/_create_session/creates_relayed_media_sessions.yml +39 -0
- data/spec/cassettes/OpenTok_OpenTok/when_initialized_properly/_create_session/creates_relayed_media_sessions_with_a_location_hint.yml +39 -0
- data/spec/cassettes/OpenTok_OpenTok/when_initialized_properly/_create_session/creates_routed_media_sessions.yml +39 -0
- data/spec/cassettes/OpenTok_OpenTok/when_initialized_properly/_create_session/creates_routed_media_sessions_for_invalid_media_modes.yml +39 -0
- data/spec/cassettes/OpenTok_OpenTok/when_initialized_properly/_create_session/creates_routed_media_sessions_with_a_location_hint.yml +39 -0
- data/spec/cassettes/OpenTok_OpenTok/when_initialized_properly/_create_session/creates_sessions_with_a_location_hint.yml +39 -0
- data/spec/matchers/token.rb +48 -0
- data/spec/opentok/archives_spec.rb +91 -0
- data/spec/opentok/opentok_spec.rb +144 -0
- data/spec/opentok/session_spec.rb +71 -0
- data/spec/shared/opentok_generates_tokens.rb +62 -0
- data/spec/shared/session_generates_tokens.rb +63 -0
- data/spec/spec_helper.rb +6 -7
- metadata +197 -59
- data/.rspec +0 -3
- data/CHANGES +0 -33
- data/doc/reference.md +0 -122
- data/lib/open_tok/archive.rb +0 -53
- data/lib/open_tok/archive_timeline_event.rb +0 -22
- data/lib/open_tok/archive_video_resource.rb +0 -28
- data/lib/open_tok/exception.rb +0 -50
- data/lib/open_tok/open_tok_sdk.rb +0 -198
- data/lib/open_tok/request.rb +0 -63
- data/lib/open_tok/role_constants.rb +0 -18
- data/lib/open_tok/session.rb +0 -25
- data/lib/open_tok/session_property_constants.rb +0 -30
- data/lib/open_tok/utils.rb +0 -10
- data/lib/open_tok/version.rb +0 -5
- data/sample/sample.rb +0 -26
- data/spec/cassettes/archives.yml +0 -83
- data/spec/cassettes/deleteArchive.yml +0 -91
- data/spec/cassettes/invalidSession.yml +0 -41
- data/spec/cassettes/session.yml +0 -46
- data/spec/cassettes/stitchArchive.yml +0 -42
- data/spec/opentok_exception_spec.rb +0 -38
- data/spec/opentok_spec.rb +0 -135
data/lib/opentok.rb
CHANGED
@@ -1,18 +1,7 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
http://www.tokbox.com/
|
4
|
-
|
5
|
-
Copyright 2010 - 2012, TokBox, Inc.
|
6
|
-
|
7
|
-
Last modified: 2012-08-28
|
8
|
-
=end
|
9
|
-
|
10
|
-
require 'rubygems'
|
1
|
+
require "opentok/version"
|
2
|
+
require "opentok/opentok"
|
11
3
|
|
4
|
+
# Namespace for classes and modules in the OpenTok 2.2 Ruby SDK.
|
12
5
|
module OpenTok
|
13
6
|
|
14
|
-
API_URL = 'http://api.opentok.com/hl'
|
15
|
-
|
16
|
-
autoload :OpenTokSDK, 'open_tok/open_tok_sdk'
|
17
|
-
|
18
7
|
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require "active_support/inflector"
|
2
|
+
|
3
|
+
module OpenTok
|
4
|
+
# Represents an archive of an OpenTok session.
|
5
|
+
#
|
6
|
+
# @attr [int] created_at
|
7
|
+
# The time at which the archive was created, in milliseconds since the UNIX epoch.
|
8
|
+
#
|
9
|
+
# @attr [string] duration
|
10
|
+
# The duration of the archive, in milliseconds.
|
11
|
+
#
|
12
|
+
# @attr [string] id
|
13
|
+
# The archive ID.
|
14
|
+
#
|
15
|
+
# @attr [string] name
|
16
|
+
# The name of the archive. If no name was provided when the archive was created, this is set
|
17
|
+
# to null.
|
18
|
+
#
|
19
|
+
# @attr [string] partner_id
|
20
|
+
# The API key associated with the archive.
|
21
|
+
#
|
22
|
+
# @attr [string] reason
|
23
|
+
# For archives with the status "stopped", this can be set to "90 mins exceeded", "failure",
|
24
|
+
# "session ended", or "user initiated". For archives with the status "failed", this can be set
|
25
|
+
# to "system failure".
|
26
|
+
#
|
27
|
+
# @attr [string] session_id
|
28
|
+
# The session ID of the OpenTok session associated with this archive.
|
29
|
+
#
|
30
|
+
# @attr [float] size
|
31
|
+
# The size of the MP4 file. For archives that have not been generated, this value is set to 0.
|
32
|
+
#
|
33
|
+
# @attr [string] status
|
34
|
+
# The status of the archive, which can be one of the following:
|
35
|
+
#
|
36
|
+
# * "available" -- The archive is available for download from the OpenTok cloud.
|
37
|
+
# * "failed" -- The archive recording failed.
|
38
|
+
# * "started" -- The archive started and is in the process of being recorded.
|
39
|
+
# * "stopped" -- The archive stopped recording.
|
40
|
+
# * "uploaded" -- The archive is available for download from the the upload target
|
41
|
+
# S3 bucket.
|
42
|
+
#
|
43
|
+
# @attr [string] url
|
44
|
+
# The download URL of the available MP4 file. This is only set for an archive with the status set to
|
45
|
+
# "available"; for other archives, (including archives with the status "uploaded") this property is
|
46
|
+
# set to null. The download URL is obfuscated, and the file is only available from the URL for
|
47
|
+
# 10 minutes. To generate a new URL, call the Archive.listArchives() or OpenTok.getArchive() method.
|
48
|
+
class Archive
|
49
|
+
|
50
|
+
# @private
|
51
|
+
def initialize(interface, json)
|
52
|
+
@interface = interface
|
53
|
+
# TODO: validate json fits schema
|
54
|
+
@json = json
|
55
|
+
end
|
56
|
+
|
57
|
+
# A JSON encoded string representation of the archive
|
58
|
+
def to_json
|
59
|
+
@json.to_json
|
60
|
+
end
|
61
|
+
|
62
|
+
# Stops an OpenTok archive that is being recorded.
|
63
|
+
#
|
64
|
+
# Archives automatically stop recording after 90 minutes or when all clients have disconnected
|
65
|
+
# from the session being archived.
|
66
|
+
def stop
|
67
|
+
# TODO: validate returned json fits schema
|
68
|
+
@json = @interface.stop_by_id @json['id']
|
69
|
+
end
|
70
|
+
|
71
|
+
# Deletes an OpenTok archive.
|
72
|
+
#
|
73
|
+
# You can only delete an archive which has a status of "available" or "uploaded". Deleting an
|
74
|
+
# archive removes its record from the list of archives. For an "available" archive, it also
|
75
|
+
# removes the archive file, making it unavailable for download.
|
76
|
+
def delete
|
77
|
+
# TODO: validate returned json fits schema
|
78
|
+
@json = @interface.delete_by_id @json['id']
|
79
|
+
end
|
80
|
+
|
81
|
+
# @private ignore
|
82
|
+
def method_missing(method, *args, &block)
|
83
|
+
camelized_method = method.to_s.camelize(:lower)
|
84
|
+
if @json.has_key? camelized_method and args.empty?
|
85
|
+
# TODO: convert create_time method call to a Time object
|
86
|
+
@json[camelized_method]
|
87
|
+
else
|
88
|
+
super method, *args, &block
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require "opentok/archive"
|
2
|
+
|
3
|
+
module OpenTok
|
4
|
+
# A class for accessing an array of Archive objects.
|
5
|
+
class ArchiveList < Array
|
6
|
+
|
7
|
+
# The total number archives.
|
8
|
+
attr_reader :total
|
9
|
+
|
10
|
+
# @private
|
11
|
+
def initialize(interface, json)
|
12
|
+
@total = json['count']
|
13
|
+
super json['items'].map { |item| Archive.new interface, item }
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
require "opentok/client"
|
2
|
+
require "opentok/archive"
|
3
|
+
require "opentok/archive_list"
|
4
|
+
|
5
|
+
module OpenTok
|
6
|
+
# A class for working with OpenTok 2.0 archives.
|
7
|
+
class Archives
|
8
|
+
|
9
|
+
# @private
|
10
|
+
def initialize(client)
|
11
|
+
@client = client
|
12
|
+
end
|
13
|
+
|
14
|
+
# Starts archiving an OpenTok 2.0 session.
|
15
|
+
#
|
16
|
+
# Clients must be actively connected to the OpenTok session for you to successfully start
|
17
|
+
# recording an archive.
|
18
|
+
#
|
19
|
+
# You can only record one archive at a time for a given session. You can only record archives
|
20
|
+
# of OpenTok server-enabled sessions; you cannot archive peer-to-peer sessions.
|
21
|
+
#
|
22
|
+
# @param [String] session_id The session ID of the OpenTok session to archive.
|
23
|
+
# @param [Hash] options A hash with the key 'name' or :name.
|
24
|
+
# @option options [String] :name This is the name of the archive. You can use this name
|
25
|
+
# to identify the archive. It is a property of the Archive object, and it is a property
|
26
|
+
# of archive-related events in the OpenTok.js library.
|
27
|
+
#
|
28
|
+
# @return [Archive] The Archive object, which includes properties defining the archive,
|
29
|
+
# including the archive ID.
|
30
|
+
#
|
31
|
+
# @raise [OpenTokArchiveError] The archive could not be started. The request was invalid or
|
32
|
+
# the session has no connected clients.
|
33
|
+
# @raise [OpenTokAuthenticationError] Authentication failed while starting an archive.
|
34
|
+
# Invalid API key.
|
35
|
+
# @raise [OpenTokArchiveError] The archive could not be started. The session ID does not exist.
|
36
|
+
# @raise [OpenTokArchiveError] The archive could not be started. The session could be
|
37
|
+
# peer-to-peer or the session is already being recorded.
|
38
|
+
# @raise [OpenTokArchiveError] The archive could not be started.
|
39
|
+
def create(session_id, options = {})
|
40
|
+
raise ArgumentError, "session_id not provided" if session_id.to_s.empty?
|
41
|
+
opts = Hash.new
|
42
|
+
opts[:name] = options[:name].to_s || options["name"].to_s
|
43
|
+
archive_json = @client.start_archive(session_id, opts)
|
44
|
+
Archive.new self, archive_json
|
45
|
+
end
|
46
|
+
|
47
|
+
# Gets an Archive object for the given archive ID.
|
48
|
+
#
|
49
|
+
# @param [String] archive_id The archive ID.
|
50
|
+
#
|
51
|
+
# @return [Archive] The Archive object.
|
52
|
+
# @raise [OpenTokArchiveError] The archive could not be retrieved. The archive ID is invalid.
|
53
|
+
# @raise [OpenTokAuthenticationError] Authentication failed while retrieving the archive.
|
54
|
+
# Invalid API key.
|
55
|
+
# @raise [OpenTokArchiveError] The archive could not be retrieved.
|
56
|
+
def find(archive_id)
|
57
|
+
raise ArgumentError, "archive_id not provided" if archive_id.to_s.empty?
|
58
|
+
archive_json = @client.get_archive(archive_id.to_s)
|
59
|
+
Archive.new self, archive_json
|
60
|
+
end
|
61
|
+
|
62
|
+
# Returns an ArchiveList, which is an array of archives that are completed and in-progress,
|
63
|
+
# for your API key.
|
64
|
+
#
|
65
|
+
# @param [Hash] options A hash with keys defining which range of archives to retrieve.
|
66
|
+
# @option options [integer] :offset Optional. The index offset of the first archive. 0 is offset
|
67
|
+
# of the most recently started archive. 1 is the offset of the archive that started prior to
|
68
|
+
# the most recent archive. If you do not specify an offset, 0 is used.
|
69
|
+
# @option options [integer] :count Optional. The number of archives to be returned. The maximum
|
70
|
+
# number of archives returned is 1000.
|
71
|
+
#
|
72
|
+
# @return [ArchiveList] An ArchiveList object, which is an array of Archive objects.
|
73
|
+
def all(options = {})
|
74
|
+
raise ArgumentError, "Limit is invalid" unless options[:count].nil? or (0..100).include? options[:count]
|
75
|
+
archive_list_json = @client.list_archives(options[:offset], options[:count])
|
76
|
+
ArchiveList.new self, archive_list_json
|
77
|
+
end
|
78
|
+
|
79
|
+
# Stops an OpenTok archive that is being recorded.
|
80
|
+
#
|
81
|
+
# Archives automatically stop recording after 90 minutes or when all clients have disconnected
|
82
|
+
# from the session being archived.
|
83
|
+
#
|
84
|
+
# @param [String] archive_id The archive ID of the archive you want to stop recording.
|
85
|
+
#
|
86
|
+
# @return [Archive] The Archive object corresponding to the archive being stopped.
|
87
|
+
#
|
88
|
+
# @raise [OpenTokArchiveError] The archive could not be stopped. The request was invalid.
|
89
|
+
# @raise [OpenTokAuthenticationError] Authentication failed while stopping an archive.
|
90
|
+
# @raise [OpenTokArchiveError] The archive could not be stopped. The archive ID does not exist.
|
91
|
+
# @raise [OpenTokArchiveError] The archive could not be stopped. The archive is not currently
|
92
|
+
# recording.
|
93
|
+
# @raise [OpenTokArchiveError] The archive could not be started.
|
94
|
+
def stop_by_id(archive_id)
|
95
|
+
raise ArgumentError, "archive_id not provided" if archive_id.to_s.empty?
|
96
|
+
archive_json = @client.stop_archive(archive_id)
|
97
|
+
Archive.new self, archive_json
|
98
|
+
end
|
99
|
+
|
100
|
+
# Deletes an OpenTok archive.
|
101
|
+
#
|
102
|
+
# You can only delete an archive which has a status of "available", "uploaded", or "deleted".
|
103
|
+
# Deleting an archive removes its record from the list of archives. For an "available" archive,
|
104
|
+
# it also removes the archive file, making it unavailable for download. For a "deleted"
|
105
|
+
# archive, the archive remains deleted.
|
106
|
+
#
|
107
|
+
# @param [String] archive_id The archive ID of the archive you want to delete.
|
108
|
+
#
|
109
|
+
# @raise [OpenTokAuthenticationError] Authentication failed or an invalid archive ID was given.
|
110
|
+
# @raise [OpenTokArchiveError] The archive could not be deleted. The status must be
|
111
|
+
# 'available', 'deleted', or 'uploaded'.
|
112
|
+
# @raise [OpenTokArchiveError] The archive could not be deleted.
|
113
|
+
def delete_by_id(archive_id)
|
114
|
+
raise ArgumentError, "archive_id not provided" if archive_id.to_s.empty?
|
115
|
+
response = @client.delete_archive(archive_id)
|
116
|
+
(200..300).include? response.code
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
require "opentok/exceptions"
|
2
|
+
|
3
|
+
require "httparty"
|
4
|
+
|
5
|
+
module OpenTok
|
6
|
+
# @private For internal use by the SDK.
|
7
|
+
class Client
|
8
|
+
include HTTParty
|
9
|
+
# TODO: expose a setting for http debugging for developers
|
10
|
+
# debug_output $stdout
|
11
|
+
|
12
|
+
def initialize(api_key, api_secret, api_url)
|
13
|
+
self.class.base_uri api_url
|
14
|
+
self.class.headers({
|
15
|
+
"X-TB-PARTNER-AUTH" => "#{api_key}:#{api_secret}",
|
16
|
+
"User-Agent" => "OpenTok-Ruby-SDK/#{VERSION}"
|
17
|
+
})
|
18
|
+
@api_key = api_key
|
19
|
+
end
|
20
|
+
|
21
|
+
def create_session(opts)
|
22
|
+
response = self.class.post("/session/create", :body => opts)
|
23
|
+
case response.code
|
24
|
+
when (200..300)
|
25
|
+
response
|
26
|
+
when 403
|
27
|
+
raise OpenTokAuthenticationError, "Authentication failed while creating a session. API Key: #{@api_key}"
|
28
|
+
else
|
29
|
+
raise OpenTokError, "Failed to create session. Response code: #{response.code}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def start_archive(session_id, opts)
|
34
|
+
body = { "sessionId" => session_id, "action" => "start" }
|
35
|
+
body["name"] = opts[:name] unless opts[:name].nil?
|
36
|
+
response = self.class.post("/v2/partner/#{@api_key}/archive", {
|
37
|
+
:body => body.to_json,
|
38
|
+
:headers => { "Content-Type" => "application/json" }
|
39
|
+
})
|
40
|
+
case response.code
|
41
|
+
when 200
|
42
|
+
response
|
43
|
+
when 400
|
44
|
+
raise OpenTokArchiveError, "The archive could not be started. The request was invalid or the session has no connected clients."
|
45
|
+
when 403
|
46
|
+
raise OpenTokAuthenticationError, "Authentication failed while starting an archive. API Key: #{@api_key}"
|
47
|
+
when 404
|
48
|
+
raise OpenTokArchiveError, "The archive could not be started. The Session ID does not exist: #{session_id}"
|
49
|
+
when 409
|
50
|
+
raise OpenTokArchiveError, "The archive could not be started. The session could be peer-to-peer or the session is already being recorded."
|
51
|
+
else
|
52
|
+
raise OpenTokArchiveError, "The archive could not be started"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def get_archive(archive_id)
|
57
|
+
response = self.class.get("/v2/partner/#{@api_key}/archive/#{archive_id}")
|
58
|
+
case response.code
|
59
|
+
when 200
|
60
|
+
response
|
61
|
+
when 400
|
62
|
+
raise OpenTokArchiveError, "The archive could not be retrieved. The Archive ID was invalid: #{archive_id}"
|
63
|
+
when 403
|
64
|
+
raise OpenTokAuthenticationError, "Authentication failed while retrieving an archive. API Key: #{@api_key}"
|
65
|
+
else
|
66
|
+
raise OpenTokArchiveError, "The archive could not be retrieved."
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def list_archives(offset, count)
|
71
|
+
query = Hash.new
|
72
|
+
query[:offset] = offset unless offset.nil?
|
73
|
+
query[:count] = count unless count.nil?
|
74
|
+
response = self.class.get("/v2/partner/#{@api_key}/archive", {
|
75
|
+
:query => query.empty? ? nil : query
|
76
|
+
})
|
77
|
+
case response.code
|
78
|
+
when 200
|
79
|
+
response
|
80
|
+
when 403
|
81
|
+
raise OpenTokAuthenticationError, "Authentication failed while retrieving archives. API Key: #{@api_key}"
|
82
|
+
else
|
83
|
+
raise OpenTokArchiveError, "The archives could not be retrieved."
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def stop_archive(archive_id)
|
88
|
+
response = self.class.post("/v2/partner/#{@api_key}/archive/#{archive_id}", {
|
89
|
+
:body => { "action" => "stop" }.to_json,
|
90
|
+
:headers => { "Content-Type" => "application/json" }
|
91
|
+
})
|
92
|
+
case response.code
|
93
|
+
when 200
|
94
|
+
response
|
95
|
+
when 400
|
96
|
+
raise OpenTokArchiveError, "The archive could not be stopped. The request was invalid."
|
97
|
+
when 403
|
98
|
+
raise OpenTokAuthenticationError, "Authentication failed while stopping an archive. API Key: #{@api_key}"
|
99
|
+
when 404
|
100
|
+
raise OpenTokArchiveError, "The archive could not be stopped. The Archive ID does not exist: #{archive_id}"
|
101
|
+
when 409
|
102
|
+
raise OpenTokArchiveError, "The archive could not be stopped. The archive is not currently recording."
|
103
|
+
else
|
104
|
+
raise OpenTokArchiveError, "The archive could not be started."
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def delete_archive(archive_id)
|
109
|
+
response = self.class.delete("/v2/partner/#{@api_key}/archive/#{archive_id}", {
|
110
|
+
:headers => { "Content-Type" => "application/json" }
|
111
|
+
})
|
112
|
+
case response.code
|
113
|
+
when 204
|
114
|
+
response
|
115
|
+
when 403
|
116
|
+
raise OpenTokAuthenticationError, "Authentication failed or an invalid Archive ID was given while deleting an archive. API Key: #{@api_key}, Archive ID: #{archive_id}"
|
117
|
+
when 409
|
118
|
+
raise OpenTokArchiveError, "The archive could not be deleted. The status must be 'available', 'deleted', or 'uploaded'. Archive ID: #{archive_id}"
|
119
|
+
else
|
120
|
+
raise OpenTokArchiveError, "The archive could not be deleted."
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module OpenTok
|
2
|
+
|
3
|
+
# Defines errors raised by methods of the OpenTok Ruby SDK.
|
4
|
+
class OpenTokError < StandardError; end
|
5
|
+
# Defines errors raised by archive-related methods of the OpenTok Ruby SDK.
|
6
|
+
class OpenTokArchiveError < OpenTokError; end
|
7
|
+
# Defines errors raised when you attempt an operation using an invalid OpenTok API key or secret.
|
8
|
+
class OpenTokAuthenticationError < OpenTokError; end
|
9
|
+
|
10
|
+
end
|
@@ -0,0 +1,174 @@
|
|
1
|
+
require "opentok/constants"
|
2
|
+
require "opentok/session"
|
3
|
+
require "opentok/client"
|
4
|
+
require "opentok/token_generator"
|
5
|
+
require "opentok/archives"
|
6
|
+
|
7
|
+
require "resolv"
|
8
|
+
|
9
|
+
module OpenTok
|
10
|
+
# Contains methods for creating OpenTok sessions, generating tokens, and working with archives.
|
11
|
+
#
|
12
|
+
# To create a new OpenTok object, call the OpenTok constructor with your OpenTok API key
|
13
|
+
# and the API secret from the OpenTok dashboard (https://dashboard.tokbox.com). Do not
|
14
|
+
# publicly share your API secret. You will use it with the OpenTok constructor (only on your web
|
15
|
+
# server) to create OpenTok sessions.
|
16
|
+
#
|
17
|
+
# @attr_reader [String] api_secret @private The OpenTok API secret.
|
18
|
+
# @attr_reader [String] api_key @private The OpenTok API key.
|
19
|
+
#
|
20
|
+
#
|
21
|
+
# @!method generate_token(options)
|
22
|
+
# Generates a token for a given session.
|
23
|
+
#
|
24
|
+
# @param [String] sessioin_id The session ID of the session to be accessed by the client using
|
25
|
+
# the token.
|
26
|
+
#
|
27
|
+
# @param [Hash] options A hash defining options for the token.
|
28
|
+
# @option options [String] :role The role for the token. Set this to one of the following
|
29
|
+
# values:
|
30
|
+
# * <code>:subscriber</code> -- A subscriber can only subscribe to streams.
|
31
|
+
#
|
32
|
+
# * <code>:publisher</code> -- A publisher can publish streams, subscribe to
|
33
|
+
# streams, and signal. (This is the default value if you do not specify a role.)
|
34
|
+
#
|
35
|
+
# * <code>:moderator</code> -- In addition to the privileges granted to a
|
36
|
+
# publisher, in clients using the OpenTok.js 2.2 library, a moderator can call the
|
37
|
+
# <code>forceUnpublish()</code> and <code>forceDisconnect()</code> method of the
|
38
|
+
# Session object.
|
39
|
+
# @option options [integer] :expire_time The expiration time, in seconds since the UNIX epoch.
|
40
|
+
# Pass in 0 to use the default expiration time of 24 hours after the token creation time.
|
41
|
+
# The maximum expiration time is 30 days after the creation time.
|
42
|
+
# @option options [String] :data A string containing connection metadata describing the
|
43
|
+
# end-user. For example, you can pass the user ID, name, or other data describing the
|
44
|
+
# end-user. The length of the string is limited to 1000 characters. This data cannot be
|
45
|
+
# updated once it is set.
|
46
|
+
# @return [String] The token string.
|
47
|
+
class OpenTok
|
48
|
+
|
49
|
+
include TokenGenerator
|
50
|
+
generates_tokens({
|
51
|
+
:api_key => ->(instance) { instance.api_key },
|
52
|
+
:api_secret => ->(instance) { instance.api_secret }
|
53
|
+
})
|
54
|
+
|
55
|
+
# @private
|
56
|
+
# don't want these to be mutable, may cause bugs related to inconsistency since these values are
|
57
|
+
# cached in objects that this can create
|
58
|
+
attr_reader :api_key, :api_secret, :api_url
|
59
|
+
|
60
|
+
##
|
61
|
+
# Create a new OpenTok object.
|
62
|
+
#
|
63
|
+
# @param [String] api_key Your OpenTok API key. See the OpenTok dashboard
|
64
|
+
# (https://dashboard.tokbox.com).
|
65
|
+
# @param [String] api_secret Your OpenTok API key.
|
66
|
+
# @param [String] api_url Do not set this parameter. It is for internal use by TokBox.
|
67
|
+
def initialize(api_key, api_secret , api_url = ::OpenTok::API_URL)
|
68
|
+
@api_key = api_key.to_s()
|
69
|
+
@api_secret = api_secret
|
70
|
+
# TODO: do we really need a copy of this in the instance or should we overwrite the module
|
71
|
+
# constant so that other objects can access the same copy?
|
72
|
+
@api_url = api_url
|
73
|
+
end
|
74
|
+
|
75
|
+
# Creates a new OpenTok session and returns the session ID, which uniquely identifies
|
76
|
+
# the session.
|
77
|
+
#
|
78
|
+
# For example, when using the OpenTok JavaScript library, use the session ID when calling the
|
79
|
+
# OT.initSession()</a> method (to initialize an OpenTok session).
|
80
|
+
#
|
81
|
+
# OpenTok sessions do not expire. However, authentication tokens do expire (see the
|
82
|
+
# generateToken() method). Also note that sessions cannot explicitly be destroyed.
|
83
|
+
#
|
84
|
+
# A session ID string can be up to 255 characters long.
|
85
|
+
#
|
86
|
+
# Calling this method results in an OpenTokException in the event of an error.
|
87
|
+
# Check the error message for details.
|
88
|
+
#
|
89
|
+
# You can also create a session using the OpenTok REST API (see
|
90
|
+
# http://www.tokbox.com/opentok/api/#session_id_production) or the OpenTok dashboard
|
91
|
+
# (see https://dashboard.tokbox.com/projects).
|
92
|
+
#
|
93
|
+
# @param [Hash] opts (Optional) This hash defines options for the session.
|
94
|
+
#
|
95
|
+
# @option opts [String] :media_mode Determines whether the session will transmit streams the
|
96
|
+
# using OpenTok Media Router (<code>:routed</code>) or not (<code>:relayed</code>).
|
97
|
+
# By default, sessions use the OpenTok Media Router.
|
98
|
+
#
|
99
|
+
# With the <code>mediaMode</code> property set to <code>:routed</code>, the session
|
100
|
+
# will use the {http://tokbox.com/#multiparty OpenTok Media Router}.
|
101
|
+
# The OpenTok Media Router provides the following benefits:
|
102
|
+
#
|
103
|
+
# * The OpenTok Media Router can decrease bandwidth usage in multiparty sessions.
|
104
|
+
# (When the <code>mediaMode</code> property is set to <code>:relayed</code>,
|
105
|
+
# each client must send a separate audio-video stream to each client subscribing to
|
106
|
+
# it.)
|
107
|
+
# * The OpenTok Media Router can improve the quality of the user experience through
|
108
|
+
# {http://tokbox.com/#iqc Intelligent Quality Control}. With
|
109
|
+
# Intelligent Quality Control, if a client's connectivity degrades to a degree that
|
110
|
+
# it does not support video for a stream it's subscribing to, the video is dropped on
|
111
|
+
# that client (without affecting other clients), and the client receives audio only.
|
112
|
+
# If the client's connectivity improves, the video returns.
|
113
|
+
# * The OpenTok Media Router supports the {http://tokbox.com/platform/archiving archiving}
|
114
|
+
# feature, which lets you record, save, and retrieve OpenTok sessions.
|
115
|
+
#
|
116
|
+
# With the <code>mediaMode</code> property set to <code>:relayed</code>, the session
|
117
|
+
# will attempt to transmit streams directly between clients. If clients cannot connect due to
|
118
|
+
# firewall restrictions, the session uses the OpenTok TURN server to relay audio-video
|
119
|
+
# streams.
|
120
|
+
#
|
121
|
+
# You will be billed for streamed minutes if you use the OpenTok Media Router or if the
|
122
|
+
# session uses the OpenTok TURN server to relay streams. For information on pricing, see the
|
123
|
+
# {http://www.tokbox.com/pricing OpenTok pricing page}.
|
124
|
+
#
|
125
|
+
# @option opts [String] :location An IP address that the OpenTok servers will use to
|
126
|
+
# situate the session in its global network. If you do not set a location hint,
|
127
|
+
# the OpenTok servers will be based on the first client connecting to the session.
|
128
|
+
#
|
129
|
+
# @return [Session] The Session object. The session_id property of the object is the session ID.
|
130
|
+
def create_session(opts={})
|
131
|
+
|
132
|
+
# normalize opts so all keys are symbols and only include valid_opts
|
133
|
+
valid_opts = [ :media_mode, :location ]
|
134
|
+
opts = opts.inject({}) do |m,(k,v)|
|
135
|
+
if valid_opts.include? k.to_sym
|
136
|
+
m[k.to_sym] = v
|
137
|
+
end
|
138
|
+
m
|
139
|
+
end
|
140
|
+
|
141
|
+
# keep opts around for Session constructor, build REST params
|
142
|
+
params = opts.clone
|
143
|
+
|
144
|
+
# anything other than :relayed sets the REST param to "disabled", in which case we force
|
145
|
+
# opts to be :routed. if we were more strict we could raise an error when the value isn't
|
146
|
+
# either :relayed or :routed
|
147
|
+
if params.delete(:media_mode) == :relayed
|
148
|
+
params["p2p.preference"] = "enabled"
|
149
|
+
else
|
150
|
+
params["p2p.preference"] = "disabled"
|
151
|
+
opts[:media_mode] = :routed
|
152
|
+
end
|
153
|
+
# location is optional, but it has to be an IP address if specified at all
|
154
|
+
unless params[:location].nil?
|
155
|
+
raise "location must be an IPv4 address" unless params[:location] =~ Resolv::IPv4::Regex
|
156
|
+
end
|
157
|
+
|
158
|
+
response = client.create_session(params)
|
159
|
+
Session.new api_key, api_secret, response['sessions']['Session']['session_id'], opts
|
160
|
+
end
|
161
|
+
|
162
|
+
# An Archives object, which lets you work with OpenTok 2.0 archives.
|
163
|
+
def archives
|
164
|
+
@archives ||= Archives.new client
|
165
|
+
end
|
166
|
+
|
167
|
+
protected
|
168
|
+
|
169
|
+
def client
|
170
|
+
@client ||= Client.new api_key, api_secret, api_url
|
171
|
+
end
|
172
|
+
|
173
|
+
end
|
174
|
+
end
|