General Customization
There are a number of adjustments you can make to customize the Vonage Video user interface:
Adding a name for a published stream
When you create a Publisher, you can (optionally) specify a name to be displayed in the video:
// Replace the first parameter with the target element ID:
var publisher = OT.initPublisher("myPublisher",
{name: "John"})
session.publish(publisher);
You can use this name to identify the client.
Note that you can also add metadata about the client when you create a token. This name is not automatically displayed in the video. However, by adding the data when you create a token, you can add information more securely (since tokens are created on the server, not on the client. For more information, see Token creation.
Clients can choose to hide the name in a Publisher or Subscriber view. See this section
You can specify the name of the publisher by calling the name() method of the Publisher.Builder object when you instantiate the Publisher object:
mPublisher = new Publisher.Builder(context)
.name("Bob's video")
.build();
You can use this name to identify the client publishing the stream. The Stream class has a name property. When you subscribe to a stream, you can display this name in a user interface element.
To specify the name property of the published stream, set the name property of the OTPublisherSettings object you use when initializing a Publisher:
let publisherSettings = OTPublisherSettings()
publisherSettings.name = "Juan"
let publisher = OTPublisher(delegate: self, settings: publisherSettings)
The OTStream class has a name property. When you subscribe to a stream, you can display this name in a user interface element. (Also, this name is displayed when the video in a web page that uses the OpenTok.js library.)
To specify the name property of the published stream, set the name property of the OTPublisherSettings object you use when initializing a Publisher:
OTPublisherSettings *_publisherSettings = [[OTPublisherSettings alloc] init];
_publisherSettings.name = @"Juan";
_publisher = [[OTPublisher alloc]
initWithDelegate:self
settings:_publisherSettings];
The OTStream class has a name property. When you subscribe to a stream, you can display this name in a user interface element. (Also, this name is displayed when the video in a web page that uses the OpenTok.js library.)
You can specify the name of the publisher by calling the name() method of the Publisher.Builder object when you instantiate the Publisher object:
publisher = new Publisher(Context.Instance,
renderer: publisherVideoRenderer,
name: "Bob's video",
capturer: capturer);
You can use this name to identify the client publishing the stream. The Stream class has a Name property. When you subscribe to a stream, you can display this name in a user interface element.
Adding a mute button for a publisher
By default, the user interface for a Publisher or a Subscriber includes a mute audio button. For a Publisher, the user can click to toggle the mic on and off.
When you publish a stream, you can specify whether the mute button is displayed by passing a style.buttonDisplayMode property into the OT.initPublisher() method:
const publisher = OT.initPublisher(
'publisher-element-id', // Replace with the replacement element ID
{
name: 'John',
style: {buttonDisplayMode: 'on'}
}
);
session.publish(publisher);
The style.buttonDisplayMode property can be set to one of three values:
- "auto" — The mute button is displayed when the stream is first displayed and when the user mouses over the video (the default).
- "off" — The mute button is not displayed.
- "on" — The mute button is displayed.
Once you have created the Publisher, you can change the mute button display mode, by calling the setStyle() method of the Publisher object. See the documentation for Publisher.setStyle().
There is no default user interface element to mute the publisher's microphone. However, you can add an element, such as a button, that calls the setPublishAudio() method of the PublisherKit object when the user clicks it. Pass in false to mute the publisher:
mPublisher.setPublishAudio(false);
Pass in true to publish audio.
mPublisher.setPublishAudio(true);
There is no default user interface element to mute the publisher's microphone. However, you can add an element, such as a button, that sets the publishAudio property of the OTPublisher object when the user clicks it. Set the publishAudio property to false to mute the publisher:
publisher.publishAudio = false
Set the publishAudio property to true to publish audio.
publisher.publishAudio = true
There is no default user interface element to mute the publisher's microphone. However, you can add an element, such as a button, that sets the publishAudio property of the OTPublisher object when the user clicks it. Set the publishAudio property to NO to mute the publisher:
publisher.publishAudio = NO;
Set the publishAudio property to YES to publish audio.
publisher.publishAudio = YES;
There is no default user interface element to mute the publisher's microphone. However, you can add an element, such as a button, that sets the PublishAudio of the Publisher object when the user clicks it. Set the property to false to mute the publisher:
publisher.PublishAudio = false;
Set the property to true to publish audio.
publisher.PublishAudio = true;
Adding a mute button for a subscriber
By default, the user interface for a Publisher or a Subscriber includes a mute audio button. For a Subscriber, the user can click to toggle the speaker on and off.
When you subscribe to a stream, you can specify whether the mute speaker is displayed by passing a style.buttonDisplayMode property into the Session.subscribe() method:
const subscriber = session.subscribe(stream,
'subscriber-element-id', // Replace with the replacement element ID
{
style: {buttonDisplayMode: 'on'}
}
);
The style.buttonDisplayMode property can be set to one of three values:
- "auto" — The mute button is displayed when the stream is first displayed and when the user mouses over the video (the default).
- "off" — The mute button is not displayed.
- "on" — The mute button is displayed.
Once you have created the Subscriber, you can change the mute button display mode, by calling the setStyle() method of the Subscriber object. See the documentation for Subscriber.setStyle().
There is no default user interface element to mute the subscriber's audio. However, you can add an element, such as a button, that calls the setSubscribeToAudio() method of the SubscriberKit object when the user clicks it. Pass in false to mute the subscriber
mSubscriber.setSubscribeToAudio(false);
Pass in true to subscribe to audio (if there is an audio stream):
mSubscriber.setSubscribeToAudio(true);
There is no default user interface element to mute the subscriber's audio. However, you can add an element, such as a button, that sets the subscribeToAudio of the OTSubscriber object when the user clicks it. Set the subscribeToAudio property to false to mute the subscriber
subscriber.subscribeToAudio = false
Set the subscribeToAudio property to true to subscribe to audio (if there is an audio stream):
subscriber.subscribeToAudio = true
There is no default user interface element to mute the subscriber's audio. However, you can add an element, such as a button, that sets the subscribeToAudio of the OTSubscriber object when the user clicks it. Set the subscribeToAudio property to NO to mute the subscriber
subscriber.subscribeToAudio = NO;
Set the subscribeToAudio property to YES to subscribe to audio (if there is an audio stream):
subscriber.subscribeToAudio = YES;
There is no default user interface element to mute the subscriber's audio. However, you can add an element, such as a button, that sets the SubscribeToAudio of the Subscriber object when the user clicks it. Set the property to false to mute the audio:
subscriber.SubscribeToAudio = false;
Set the property to true to enable audio playback (if the stream has audio):
subscriber.SubscribeToAudio = true;
Adding a button to toggle the publisher's camera
There is no default user interface element to toggle the camera used by the publisher. However, you can add and element, such as a button, that calls the swapCamera method of the Publisher object:
mPublisher.swapCamera();
Note that the cameraPosition property is not available in the PublisherKit class. If you are using the PublisherKit class to implement a custom video capturer, you can define the camera used in the custom video capturing code.
There is no default user interface element to toggle the camera used by the publisher. However, you can add an element, such as a button, that sets the cameraPosition property the OTPublisher object. Set the property to a value defined in the AVCaptureDevicePosition enum. For example, the following code sets the publisher to use the back camera:
publisher.cameraPosition = .back
Note that the cameraPosition property is not available in the OTPublisherKit class. If you are using the OTPublisherKit class to implement a custom video capturer, you can define the camera used in the custom video capturing code.
There is no default user interface element to toggle the camera used by the publisher. However, you can add an element, such as a button, that sets the cameraPosition property the OTPublisher object. Set the property to a value defined in the AVCaptureDevicePosition enum. For example, the following code sets the publisher to use the back camera:
publisher.cameraPosition = AVCaptureDevicePositionBack;
Note that the cameraPosition property is not available in the OTPublisherKit class. If you are using the OTPublisherKit class to implement a custom video capturer, you can define the camera used in the custom video capturing code.
There is no default user interface element to toggle the camera used by the publisher. However, you can add and element, such as a button, that sets the VideoCapturer property of the Publisher object:
publisher.VideoCapturer = newCapturer;
For more information, see Using a custom video capturer.
Adjusting user interface when video is enabled or disabled
A Subscriber objects dispatches the following events related to the video being enabled or disabled for the subscriber's stream:
videoEnabled— Dispatched when the video has been enabled after it was previously disabled.videoDisabled— Dispatched when the video has been disabled. The reason property of the event object indicates why the video was disabled. (This event object is an VideoEnabledChangedEvent object.)videoDisableWarning— Dispatched when the Media Router determines that the stream quality has degraded and the video will be disabled if the quality degrades more. If the quality degrades further, the Subscriber disables the video and dispatches avideoDisabledevent.videoDisableWarningLifted— The video has been enabled after it was previously disabled.
The videoDisableWarning and videoDisableWarningLifted events are only available in sessions that use the Media Router (sessions with the media mode set to routed).
By default, the Subscriber displays a video disabled warning indicator and a video disabled indicator when the videoDisableWarning and videoDisableWarningLifted events are dispatched. You can disable the default display of the indicator by setting the videoDisabledDisplayMode style setting of the Subscriber object.
The following example uses the videoDisabledDisplayMode style setting to have the video disabled warning indicator and a video disabled indicator blink every one second when the videoDisableWarning and videoDisableWarningLifted events are dispatched:
var indicatorBlinker = new IndicatorBlinker(subscriber);
var IndicatorBlinker = function(subscriber) {
var timer;
var indicatorOn = false;
subscriber.on({
videoDisabled: function(event) {
start();
},
videoDisableWarning: function(event) {
start();
},
videoDisableWarningLifted: function(event) {
stop();
},
videoEnabled: function(event) {
stop();
}
});
var start = function() {
subscriber.setStyle('videoDisabledDisplayMode', 'on');
if (timer) {
clearInterval(timer);
}
timer = setInterval(function() {
if (indicatorOn) {
subscriber.setStyle('videoDisabledDisplayMode', 'off');
} else {
subscriber.setStyle('videoDisabledDisplayMode', 'on');
}
indicatorOn = !indicatorOn;
}, 1000);
indicatorOn = true;
};
var stop = function() {
if (timer) {
clearInterval(timer);
}
};
};
You can also set the videoDisabledDisplayMode style to 'off' and add your own user interface elements based on the videoDisableWarning, videoDisabled, videoDisableWarningLifted, and videoEnabled events.
When a subscriber's video is disabled, the SubscriberKit.VideoListener.onVideoDisabled(subscriber, reason) method is called. When this occurs, you can add a user interface element (such as an icon) to indicate that the video was disabled:
@Override
public void onVideoDisabled(SubscriberKit subscriber, String reason) {
// Display the video disabled indicator
}
When a subscriber's video is reenabled, the SubscriberKit.VideoListener.onVideoEnabled(subscriber, reason) method is called. When this occurs, you may remove a user interface element (such as an icon) that indicate that the video is reenabled:
@Override
public void onVideoEnabled(SubscriberKit subscriber, String reason) {
// Display the video disabled indicator
}
In sessions that use the Vonage Video Media Router (sessions with the media mode set to routed), the SubscriberKit.VideoListener may also call the following methods:
- onVideoDisableWarning(subscriber) — The Vonage Video Media Router has determined that the stream quality has degraded and the video will be disabled if the quality degrades further.
- onVideoDisableWarningLifted(subscriber) — The Vonage Video Media Router has determined that the stream quality has improved to the point at which the video being disabled is not an immediate risk.
You may also want to display and remove a user interface notification (such as an icon) when these messages are sent.
Note that when you publish a stream, you can prevent it from having its video disabled due to stream quality. Before you publish the stream (by calling the Session.publish(publisher) method), call the setAudioFallbackEnabled(boolean enabled) method of the Publisher object (or PublisherKit object) and pass in false.
When a subscriber's video is disabled, the OTSubscriberKitDelegate subscriberVideoDisabled(_:reason:) message is sent. When this occurs, you can add a user interface element (such as an icon) to indicate that the video was disabled:
func subscriberVideoDisabled(_ subscriber: OTSubscriberKit, reason: OTSubscriberVideoEventReason) {
// Display the video disabled indicator
}
When a subscriber's video is reenabled, the OTSubscriberKitDelegate subscriberVideoEnabled(_:reason:) message is sent. When this occurs, you may remove a user interface element (such as an icon) that indicate that the video is reenabled:
func subscriberVideoEnabled(_ subscriber: OTSubscriberKit, reason: OTSubscriberVideoEventReason) {
// Remove the video disabled indicator
}
In sessions that use the Vonage Video Media Router (sessions with the media mode set to routed), the following messages can also be sent:
- OTSubscriberKitDelegate subscriberVideoDisableWarning(_:) — The Vonage Video Media Router has determined that the stream quality has degraded and the video will be disabled if the quality degrades further.
- OTSubscriberKitDelegate subscriberVideoDisableWarningLifted(_:)] — The Vonage Video Media Router has determined that the stream quality has improved to the point at which the video being disabled is not an immediate risk.
You may also want to display and remove a user interface notification (such as an icon) when these messages are sent.
Note that when you publish a stream, you can prevent it from having its video disabled due to stream quality. Before you publish the stream (by calling the OTSession publish(_:error:) method), set the audioFallbackEnabled property of the Publisher object (or PublisherKit object) to false.
When a subscriber's video is disabled, the [OTSubscriberKitDelegate subscriberVideoDisabled:reason:] message is sent. When this occurs, you can add a user interface element (such as an icon) to indicate that the video was disabled:
- (void)subscriberVideoDisabled:(OTSubscriberKit*)subscriber
reason:(OTSubscriberVideoEventReason)reason
{
// Display the video disabled indicator
}
When a subscriber's video is reenabled, the [OTSubscriberKitDelegate subscriberVideoEnabled:reason:] message is sent. When this occurs, you may remove a user interface element (such as an icon) that indicate that the video is reenabled:
- (void)subscriberVideoEnabled:(OTSubscriberKit*)subscriber
reason:(OTSubscriberVideoEventReason)reason
{
// Remove the video disabled indicator
}
In sessions that use the Vonage Video Media Router (sessions with the media mode set to routed), the following messages can also be sent:
- [OTSubscriberKitDelegate subscriberVideoDisableWarning:] — The Vonage Video Media Router has determined that the stream quality has degraded and the video will be disabled if the quality degrades further.
- [OTSubscriberKitDelegate subscriberVideoDisableWarningLifted:] — The Vonage Video Media Router has determined that the stream quality has improved to the point at which the video being disabled is not an immediate risk.
You may also want to display and remove a user interface notification (such as an icon) when these messages are sent.
Note that when you publish a stream, you can prevent it from having its video disabled due to stream quality. Before you publish the stream (by calling the [OTSession publish:error] method), set the audioFallbackEnabled property of the Publisher object (or PublisherKit object) to NO.
When a subscriber's video is disabled, the Subscriber object sends a VideoDisabled event. When this occurs, you can add a user interface element (such as an icon) to indicate that the video was disabled:
subscriber.VideoDisabled += Subscriber_VideoDisabled;
private void Subscriber_VideoDisabled(object sender, EventArgs e) {
// Display the video disabled indicator
}
When a subscriber's video is reenabled, the Subscriber object sends a VideoEnabled event. When this occurs, you may remove a user interface element (such as an icon) that indicate that the video is reenabled:
subscriber.VideoEnabled += Subscriber_VideoEnabled;
private void Subscriber_VideoEnabled(object sender, EventArgs e) {
// Display the video disabled indicator
}
In sessions that use the Vonage Video Media Router (sessions with the media mode set to routed), the Subscribe may also send the following events:
VideoDisableWarning— The Vonage Video Media Router has determined that the stream quality has degraded and the video will be disabled if the quality degrades further.VideoDisableWarningLifted— The Vonage Video Media Router has determined that the stream quality has improved to the point at which the video being disabled is not an immediate risk.
You may also want to display and remove a user interface notification (such as an icon) when these events are sent.
Displaying an indicator element when a session is being archived
When a archive of a session starts recording (or if you connect to a session that is being recorded), the Session.ArchiveListener.onArchiveStarted(session, name) method is called. When the recording stops the Session.ArchiveListener.onArchiveStopped(session, name) method is called. You can add a user interface element, such as an icon displayed in a publisher view, to indicate that a video is being recorded:
@Override
public void onArchiveStarted(Session session, String id, String name) {
// Display the archive indicator
}
@Override
public void onArchiveStopped(Session session, String id, String name) {
// Hide the archive indicator
}
When a archive of a session starts recording (or if you connect to a session that is being recorded), the OTSessionDelegate session(_:archiveStartedWithId:name:) message is sent. When the recording stops the OTSessionDelegate session(_:archiveStoppedWithId:) message is sent. You can add a user interface element, such as an icon displayed in a OTPublisher view, to indicate that a video is being recorded:
func session(_ session: OTSession, archiveStartedWithId archiveId: String, name: String?) {
// Display the archive indicator
}
func session(_ session: OTSession, archiveStoppedWithId archiveId: String) {
// Hide the archive indicator
}
When a archive of a session starts recording (or if you connect to a session that is being recorded), the [OTSessionDelegate session:archiveStartedWithId:name:] message is sent. When the recording stops the [OTSessionDelegate session:archiveStoppedWithId:] message is sent. You can add a user interface element, such as an icon displayed in a OTPublisher view, to indicate that a video is being recorded:
- (void) session:(OTSession*)session
archiveStartedWithId:(NSString*)archiveId
name:(NSString*)name
{
// Display the archive indicator
}
- (void) session:(OTSession*)session
archiveStoppedWithId:(NSString*)archiveId
{
// Hide the archive indicator
}
When a archive of a session starts recording (or if you connect to a session that is being recorded), the Session object sends an ArchiveStarted event. When the recording stops the Session object sends an ArchiveStopped event. You can add a user interface element, such as an icon displayed in a publisher view, to indicate that a video is being recorded:
session.ArchiveStarted += Session_ArchiveStarted;
session.ArchiveStopped += Session_ArchiveStopped;
private void Session_ArchiveStarted(object sender, EventArgs e) {
// Display the archive indicator
}
private void Session_ArchiveStopped(object sender, EventArgs e) {
// Hide the archive indicator
}
Adjusting user interface based on audio levels
Publisher and Subscriber objects dispatch audioLevelUpdated events periodically to report the audio level. You can use these events to display an audio level indicator. You can also use these events to detect active speakers in a session.
The following example adjusts the value of a meter element that shows volume of a subscriber. The code sets the audioLevelDisplayMode style to 'off', which disables the default audio level meter displayed in the Subscriber. Note that the audio level is adjusted logarithmically and a moving average is applied:
subscriber.setStyle('audioLevelDisplayMode', 'off');
var movingAvg = null;
subscriber.on('audioLevelUpdated', function(event) {
if (movingAvg === null || movingAvg <= event.audioLevel) {
movingAvg = event.audioLevel;
} else {
movingAvg = 0.7 * movingAvg + 0.3 * event.audioLevel;
}
// 1.5 scaling to map the -30 - 0 dBm range to [0,1]
var logLevel = (Math.log(movingAvg) / Math.LN10) / 1.5 + 1;
logLevel = Math.min(Math.max(logLevel, 0), 1);
document.getElementById('subscriberMeter').value = logLevel;
});
The example assumes that there is an HTML meter element with the ID "subscriberMeter".
Note that in audio-only mode, a Publisher or Subscriber DOM element displays a volume indicator by default (in the upper right-hand corner of the element). You can disable this default user interface element and display your own volume meter. See the next topic, Adjusting user interface when video is enabled or disabled.
You can also use the audioLevelUpdated event to determine when a publisher or subscriber's audio is loud enough for long enough to label the participant as having started talking. Or, if the audio has been quiet for long enough, you can identify the participant as having stopped talking:
var subscriber = session.subscribe(event.stream);
SpeakerDetection(subscriber, function() {
console.log('started talking');
}, function() {
console.log('stopped talking');
});
var SpeakerDetection = function(subscriber, startTalking, stopTalking) {
var activity = null;
subscriber.on('audioLevelUpdated', function(event) {
var now = Date.now();
if (event.audioLevel > 0.2) {
if (!activity) {
activity = {timestamp: now, talking: false};
} else if (activity.talking) {
activity.timestamp = now;
} else if (now- activity.timestamp > 1000) {
// detected audio activity for more than 1s
// for the first time.
activity.talking = true;
if (typeof(startTalking) === 'function') {
startTalking();
}
}
} else if (activity && now - activity.timestamp > 3000) {
// detected low audio activity for more than 3s
if (activity.talking) {
if (typeof(stopTalking) === 'function') {
stopTalking();
}
}
activity = null;
}
});
};
(Instead of logging to the console, your app could adjust a user interface element when the user starts and stops talking.
The SubscriberKit.AudioLevelListener.onAudioLevelUpdated(subscriber, audioLevel) and PublisherKit.AudioLevelListener.onAudioLevelUpdated(publisher, audioLevel) messages are sent on a regular interval with the audio level of the subscriber and publisher. You can use the audioLevel value to update the display in an audio level meter:
@Override
public void onAudioLevelUpdated(
SubscriberKit subscriber, float audioLevel) {
// Adjust an audio meter UI element based on the audioLevel value.
}
By default, for privacy reasons, when all publishers are muted audio capture stops and the microphone is released. This means there won't be more audio level updates until a publisher instance enables audio again. From version 2.31.0 onwards the publisher is enabled with a property to allow audio capture to continue while muted.
When instantiating a new publisher instance the developer can enable this behaviour:
mPublisher = new Publisher.Builder(this).name(mUsername).allowAudioCaptureWhileMuted(true).build();
Note: By enabling this behaviour the microphone will be used even when the publisher is muted.
The OTPublisherKitAudioLevelDelegate publisher(_:audioLevelUpdated:) and OTSubscriberKitAudioLevelDelegate subscriber(_:audioLevelUpdated:) messages are sent on a regular interval with the audio level of the subscriber and publisher. You can use the audioLevel value to update the display in an audio level meter.
By default, for privacy reasons, when all publishers are muted audio capture stops and the microphone is released. This means there won't be more audio level updates until a publisher instance enables audio again. From version 2.31.0 onwards the publisher is enabled with a property to allow audio capture to continue while muted.
When instantiating a new publisher instance the developer can enable this behaviour:
let settings = OTPublisherSettings()
settings.allowAudioCaptureWhileMuted = true;
publisher = OTPublisher(delegate: self, settings: settings)!
Note: By enabling this behaviour the microphone will be used even when the publisher is muted.
The [OTPublisherKitAudioLevelDelegate publisher:audioLevelUpdated:] and [OTSubscriberKitAudioLevelDelegate subscriber:audioLevelUpdated:] messages are sent on a regular interval with the audio level of the subscriber and publisher. You can use the audioLevel value to update the display in an audio level meter.
By default, for privacy reasons, when all publishers are muted audio capture stops and the microphone is released. This means there won't be more audio level updates until a publisher instance enables audio again. From version 2.31.0 onwards the publisher is enabled with a property to allow audio capture to continue while muted.
When instantiating a new publisher instance the developer can enable this behaviour:
OTPublisherKitSettings* settings = [[OTPublisherKitSettings alloc] init];
settings.allowAudioCaptureWhileMuted = true;
_publisher = [[OTPublisherKit alloc] initWithDelegate:self settings:settings];
Note: By enabling this behaviour the microphone will be used even when the publisher is muted.
The Subscriber.AudioLevel and Publisher.AudioLevel events are sent on a regular interval with the audio level of the subscriber and publisher. You can use the AudioLevel property of the event arguments to update the display in an audio level meter:
@Override
publisher.AudioLevel += Publisher_AudioLevel;
subscriber.AudioLevel += Subscriber_AudioLevel;
private void Publisher_AudioLevel(object sender, EventArgs e) {
// Display the audio level based on e.AudioLevel
}
private void Subscriber_AudioLevel(object sender, EventArgs e) {
// Display the audio level based on e.AudioLevel
}
By default, for privacy reasons, when all publishers are muted audio capture stops and the microphone is released. This means there won't be more audio level updates until a publisher instance enables audio again. From version 2.31.0 onwards the publisher is enabled with a property to allow audio capture to continue while muted.
When instantiating a new publisher instance the developer can enable this behaviour:
publisher = new Publisher.Builder(_context)
{
AllowAudioCaptureWhileMuted = true
}.Build();
Note: By enabling this behaviour the microphone will be used even when the publisher is muted.
Using a custom video renderer
The Subscriber and Publisher classes implement a standard video renderer that renders the stream and provides user interface controls for displaying the stream name and muting the microphone or camera. You can use the SubscriberKit and PublisherKit classes to implement a custom video renderer.
The Android SDK includes a BaseVideoRenderer class. Override this class to create a custom video renderer.
After instantiating a PublisherKit object, you can set a custom video renderer by calling the setRenderer() method of the PublisherKit object:
mPublisher = new PublisherKit(MyClass.this, "publisher");
// Use a custom video renderer.
// MyVideoRenderer extends BaseVideoRenderer
mRenderer = new MyVideoRenderer();
mPublisher.setRenderer(new mRenderer);
The SubscriberKit class also has a setRenderer() method.
The onFrame() method of the BaseVideoRenderer class is called when a new frame is available:
public void onFrame(Frame frame) {
// The new frame is available.
}
The frame is a BaseVideoRenderer.Frame object. This object includes a getBuffer() that returns the byte buffer containing the video frame data. You can use this byte buffer to add the video frame image to the publisher's view.
For an example, see the OpenTokVideoRenderer class in the OpenTokHelloWorld sample application.
You can also set up a publisher to use a custom video capturer.
The OTPublisher and OTSubscriber classes provide a default UIView instance that renders the publisher or subscriber video. You can use the custom video stream API to define a custom video renderer, using OTPublisherKit, OTSubscriberKit, and OTVideoRender classes.
You can also set up a publisher to use a custom video capturer.
The OTPublisher and OTSubscriber classes provide a default UIView instance that renders the publisher or subscriber video. You can use the custom video stream API to define a custom video renderer, using OTPublisherKit, OTSubscriberKit, and OTVideoRender classes.
You can also set up a publisher to use a custom video capturer.
By default, publishers use a default video renderer for Windows Presentation Foundation, which is defined by the Vonage Video Windows SDK.
You can also specify a renderer for the video by creating a class that implements the IVideoRenderer interface. The interface includes a RenderFrame(frame) method which is called when a new video frame is available. In your implementation of this method, use the frame object passed into the method to create an image to render. Also, at the end of your implementation of this method, be sure to call the Dispose() method of the frame object, to prevent memory leaks.
When you instantiate a Publisher or Subscriber object, you can pass the custom video renderer object into the Publisher() or Subscriber() constructor (as the renderer parameter).