require "opentok/constants"
require "opentok/session"
require "opentok/client"
require "opentok/token_generator"
require "opentok/connections"
require "opentok/archives"
require "opentok/sip"
require "opentok/streams"
require "opentok/signals"
require "opentok/broadcasts"
require "resolv"
require "set"
module OpenTok
# Contains methods for creating OpenTok sessions and generating tokens. It also includes
# methods for returning object that let you work with archives, work with live streaming
# broadcasts, using SIP interconnect, sending signals to sessions, disconnecting clients from
# sessions, and setting the layout classes for streams.
#
# To create a new OpenTok object, call the OpenTok constructor with your OpenTok API key
# and the API secret for your {https://tokbox.com/account OpenTok project}. Do not
# publicly share your API secret. You will use it with the OpenTok constructor (only on your web
# server) to create OpenTok sessions.
#
# @attr_reader [String] api_secret @private The OpenTok API secret.
# @attr_reader [String] api_key @private The OpenTok API key.
#
#
# @!method generate_token(session_id, options)
# Generates a token for a given session.
#
# @param [String] session_id The session ID of the session to be accessed by the client using
# the token.
#
# @param [Hash] options A hash defining options for the token.
# @option options [Symbol] :role The role for the token. Set this to one of the following
# values:
# * :subscriber
-- A subscriber can only subscribe to streams.
#
# * :publisher
-- A publisher can publish streams, subscribe to
# streams, and signal. (This is the default value if you do not specify a role.)
#
# * :moderator
-- In addition to the privileges granted to a
# publisher, in clients using the OpenTok.js library, a moderator can call the
# forceUnpublish()
and forceDisconnect()
method of the
# Session object.
# @option options [integer] :expire_time The expiration time, in seconds since the UNIX epoch.
# Pass in 0 to use the default expiration time of 24 hours after the token creation time.
# The maximum expiration time is 30 days after the creation time.
# @option options [String] :data A string containing connection metadata describing the
# end-user. For example, you can pass the user ID, name, or other data describing the
# end-user. The length of the string is limited to 1000 characters. This data cannot be
# updated once it is set.
# @option options [Array] :initial_layout_class_list
# An array of class names (strings) to be used as the initial layout classes for streams
# published by the client. Layout classes are used in customizing the layout of videos in
# {https://tokbox.com/developer/guides/broadcast/live-streaming/ live streaming broadcasts}
# and {https://tokbox.com/developer/guides/archiving/layout-control.html composed archives}.
# @return [String] The token string.
class OpenTok
include TokenGenerator
generates_tokens({
:api_key => ->(instance) { instance.api_key },
:api_secret => ->(instance) { instance.api_secret }
})
# @private
# don't want these to be mutable, may cause bugs related to inconsistency since these values are
# cached in objects that this can create
attr_reader :api_key, :api_secret, :timeout_length, :api_url, :ua_addendum
##
# Create a new OpenTok object.
#
# @param [String] api_key The OpenTok API key for your
# {https://tokbox.com/account OpenTok project}.
# @param [String] api_secret Your OpenTok API key.
# @option opts [Symbol] :api_url Do not set this parameter. It is for internal use by TokBox.
# @option opts [Symbol] :ua_addendum Do not set this parameter. It is for internal use by TokBox.
# @option opts [Symbol] :timeout_length Custom timeout in seconds. If not provided, defaults to 2 seconds.
def initialize(api_key, api_secret, opts={})
@api_key = api_key.to_s()
@api_secret = api_secret
@timeout_length = opts[:timeout_length] || 2
@api_url = opts[:api_url] || API_URL
@ua_addendum = opts[:ua_addendum]
end
# Creates a new OpenTok session and returns the session ID, which uniquely identifies
# the session.
#
# For example, when using the OpenTok JavaScript library, use the session ID when calling the
# OT.initSession() method (to initialize an OpenTok session).
#
# OpenTok sessions do not expire. However, authentication tokens do expire (see the
# generateToken() method). Also note that sessions cannot explicitly be destroyed.
#
# A session ID string can be up to 255 characters long.
#
# Calling this method results in an OpenTokException in the event of an error.
# Check the error message for details.
#
# You can also create a session using the OpenTok REST API (see
# http://www.tokbox.com/opentok/api/#session_id_production) or at your
# {https://tokbox.com/account OpenTok account page}.
#
# @param [Hash] opts (Optional) This hash defines options for the session.
#
# @option opts [Symbol] :media_mode Determines whether the session will transmit streams the
# using OpenTok Media Router (:routed
) or not (:relayed
).
# By default, this property is set to :relayed
.
#
# With the media_mode
property set to :relayed
, the session
# will attempt to transmit streams directly between clients. If clients cannot connect due to
# firewall restrictions, the session uses the OpenTok TURN server to relay audio-video
# streams.
#
# With the media_mode
property set to :routed
, the session will use
# the {https://tokbox.com/opentok/tutorials/create-session/#media-mode OpenTok Media Router}.
# The OpenTok Media Router provides the following benefits:
#
# * The OpenTok Media Router can decrease bandwidth usage in multiparty sessions.
# (When the media_mode
property is set to :relayed
,
# each client must send a separate audio-video stream to each client subscribing to
# it.)
# * The OpenTok Media Router can improve the quality of the user experience through
# {https://tokbox.com/platform/fallback audio fallback and video recovery}. With
# these features, if a client's connectivity degrades to a degree that
# it does not support video for a stream it's subscribing to, the video is dropped on
# that client (without affecting other clients), and the client receives audio only.
# If the client's connectivity improves, the video returns.
# * The OpenTok Media Router supports the
# {https://tokbox.com/opentok/tutorials/archiving archiving}
# feature, which lets you record, save, and retrieve OpenTok sessions.
#
# @option opts [String] :location An IP address that the OpenTok servers will use to
# situate the session in its global network. If you do not set a location hint,
# the OpenTok servers will be based on the first client connecting to the session.
#
# @option opts [Symbol] :archive_mode Determines whether the session will be archived
# automatically (:always
) or not (:manual
). When using automatic
# archiving, the session must use the :routed
media mode.
#
# @return [Session] The Session object. The session_id property of the object is the session ID.
def create_session(opts={})
# normalize opts so all keys are symbols and only include valid_opts
valid_opts = [ :media_mode, :location, :archive_mode ]
opts = opts.inject({}) do |m,(k,v)|
if valid_opts.include? k.to_sym
m[k.to_sym] = v
end
m
end
# keep opts around for Session constructor, build REST params
params = opts.clone
# anything other than :relayed sets the REST param to "disabled", in which case we force
# opts to be :routed. if we were more strict we could raise an error when the value isn't
# either :relayed or :routed
if params.delete(:media_mode) == :routed
params["p2p.preference"] = "disabled"
else
params["p2p.preference"] = "enabled"
opts[:media_mode] = :relayed
end
# location is optional, but it has to be an IP address if specified at all
unless params[:location].nil?
raise "location must be an IPv4 address" unless params[:location] =~ Resolv::IPv4::Regex
end
# archive mode is optional, but it has to be one of the valid values if present
unless params[:archive_mode].nil?
raise "archive mode must be either always or manual" unless ARCHIVE_MODES.include? params[:archive_mode].to_sym
end
raise "A session with always archive mode must also have the routed media mode." if (params[:archive_mode] == :always && params[:media_mode] == :relayed)
response = client.create_session(params)
Session.new api_key, api_secret, response['sessions']['Session']['session_id'], opts
end
# An Archives object, which lets you work with OpenTok archives.
def archives
@archives ||= Archives.new client
end
# A Broadcasts object, which lets you work with OpenTok live streaming broadcasts.
def broadcasts
@broadcasts ||= Broadcasts.new client
end
# A Sip object, which lets you use the OpenTok SIP gateway.
def sip
@sip ||= Sip.new client
end
# A Streams object, which lets you work with OpenTok live streaming broadcasts.
def streams
@streams ||= Streams.new client
end
# A Signals object, which lets you send signals to OpenTok sessions.
def signals
@signals ||= Signals.new client
end
# A Connections object, which lets disconnect clients from an OpenTok session.
def connections
@connections ||= Connections.new client
end
protected
def client
@client ||= Client.new api_key, api_secret, api_url, ua_addendum, timeout_length: @timeout_length
end
end
end