Subscribing to a stream
In this guide you will learn to subscribe users to a stream within your application.
To subscribe to all streams in the session, add an OTSubscriber object as a chile of the OTSession object:
<OTSession
applicationId="the Application ID"
sessionId="the session ID"
token="the token">
<OTSubscriber/>
</OTSession>
After the client connects to the session, the OTSubscriber object adds views for subscriber videos when other clients streams become available in the session.
The OTSubscriber object dispatches a connected event when a subscriber successfully starts streaming. It dispatches an error event if there is an error subscribing. Set an eventHandlers prop of the OTSubscriber component, and set the connected and error properties of that object to callback functions:
<OTSubscriber
eventHandlers={{
connected: () => {
console.log('The subscriber started streaming.');
},
error: () => {
console.log('The subscriber failed.');
}
}}/>
To subscribe to a stream, pass the Stream object into the subscribe method of the Session object:
session.subscribe(stream, replacementElementId);
The subscribe() method takes the following parameters:
stream—The Stream object.targetElement— (Optional) Defines the DOM element that the Subscriber video replaces.properties— (Optional) A set of properties that customize the appearance of the Subscriber view in the HTML page and select whether to subscribe to audio and video
see Adjusting audio and video.
completionHandler— (Optional) A function that is called asynchronously when the call to thesubscribe()method completes successfully or fails. If the call to thesubscribe()method fails, the completion handler is passed an error object. This object has acodeandmessageproperty that describe the error.
The following code subscribes to all streams, other than those published by your client:
session.on("streamCreated", function(event) {
session.subscribe(event.stream);
});
// Replace with your token:
session.connect(token, function (error) {
if(error) {
// failed to connect
}
});
The insertMode property of the properties parameter of the Session.subscribe() method specifies how the Publisher object will be inserted in the HTML DOM, in relation to the targetElement parameter. You can set this parameter to one of the following values:
"replace"— The Subscriber object replaces contents of the targetElement. This is the default."after"— The Subscriber object is a new element inserted after the targetElement in the HTML DOM. (Both the Subscriber and targetElement have the same parent element.)"before"— The Subscriber object is a new element inserted before the targetElement in the HTML DOM. (Both the Subscriber and targetElement have the same parent element.)"append"— The Subscriber object is a new element added as a child of the targetElement. If there are other child elements, the Publisher is appended as the last child element of the targetElement.
For example, the following code adds a new Subscriber object as a child of a subscriberContainer DOM element:
session.on('streamCreated', function(event) {
var subscriberProperties = {insertMode: 'append'};
var subscriber = session.subscribe(event.stream,
'subscriberContainer',
subscriberProperties,
function (error) {
if (error) {
console.log(error);
} else {
console.log('Subscriber added.');
}
});
});
The Subscriber object has an element property, which is set to the HTML DOM element containing it.
To subscribe to a stream, first instantiate a Subscriber.Builder object by calling the Subscriber.Builder(Context context, Stream stream) constructor. Pass in the Android application context for the Subscriber and the Stream object. Call the build() method to create the Subscriber object. Then call the subscribe() method of the Session object to start subscribing to the stream:
mSubscriber = new Subscriber.Builder(context, stream)
.build();
mSession.subscribe(mSubscriber);
The SubscriberKit.SubscriberListener.onConnected(SubscriberKit subscriber) method is called when the app starts receiving the subscriber's stream. At this point, you can add the subscriber's view (returned by the getView() method of the Subscriber object) as a subview of an android.view.ViewGroup object to display it in the app:
@Override
public void onConnected(subscriber) {
// mViewContainer is an Android View
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
getResources().getDisplayMetrics().widthPixels, getResources()
.getDisplayMetrics().heightPixels);
mViewContainer.addView(mSubscriber.getView(), layoutParams);
}
Unsubscribing from a stream
To stop playing a stream you are subscribed to, call the Session.unsubscribe(Subscriber subscriber) method:
mSession.unsubscribe(mSubscriber);
The Subscriber is disconnected, and its view is removed from its superview.
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()
To subscribe to a stream, call the [OTSubscriber initWithStream:] method, passing in an OTStream object and a delegate object to receive subscriber-related messages. Then call the[OTSession subscribe:error] method to start subscribing to the stream:
- (void)session:(OTSession*)session streamCreated:(OTStream*)stream
{
subscriber = [[OTSubscriber alloc] initWithStream:stream delegate:self];
OTError* error = nil;
[session subscribe:subscriber error:&error]
if (error) {
NSLog(@"subscribe failed with error: (%@)", error);
}
}
The [OTSubscriberDelegate subscriberDidConnectToStream:] 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:
- (void)subscriberDidConnectToStream:(OTSubscriber*)subscriber
{
[subscriber.view setFrame:CGRectMake(0, 300, 400, 300)];
[self.view addSubview:subscriber.view];
}
Unsubscribing from a stream
To stop playing a stream you are subscribed to, call the [OTSession unsubscribe:error:] method:
OTError* error = nil;
[session unsubscribe:_subscriber error:&error]
if (error) {
NSLog(@"unsubscribe failed with error: (%@)", error);
}
The Subscriber is disconnected. Next, remove its view from its superview:
[subscriber.view removeFromSuperview:];
To subscribe to a stream, first instantiate a Subscriber object by calling the Subscriber(context, stream, renderer) constructor. Pass in the Windows application context for the Subscriber, the Stream object, and a video renderer.
The OpenTok.IVideoRenderer interface defines the video renderer. The OpenTok.VideoRenderer class, included in Vonage Video Windows SDK, renders video to an Windows Presentation Framework control. The VideoRenderer object is a subclass of System.Windows.Controls.Control.
You can add this element to your view hierarchy. Or you can create your own custom video renderer that implements the OpenTok.IVideoRenderer interface.
Call the subscribe() method of the Session object to start subscribing to the stream:
VideoRenderer videoRenderer = new VideoRenderer();
// Add the video renderer to the application's view hierarchy.
Subscriber subscriber = new Subscriber(Context.Instance, stream, renderer);
subscriber.Error += Subscriber_Error;
session.subscribe(subscriber);
private void Session_Error(object sender, Subscriber.ErrorEventArgs e)
{
Console.WriteLine("Subscriber error:" + e.ErrorCode);
}
The Subscriber object sends an Error event if there is an error in subscribing to the stream. Check the ErrorCode property of the arguments passed into the event to see details on why subscribing failed. (The OpenTok.ErrorCode enum defines ErrorCode values.)
The Subscriber object sends a Connected event when the app starts receiving the subscriber's stream.
Note: The OpenTok.Subscriber class implements the System.IDisposable interface. Be sure to call the Dispose() method of the Subscriber object to release its resources when you no longer need the object (for example, when the Subscriber stops streaming video or when the app or window is closing).
You can create a custom audio driver to be used by all publishers and subscribers.
Unsubscribing from a stream
To stop playing a stream you are subscribed to, call the Session.Unsubscribe(subscriber) method:
session.unsubscribe(subscriber);
The Subscriber is disconnected, and its view is removed from its superview.
The on_stream_received callback function (see the previous section) includes a stream parameter, which is a pointer to an otc_stream struct representing the new stream. To subscribe to the stream, instantiate a otc_subscriber_callbacks instance, set some callback functions for subscriber-related events, and then call the otc_subscriber_new() function passing in the otc_stream and otc_subscriber_callbacks instances
char *user_data = strdup("Session user data");
static void on_subscriber_connected(otc_subscriber *subscriber,
void *user_data,
const otc_stream *stream) {
// Called when the subscriber connects to the stream.
}
static void on_render_frame(otc_subscriber *subscriber,
void *user_data,
const otc_video_frame *frame) {
// Called when the subscriber is ready to render a new video frame
}
static void on_error(otc_subscriber *subscriber,
void *user_data) {
// Called when there is an error.
}
struct otc_subscriber_callbacks subscriber_callbacks = {0};
subscriber_callbacks.user_data = user_data;
subscriber_callbacks.on_connected = on_subscriber_connected;
subscriber_callbacks.on_render_frame = on_subscriber_render_frame;
subscriber_callbacks.on_error = on_subscriber_error;
otc_subscriber *subscriber = otc_subscriber_new(stream,
&subscriber_callbacks);
if (subscriber == NULL) {
printf("Could not create OpenTok subscriber successfully");
return;
}
if (otc_session_subscribe(session, subscriber) != OTC_SUCCESS) {
printf("Could not subscribe successfully.");
}
Use the user_data member of the otc_subscriber_callbacks structure to set data you may want to reference in the callback functions. In this example, we set it to a pointer to a string object. But it could be a pointer to an instance of some other type that contains meaningful information.
The other members of the otc_subscriber_callbacks structure are each callback functions that are invoked when events related to the subscriber occur:
on_connected— Called when the subscriber connects to the audio-video stream.on_render_frame— Called each time the subscriber is ready to render a new video frame.on_error— Called when a subscriber error occurs.
All callbacks will not be made on the application or main thread but on an internal thread. The application should return the callback as quickly as possible to avoid blocking the internal thread.
See otc_subscriber_callbacks in the Vonage Video Linux SDK reference for details on each of the callback functions.
Unsubscribing from a stream
To stop playing a stream you are subscribed to, call the otc_session_unsubscribe() function, passing in the otc_session and otc_subscriber instances:
if (session.unsubscribe(session, subscriber) == OTC_SUCCESS) {
printf("Unsubscribed from the stream successfully.");
otc_subscriber_delete(subscriber);
} else {
printf("Could not unsubscribe successfully.");
};
Call the otc_subscriber_delete() function to release the subscriber instance, including all hardware and UI resources bound to it.