Subscribing to streams — iOS (Swift)
Once you have connected to a session, you can subscribe to streams in the session. When you subscribe to a stream, you can put its video view in the app.
This topic includes the following sections:
- Detecting streams in a session
- Subscribing to a stream
- Unsubscribing from a stream
- Detecting when streams leave a session
- Detecting when a subscriber's video is disabled
- Getting information about a stream
- Setting the preferred frame rate and resolution
Automatic reconnection
If a client drops a connection to a subscribed stream (for example, due to a drop in network connectivity in either client), it will attempt to automatically reconnect to the stream. When the stream is dropped and the client tries to reconnect, the OTSubscriberDelegate subscriberDidDisconnect(fromStream:) message is sent to the OTSubscriber object's delegate. When the connection is restored, the OTSubscriberDelegate subscriberDidReconnect(toStream:) message is sent. If the client cannot restore the connection, the OTSessionDelegate session(_:streamDestroyed:) message is sent.
In response to these events, your application can (optionally) display user interface notifications indicating the temporary disconnection, reconnection, and disconnection states.
// OTSubscriber delegate callbacks:
func subscriberDidDisconnect(fromStream subscriber: OTSubscriberKit) {
// Display a user interface notification.
}
func subscriberDidReconnect(toStream subscriber: OTSubscriberKit) {
// Adjust user interface.
}
// OTSession delegate callback:
func session(_ session: OTSession, streamDestroyed stream: OTStream) {
// Adjust user interface.
}
Detecting streams in a session
The OTSessionDelegate session(_ session:streamCreated:) message is sent when a new stream is created in a session. (A stream is created when a client publishes a stream to the session.) The OTStream object has properties that define the stream. Compare the connection property of the OTStream object with the connection property of the OTSession object to determine whether the stream is one that your client published:
func session(_ session: OTSession, streamCreated stream: OTStream) {
print("Session streamCreated: \(stream.streamId)")
// See the declaration of subscribeToSelf above.
if stream.connection.connectionId == session.connection.connectionId {
// This is my own stream
} else {
// This is a stream from another client.
}
}
You can subscribe to a stream to display it in your app. See the next section.
Subscribing to a stream
To subscribe to a stream, call the OTSubscriber init(stream:delegate:) method, passing in an OTStream object and a delegate object to receive subscriber-related messages. Then call theOTSession subscribe(_:error:) method to start subscribing to the stream:
func session(_ session: OTSession, streamCreated stream: OTStream) {
subscriber = OTSubscriber(stream: stream, delegate: self)
var error: OTError?
session.subscribe(subscriber!, error: &error)
if error {
print("subscribe failed with error: \(error)")
}
}
The OTSubscriberDelegate subscriberDidConnect(toStream:) message is sent when the app starts receiving the subscriber's stream. At this point, you can add the subscriber's view (represented by the OTSubscriber view property) to the app:
func subscriberDidConnect(toStream subscriber: OTSubscriberKit) {
if let subscriberView = self.subscriber?.view {
subscriberView.frame = CGRect(x: 0, y: 300, width: 400, height: 300)
self.view.addSubview(subscriberView)
}
}
Unsubscribing from a stream
To stop playing a stream you are subscribed to, call the OTSession unsubscribe(_:error:) method:
var error: OTError?
session.unsubscribe(subscriber, error: &error)
if (error) {
print("unsubscribe failed with error: \(error)")
}
The Subscriber is disconnected. Next, remove its view from its superview:
subscriber.view?.removeFromSuperview()
Detecting when streams leave a session
When streams leave a session, the OTSession session(_:streamDestroyed:) message is sent. When a stream is dropped, the view for any OTSubscriber object for the stream is removed from its superview. Check if the stream is not published by your own client, and remove its view from its superview.
func session(_ session: OTSession, streamDestroyed stream: OTStream) {
print("Session streamDestroyed: \(stream.streamId)")
if subscriber?.stream?.streamId == stream.streamId {
subscriber?.view?.removeFromSuperview()
subscriber = nil
}
}
Detecting when a subscriber's video is disabled
The subscriber's delegate sends the OTSubscriberDelegate subscriberVideoDisabled(_:reason:) message when the subscriber's video is disabled:
func subscriberVideoDisabled(_ subscriber: OTSubscriberKit, reason: OTSubscriberVideoEventReason) {
print("subscriber video disabled.")
}
The reason parameter can be set to one of the following constants defined in the OTSubscriberVideoEventReason enum:
OTSubscriberVideoEventPublisherPropertyChanged— The video event was caused by the stream's publisher stopping the video stream.OTSubscriberVideoEventQualityChanged— The video event was caused by a change to the video stream quality. Stream quality may change due to network conditions or CPU usage on either the subscriber or publisher. This reason is only used in sessions that have the media mode set to "routed". (See The OpenTok Media Router and media modes.) This feature of the OpenTok Media Router has a subscriber drop the video stream when the video stream quality degrades, and the message is sent. When conditions improve, the video stream resumes, and theOTSubscriberDelegate subscriberVideoEnabled(_:reason:)message is sent. When the video stream is dropped, the subscriber continues to receive the audio stream, if there is one.OTSubscriberVideoEventSubscriberPropertyChanged— The video event was caused by a change to this subscriber'sOTSubscriber subscribeToVideoproperty.
If the video stream resumes, the OTSubscriberDelegate subscriberVideoEnabled(_:reason:) message is sent.
When you publish a stream, you enable or disable publisher and subscriber audio fallback. The audio fallback feature disables video (in publishers and subscribers) when network or CPU conditions do not support video. See Audio fallback (Web).
Getting information about a stream
The OTStream object has the following properties that define the stream:
connection—The OTConnection object corresponding to the connection that is publishing the stream. You can compare this to theconnectionproperty of the OTSession object to see if the stream is being published by your client.creationTime—The Date timestamp for the creation time of the stream.hasAudio—(Bool) Whether the stream has audio.hasVideo—(Bool) Whether the stream has video.name—(String?) The name of the stream. This is set when you initialize the Publisher of the stream (see Initializing an OTPublisher object).session—(OTSession) The OpenTok session to which the stream is bound.streamId—(String) The unique ID for the stream.videoDimensions—A CGSize object defining the current dimensions of the video media track on this stream.videoType—(OTStreamVideoType) Whether the stream uses a camera video source (OTStreamVideoTypeCamera), a screen-sharing video source (OTStreamVideoTypeScreen), or a custom video source (OTStreamVideoTypeCustom). See Screen sharing.
You can set a OTSubscriberKitNetworkStatsDelegate object for the OTSubscriberKit object to monitor statistics for a subscriber's stream.
Refer to the client observability developer guide for detailed information.
Setting the preferred frame rate and resolution
When subscribing to a stream that uses the scalable video feature, you can set the preferred frame rate and resolution for the stream the subscribing client receives from the OpenTok Media Router. For details, see SubscriberKit.preferredFrameRate and SubscriberKit.preferredResolution.