Esempio n. 1
0
        public void GenerateTokenWithExpireTimeTest()
        {
            OpenTok opentok    = new OpenTok(apiKey, apiSecret);
            double  expireTime = OpenTokUtils.GetCurrentUnixTimeStamp() + 10;

            String sessionId = "1_MX4xMjM0NTZ-flNhdCBNYXIgMTUgMTQ6NDI6MjMgUERUIDIwMTR-MC40OTAxMzAyNX4";
            string token     = opentok.GenerateToken(sessionId, expireTime: expireTime);

            Assert.NotNull(token);
            var data = CheckToken(token, apiKey);

            Assert.Equal(data["partner_id"], apiKey.ToString());
            Assert.NotNull(data["sig"]);
            Assert.NotNull(data["create_time"]);
            Assert.NotNull(data["nonce"]);
            Assert.Equal(data["role"], Role.PUBLISHER.ToString());
            Assert.Equal(data["expire_time"], ((long)expireTime).ToString());
        }
Esempio n. 2
0
        /**
         * Starts archiving an OpenTok session.
         *
         * <p>
         * Clients must be actively connected to the OpenTok session for you to successfully start
         * recording an archive.
         * <p>
         * You can only record one archive at a time for a given session. You can only record
         * archives of sessions that uses the OpenTok Media Router (sessions with the media mode set
         * to routed); you cannot archive sessions with the media mode set to relayed.
         * <p>
         * Note that you can have the session be automatically archived by setting the archiveMode
         * parameter of the OpenTok.CreateSession() method to ArchiveMode.ALWAYS.
         *
         * @param sessionId The session ID of the OpenTok session to archive.
         *
         * @param name The name of the archive. You can use this name to identify the archive. It is
         * a property of the Archive object, and it is a property of archive-related events in the
         * OpenTok client libraries.
         *
         * @param hasVideo Whether the archive will record video (true) or not (false). The default
         * value is true (video is recorded). If you set both <code>hasAudio</code> and
         * <code>hasVideo</code> to false, the call to the <code>StartArchive()</code> method
         * results in an error.
         *
         * @param hasAudio Whether the archive will record audio (true) or not (false). The default
         * value is true (audio is recorded). If you set both <code>hasAudio</code> and
         * <code>hasVideo</code> to false, the call to the <code>StartArchive()</code> method
         * results in an error.
         *
         * @param outputMode Whether all streams in the archive are recorded to a single file
         * (<code>OutputMode.COMPOSED</code>, the default) or to individual files
         * (<code>OutputMode.INDIVIDUAL</code>).
         *
         * @return The Archive object. This object includes properties defining the archive,
         * including the archive ID.
         */
        public async Task <Archive> StartArchive(string sessionId, string name = "", bool hasVideo = true, bool hasAudio = true, OutputMode outputMode = OutputMode.COMPOSED)
        {
            if (String.IsNullOrEmpty(sessionId))
            {
                throw new OpenTokArgumentException("Session not valid");
            }
            string url     = string.Format("v2/partner/{0}/archive", this.ApiKey);
            var    headers = new Dictionary <string, string> {
                { "Content-type", "application/json" }
            };
            var data = new Dictionary <string, object>()
            {
                { "sessionId", sessionId }, { "name", name }, { "hasVideo", hasVideo }, { "hasAudio", hasAudio }, { "outputMode", outputMode.ToString().ToLower() }
            };
            string response = await Client.Post(url, headers, data);

            return(OpenTokUtils.GenerateArchive(response, ApiKey, ApiSecret, OpenTokServer));
        }
Esempio n. 3
0
        /**
         * Starts archiving an OpenTok 2.0 session.
         *
         * <p>
         * Clients must be actively connected to the OpenTok session for you to successfully start
         * recording an archive.
         * <p>
         * You can only record one archive at a time for a given session. You can only record
         * archives of sessions that uses the OpenTok Media Router; you cannot archive peer-to-peer
         * sessions.
         *
         * @param sessionId The session ID of the OpenTok session to archive.
         *
         * @param name The name of the archive. You can use this name to identify the archive. It is
         * a property of the Archive object, and it is a property of archive-related events in the
         * OpenTok client libraries.
         *
         * @return The Archive object. This object includes properties defining the archive,
         * including the archive ID.
         */
        public Archive StartArchive(string sessionId, string name = "")
        {
            if (String.IsNullOrEmpty(sessionId))
            {
                throw new OpenTokArgumentException("Session not valid");
            }
            string url     = string.Format("v2/partner/{0}/archive", this.ApiKey);
            var    headers = new Dictionary <string, string> {
                { "Content-type", "application/json" }
            };
            var data = new Dictionary <string, object>()
            {
                { "sessionId", sessionId }, { "name", name }
            };
            string response = Client.Post(url, headers, data);

            return(OpenTokUtils.GenerateArchive(response, ApiKey, ApiSecret, OpenTokServer));
        }
Esempio n. 4
0
        /**
         * Creates a new OpenTok session.
         * <p>
         * OpenTok sessions do not expire. However, authentication tokens do expire (see the
         * generateToken() method). Also note that sessions cannot explicitly be destroyed.
         * <p>
         * A session ID string can be up to 255 characters long.
         * <p>
         * 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
         * <a href="http://www.tokbox.com/opentok/api/#session_id_production">OpenTok
         * REST API</a> or the <a href="https://dashboard.tokbox.com/projects">OpenTok
         * dashboard</a>.
         *
         * @param location (String) 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.
         *
         * @param mediaMode Whether the session will transmit streams using the
         * OpenTok Media Router (<code>MediaMode.ROUTED</code>) or not
         * (<code>MediaMode.RELAYED</code>). By default, the setting is
         * <code>MediaMode.RELAYED</code>.
         * <p>
         * With the <code>mediaMode</code> parameter set to <code>MediaMode.RELAYED</code>, 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
         * streams.
         * <p>
         * The <a href="https://tokbox.com/opentok/tutorials/create-session/#media-mode"
         * target="_top">OpenTok Media Router</a> provides the following benefits:
         *
         * <ul>
         *   <li>The OpenTok Media Router can decrease bandwidth usage in multiparty sessions.
         *       (When the <code>mediaMode</code> parameter is set to
         *       <code>MediaMode.ROUTED</code>, each client must send a separate audio-video stream
         *      to each client subscribing to it.)</li>
         *   <li>The OpenTok Media Router can improve the quality of the user experience through
         *     <a href="https://tokbox.com/platform/fallback" target="_top">audio fallback and video
         *     recovery</a>. 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.</li>
         *   <li>The OpenTok Media Router supports the
         *     <a href="http://tokbox.com/opentok/tutorials/archiving" target="_top">archiving</a>
         *     feature, which lets you record, save, and retrieve OpenTok sessions.</li>
         * </ul>
         *
         * @param archiveMode Whether the session is automatically archived
         * (<code>ArchiveMode.ALWAYS</code>) or not (<code>ArchiveMode.MANUAL</code>). By default,
         * the setting is <code>ArchiveMode.MANUAL</code>, and you must call the
         * StartArchive() method of the OpenTok object to start archiving. To archive the session
         * (either automatically or not), you must set the mediaMode parameter to
         * <code>MediaMode.ROUTED</code>.
         *
         * @return A Session object representing the new session. The <code>Id</code> property of
         * the Session is the session ID, which uniquely identifies the session. You will use
         * this session ID in the client SDKs to identify the session. For example, when using the
         * OpenTok.js library, use the session ID when calling the
         * <a href="http://tokbox.com/opentok/libraries/client/js/reference/OT.html#initSession">
         * OT.initSession()</a> method (to initialize an OpenTok session).
         */
        public async Task <Session> CreateSession(string location = "", MediaMode mediaMode = MediaMode.RELAYED, ArchiveMode archiveMode = ArchiveMode.MANUAL)
        {
            if (!OpenTokUtils.TestIpAddress(location))
            {
                throw new OpenTokArgumentException(string.Format("Location {0} is not a valid IP address", location));
            }

            if (archiveMode == ArchiveMode.ALWAYS && mediaMode != MediaMode.ROUTED)
            {
                throw new OpenTokArgumentException("A session with always archive mode must also have the routed media mode.");
            }

            string preference = (mediaMode == MediaMode.RELAYED) ? "enabled" : "disabled";

            var headers = new Dictionary <string, string> {
                { "Content-type", "application/x-www-form-urlencoded" }
            };
            var data = new Dictionary <string, object>
            {
                { "location", location },
                { "p2p.preference", preference },
                { "archiveMode", archiveMode.ToString().ToLower() }
            };

            var response = await Client.Post("session/create", headers, data);

            var xmlDoc = XDocument.Parse(response);

            if (!xmlDoc.Descendants("session_id").Any())
            {
                throw new OpenTokWebException("Session could not be provided. Are ApiKey and ApiSecret correctly set?");
            }

            var sessionId = xmlDoc.Descendants("session_id").First().Value;
            var apiKey    = Convert.ToInt32(xmlDoc.Descendants("partner_id").First().Value);

            return(new Session(sessionId, apiKey, ApiSecret, location, mediaMode, archiveMode));
        }
Esempio n. 5
0
        /// <summary>
        /// Starts archiving an OpenTok session.
        /// <para>
        /// Clients must be actively connected to the OpenTok session for you to successfully start
        /// recording an archive.
        /// </para>
        /// <para>
        /// You can only record one archive at a time for a given session. You can only record
        /// archives of sessions that uses the OpenTok Media Router (sessions with the media mode set
        /// to routed); you cannot archive sessions with the media mode set to relayed.
        /// </para>
        /// <para>
        /// Note that you can have the session be automatically archived by setting the archiveMode
        /// parameter of the <see cref="CreateSession"/> method to <see cref="ArchiveMode.ALWAYS"/>.
        /// </para>
        /// </summary>
        /// <param name="sessionId">
        /// The session ID of the OpenTok session to archive.
        /// </param>
        /// <param name="name">
        /// The name of the archive. You can use this name to identify the archive. It is a property
        /// of the Archive object, and it is a property of archive-related events in the OpenTok client
        /// libraries.
        /// </param>
        /// <param name="hasVideo">
        /// Whether the archive will record video (true) or not (false). The default value is true
        /// (video is recorded). If you set both <paramref name="hasAudio"/> and <paramref name="hasVideo"/>
        /// to false, the call to the <see cref="StartArchive"/> method results in an error.
        /// </param>
        /// <param name="hasAudio">
        /// Whether the archive will record audio (true) or not (false). The default value is true
        /// (audio is recorded). If you set both <paramref name="hasAudio"/> and <paramref name="hasVideo"/>
        /// to false, the call to the <see cref="StartArchive"/> method results in an error.
        /// </param>
        /// <param name="outputMode">
        /// Whether all streams in the archive are recorded to a single file (<see cref="OutputMode.COMPOSED"/>,
        /// the default) or to individual files (<see cref="OutputMode.INDIVIDUAL"/>).
        /// </param>
        /// <param name="resolution">
        /// The resolution for the archive. The default for <see cref="OutputMode.COMPOSED"/> is "640x480".
        /// You cannot specify the resolution for <see cref="OutputMode.INDIVIDUAL"/>.
        /// </param>
        /// <param name="layout">
        /// The layout that you want to use for your archive. If type is set to <see cref="LayoutType.custom"/>
        /// you must provide a StyleSheet string to Vonage how to layout your archive.
        /// </param>
        /// <returns>
        /// The Archive object. This object includes properties defining the archive, including the archive ID.
        /// </returns>
        public Archive StartArchive(string sessionId, string name = "", bool hasVideo = true, bool hasAudio = true, OutputMode outputMode = OutputMode.COMPOSED, string resolution = null, ArchiveLayout layout = null)
        {
            if (String.IsNullOrEmpty(sessionId))
            {
                throw new OpenTokArgumentException("Session not valid");
            }
            string url     = string.Format("v2/project/{0}/archive", this.ApiKey);
            var    headers = new Dictionary <string, string> {
                { "Content-type", "application/json" }
            };
            var data = new Dictionary <string, object>()
            {
                { "sessionId", sessionId }, { "name", name }, { "hasVideo", hasVideo }, { "hasAudio", hasAudio }, { "outputMode", outputMode.ToString().ToLowerInvariant() }
            };

            if (!String.IsNullOrEmpty(resolution) && outputMode.Equals(OutputMode.INDIVIDUAL))
            {
                throw new OpenTokArgumentException("Resolution can't be specified for Individual Archives");
            }
            else if (!String.IsNullOrEmpty(resolution) && outputMode.Equals(OutputMode.COMPOSED))
            {
                data.Add("resolution", resolution);
            }
            if (layout != null)
            {
                if (layout?.Type == LayoutType.custom && string.IsNullOrEmpty(layout?.StyleSheet) ||
                    layout?.Type != LayoutType.custom && !string.IsNullOrEmpty(layout?.StyleSheet))
                {
                    throw new OpenTokArgumentException("Could not set layout, stylesheet must be set if and only if type is custom");
                }
                data.Add("layout", layout);
            }

            string response = Client.Post(url, headers, data);

            return(OpenTokUtils.GenerateArchive(response, ApiKey, ApiSecret, OpenTokServer));
        }
Esempio n. 6
0
        /**
         * Use this method to start a live streaming for an OpenTok session.
         * This broadcasts the session to an HLS (HTTP live streaming) or to RTMP streams.
         * <p>
         * To successfully start broadcasting a session, at least one client must be connected to the session.
         * <p>
         * You can only have one active live streaming broadcast at a time for a session
         * (however, having more than one would not be useful).
         * The live streaming broadcast can target one HLS endpoint and up to five RTMP servers simulteneously for a session.
         * You can only start live streaming for sessions that use the OpenTok Media Router (with the media mode set to routed);
         * you cannot use live streaming with sessions that have the media mode set to relayed OpenTok Media Router. See
         * <a href="https://tokbox.com/developer/guides/create-session/#media-mode">The OpenTok Media Router and media modes.</a>
         * <p>
         * For more information on broadcasting, see the
         * <a href="https://tokbox.com/developer/guides/broadcast/">Broadcast developer guide.</a>
         *
         * @param sessionId The session ID corresponding to the session.
         *
         * @param properties This BroadcastProperties object defines options for the broadcast.
         *
         * @return The Broadcast object. This object includes properties defining the archive, including the archive ID.
         */
        public Broadcast StartBroadcast(string sessionId, Boolean hls = true, List <Rtmp> rtmpList = null, string resolution = null, int maxDuration = 7200, BroadcastLayout layout = null)
        {
            if (String.IsNullOrEmpty(sessionId))
            {
                throw new OpenTokArgumentException("Session not valid");
            }

            if (!String.IsNullOrEmpty(resolution) && resolution != "640x480" && resolution != "1280x720")
            {
                throw new OpenTokArgumentException("Resolution value must be either 640x480 (SD) or 1280x720 (HD).");
            }

            if (maxDuration < 60 || maxDuration > 36000)
            {
                throw new OpenTokArgumentException("MaxDuration value must be between 60 and 36000 (inclusive).");
            }

            if (rtmpList != null && rtmpList.Count() >= 5)
            {
                throw new OpenTokArgumentException("Cannot add more than 5 RTMP properties");
            }

            string url     = string.Format("v2/project/{0}/broadcast", this.ApiKey);
            var    headers = new Dictionary <string, string> {
                { "Content-type", "application/json" }
            };
            var outputs = new Dictionary <string, object>();

            if (hls)
            {
                outputs.Add("hls", new Object());
            }

            if (rtmpList != null)
            {
                outputs.Add("rtmp", rtmpList);
            }

            var data = new Dictionary <string, object>()
            {
                { "sessionId", sessionId },
                { "maxDuration", maxDuration },
                { "outputs", outputs }
            };

            if (!String.IsNullOrEmpty(resolution))
            {
                data.Add("resolution", resolution);
            }

            if (layout != null)
            {
                if ((layout.Type.Equals(BroadcastLayout.LayoutType.Custom) && String.IsNullOrEmpty(layout.Stylesheet)) ||
                    (!layout.Type.Equals(BroadcastLayout.LayoutType.Custom) && !String.IsNullOrEmpty(layout.Stylesheet)))
                {
                    throw new OpenTokArgumentException("Could not set the layout. Either an invalid JSON or an invalid layout options.");
                }
                else
                {
                    if (layout.Type.Equals(BroadcastLayout.LayoutType.Custom))
                    {
                        data.Add("layout", layout);
                    }
                    else
                    {
                        data.Add("layout", new { type = OpenTokUtils.convertToCamelCase(layout.Type.ToString()) });
                    }
                }
            }

            string response = Client.Post(url, headers, data);

            return(OpenTokUtils.GenerateBroadcast(response, ApiKey, ApiSecret, OpenTokServer));
        }
Esempio n. 7
0
        public MainModule(OpenTokService opentokService)
        {
            Get["/"] = _ => View["index"];

            Get["/host"] = _ =>
            {
                dynamic locals = new ExpandoObject();

                locals.ApiKey             = opentokService.OpenTok.ApiKey.ToString();
                locals.SessionId          = opentokService.Session.Id;
                locals.Token              = opentokService.Session.GenerateToken(Role.PUBLISHER, 0, null, new List <string> (new string[] { "focus" }));
                locals.InitialBroadcastId = opentokService.broadcastId;
                locals.FocusStreamId      = opentokService.focusStreamId;
                locals.InitialLayout      = OpenTokUtils.convertToCamelCase(opentokService.layout.ToString());

                return(View["host", locals]);
            };

            Get["/participant"] = _ =>
            {
                dynamic locals = new ExpandoObject();

                locals.ApiKey        = opentokService.OpenTok.ApiKey.ToString();
                locals.SessionId     = opentokService.Session.Id;
                locals.Token         = opentokService.Session.GenerateToken();
                locals.FocusStreamId = opentokService.focusStreamId;
                locals.Layout        = OpenTokUtils.convertToCamelCase(opentokService.layout.ToString());

                return(View["participant", locals]);
            };

            Post["/start"] = _ =>
            {
                bool            horizontal  = Request.Form["layout"] == "horizontalPresentation";
                BroadcastLayout layoutType  = new BroadcastLayout(horizontal ? BroadcastLayout.LayoutType.HorizontalPresentation : BroadcastLayout.LayoutType.VerticalPresentation);
                int             maxDuration = 7200;
                if (Request.Form["maxDuration"] != null)
                {
                    maxDuration = int.Parse(Request.Form["maxDuration"]);
                }
                Broadcast broadcast = opentokService.OpenTok.StartBroadcast(
                    opentokService.Session.Id,
                    hls: true,
                    rtmpList: null,
                    resolution: Request.Form["resolution"],
                    maxDuration: maxDuration,
                    layout: layoutType
                    );
                opentokService.broadcastId = broadcast.Id.ToString();
                return(broadcast);
            };

            Get["/stop/{id}"] = parameters =>
            {
                Broadcast broadcast = opentokService.OpenTok.StopBroadcast(parameters.id);
                opentokService.broadcastId = "";
                return(broadcast);
            };

            Get["/broadcast"] = _ =>
            {
                if (!String.IsNullOrEmpty(opentokService.broadcastId))
                {
                    try
                    {
                        Broadcast broadcast = opentokService.OpenTok.GetBroadcast(opentokService.broadcastId);
                        if (broadcast.Status == Broadcast.BroadcastStatus.STARTED)
                        {
                            return(Response.AsRedirect(broadcast.Hls));
                        }
                        else
                        {
                            return(Response.AsText("Broadcast not in progress."));
                        }
                    }
                    catch (Exception ex)
                    {
                        return(Response.AsText("Could not get broadcast " + opentokService.broadcastId + ". Exception Message: " + ex.Message));
                    }
                }
                else
                {
                    return(Response.AsText("There's no broadcast running right now."));
                }
            };

            Get["/broadcast/{id}/layout/{layout}"] = parameters =>
            {
                bool            horizontal = parameters.layout == "horizontalPresentation";
                BroadcastLayout layout     = new BroadcastLayout(horizontal ? BroadcastLayout.LayoutType.HorizontalPresentation : BroadcastLayout.LayoutType.VerticalPresentation);
                opentokService.OpenTok.SetBroadcastLayout(parameters.id, layout);
                return(HttpStatusCode.OK);
            };

            Post["/focus"] = _ =>
            {
                string focusStreamId = Request.Form["focus"];
                opentokService.focusStreamId = focusStreamId;
                StreamList streamList = opentokService.OpenTok.ListStreams(opentokService.Session.Id);
                List <StreamProperties> streamPropertiesList = new List <StreamProperties>();
                foreach (Stream stream in streamList)
                {
                    StreamProperties streamProperties = new StreamProperties(stream.Id, null);
                    if (focusStreamId.Equals(stream.Id))
                    {
                        streamProperties.addLayoutClass("focus");
                    }
                    streamPropertiesList.Add(streamProperties);
                }
                opentokService.OpenTok.SetStreamClassLists(opentokService.Session.Id, streamPropertiesList);
                return(HttpStatusCode.OK);
            };
        }