Release Notes
The most current release version is 2024.4.0
.
Release notes for this version are shown below, followed by notes from prior releases.
To get the Android SDK for a specific version, update the Phenix SDK version in build.gradle file to match the version number,
e.g., 2022.0.3
. Some versions require additional integration steps; these are called out in the version-specific release notes.
v2024.4.0 Release Notes
Release Date: 2024.10.30
Features/Improvements
-
Selective camera autofocus. In this release we're introducing the ability to select a coordinate in the source frame of the camera image where the camera will focus on. This area is called a focus target. This is documented in our examples.
-
New Nielsen ID3 tag helper module. The PhenixSdkNielsen module is used in conjunction with the Nielsen Android SDK for viewership tracking.
-
Decode H264 B-Frames delivered to Android SDK subscribers when possible. Since it has become possible to ingest H264 streams with B-Frames, changes have been made to allow for delivery of B-Frames. When the Android SDK is used to subscribe to streams containing B-Frames, an effort is made to configure the Android HW H264 decoder strategy to render B-Frames.
Enhancements
- Establish a new TURN connection on network change. A new TURN connection is established when switching between different networks. This provides stream and VOD continuity on network changes.
Fixes/Updates
-
Updated internal bitrate control to make sure that the target bitrate is set more consistently when faced with changing network conditions.
-
Increased robustness when resetting a temporary bandwidth limit on a subscriber of a stream.
-
Underlying platform changes relative to this release restore timeshift functionality.
-
Fixed a memory leak in the telemetry support when restarting SDK native Pcast services.
-
Ensure our TcpSocket never calls async_write while a previous async_write is active. Updated documentation for the library we use to interact with our TCP socket indicates that a race condition occurs if concurrent calls to “async_write” are performed. This race condition was fixed which enables the ability to publish using the Android SDK using
reliable-transport
capability. This change addresses the issue with Android publishers that resulted in stalled/abandoned streams when the stream was transported via our TURN server. -
Allow an Android subscriber to modify frames with the frame-ready API before rendering them. The Android Frame Ready API provides frames in the ARGB_8888 pixel format. Prior to this release, when used in the subscriber/viewer workflow, frames returned from the Frame Ready API were not rendering properly. As of this release, the Frame Ready API will be able to render the frames that are returned in the
ARGB_8888
pixel format. -
Fixed audio and video tracks losing synchronization after switching between front and rear camera during an ongoing stream.
Deprecations
None.
v2023.0.0 Release Notes
Release Date: 2024.02.02
Features/Improvements
Setting an authentication token in the SDK triggers re-authentication if the current SDK AuthenticationStatus is unauthenticated. Otherwise, the new authentication token will be used during the next SDK re-authentication attempt.
To support this, there is a new API function for setting an authentication token:
PCastExpress.setAuthenticationToken
To subscribe to authentication status events, subscribe to the AuthenticationStatus observable
through the API:
PCastExpress.getObservableAuthenticationStatus
These are documented in the PCastExpress API.
Enhancements
unrecoverableErrorCallback
It is now mandatory to supply an unrecoverableErrorCallback
when creating a PCastExpress instance.
Developers must handle unrecoverable errors and prevent an application exit as the default behavior
if the callback is not set. If you attempt to create a PCastExpress instance without this parameter,
the creation will not be successful.
The function to include a mandatory unrecoverableErrorCallback
is
PCastExpressFactory.createPCastExpressOptionsBuilder
, as shown below.
PCastExpressFactory.createPCastExpressOptionsBuilder((status, description) -> {
// Best option is to try rebuilding the ChannelExpress
// instance and/or quit your app
})
.buildPCastExpressOptions();
Cancelation Now Cancellation
In the SDK, the spelling of EchoCancelation has been corrected to EchoCancellation,
adding the missing letter L
.
When you create new UserMedia, EchoCancellation is part of the MediaOptions that can be specified.
Tokens Now Required
Channels and Rooms can ONLY be joined using tokens. Channels and Rooms can no longer be joined with IDs or Aliases as input parameters to the API. When joining Channels and Rooms with tokens, the tokens need to contain either a Channel/Room ID or Alias. Please see the deprecations section for functions that have been deprecated as they use IDs and Aliases to join Rooms or Channels.
Joining Channels occurs now using the following existing ChannelOptions configuration method
PhenixJoinChannelOptionsBuilder.withStreamToken
Joining Rooms occurs now using the new RoomOptions configuration method
PhenixJoinRoomOptionsBuilder.withStreamToken
For authenticating with the Phenix Platform, either a authToken or an edgeauthToken is
supplied to the existing PCastExpressOptionsBuilder.withAuthenticationToken(authToken)
Requests Include UserAgent String
To support analytics, the WebSocket and HTTP requests now send a formatted User-Agent string, which includes relevant client application and platform information.
Examples of these are:
-
PhenixRTS/SDK/2023.0.0-2205f42-20230105T120033Z (iOS:16.0; ARM64; iPhone14,8) WebSocket++/0.7.0
-
PhenixRTS/PhenixPeer/2023.0.0-2205f42-20230105T120033Z (MacOS:12.5.1; x86_64; MacBookPro18,2) Poco/0.7.0
-
PhenixRTS/SDK/2023.0.0-2205f42-20230105T120033Z (Android:13; armv71; HTC Desire V) WebSocket++/0.7.0
-
PhenixRTS/PhenixCli/2023.0.0-2205f42-20230105T120033Z (Windows:10; x86_64; Pentium |||) Poco/0.7.0
-
PhenixRTS/PhenixCli/2023.0.0-2205f42-20230105T120033Z (Linux:#215-Ubuntu SMP Fri Jan 20 18:24:59 UTC 2023; x86_64; Intel(R) Xeon(R) CPU @ 2.80GHz) poco/1.11.1
Bug Fixes
All Publish
and Subscribe
APIs will now wait until a valid session is available before proceeding.
Fixed memory leak when an application is entering the background. The issue could be observed when monitoring an application's memory consumption through Android's Memory Profiler.
Fixed a crash when repeatedly re-instantiating ChannelExpress
and RoomExpress
instances.
Fixed a crash when an application is backgrounded and brought back to the foreground where internal services try to re-initialize while they are still shutting down.
Fixed microphone audio capture, which led to a diminished captured audio volume, when configuring Echo Cancellation on devices running Android 10 and above. The fix applies to setting UserMedia audio options in the Android where we set echo cancellation. An example of audio options that enable Echo Cancellation in Kotlin is shown below.
UserMediaOptions userMediaConstraints = new UserMediaOptions();
userMediaConstraints.audioOptions.enabled = true
userMediaConstraints
.audioOptions
.capabilityConstraints[DeviceCapability.AUDIO_ECHO_CANCELLATION_MODE]
= listOf(DeviceConstraint(AudioEchoCancellationMode.ON))
Deprecations
It is now mandatory to supply an unrecoverableErrorCallback
when creating a PCastExpress instance.
The function for configuring unrecoverableErrorCallback, PCastExpressOptionsBuilder.WithUnrecoverableErrorCallback
,
has been removed.
Channels and Rooms can no longer be joined with IDs or Aliases, as discussed in the token section above. Removed functions are:
- PhenixJoinChannelOptionsBuilder.withJoinRoomOptions
- PhenixJoinRoomOptionsBuilder.withRoomId
- PhenixJoinRoomOptionsBuilder.withRoomAlias
- PublishToChannelOptionsBuilder.withChannelId
- PublishToRoomOptionsBuilder.withRoomId
Creation and deletion of Channels and Rooms can no longer be performed by the Android SDK. This now requires a service that interfaces with the platform REST API. Please contact Phenix if you require assistance in setting up your service. Removed functions are:
- PhenixChannelExpress.createChannel
- PhenixRoomExpress.createRoom
- PhenixRoomService.createRoom
- PhenixRoomService.destroyRoom
Remote publishing is no longer allowed via the Android SDK. Removed functions are:
- PublishOptionsBuilder.WithConnectOptions
- SubscribeOptionsBuilder.WithConnectOptions
- SubscribeToMemberStreamOptionsBuilder.WithConnectOptions
Creating PCastAdmin has been removed from the SDK. The function PCastFactory.createPCastAdmin
has been removed.
As re-authorization was removed with the removal of AdminAPI, WithSkipRetryOnUnauthorized was removed from SDK API interfaces.
Note that re-authentication support has been added through PCastExpress.SetAuthenticationToken
and observing authentication
status through PCastExpress.getObservableAuthenticationStatus
. Removed functions are:
- JoinChannelOptionsBuilder.withSkipRetryOnUnauthorized
- PublishOptionsBuilder.withSkipRetryOnUnauthorized
- PhenixSubscribeOptionsBuilder.withSkipRetryOnUnauthorized
- SubscribeToMemberStreamOptionsBuilder.withSkipRetryOnUnauthorized
The SDK no longer allows the user to set the PCast URI, which is the URI to the Platform backend, through code. The
PhenixPCastExpressOptionsBuilder.withPCastUri
function has been removed.
PCastUri configuration for a session now exclusively occurs through an optional URI parameter set in the authToken or
an edgeToken. To set backend URIs in tokens using the edgeAuth library, use the -y
or --uri
parameter.
A token's backend URI parameter value can be verified by
decoding tokens within Portal.
When no URI parameter is supplied in the authToken or edgeToken, the production Platform backend,
https://pcast.phenixrts.com/
, is configured in the SDK.
v2022.0.3 Release Notes
Release Date: 2022.07.27
Features/Improvements
-
Added support for using a different CDN domain for playlists.
-
Added support for PCastUri in tokens.
-
Added support for channel/room alias or ID in tokens.
-
Improved network usage.
-
Improved video performance and compatibility
Fixes
-
Fixed chat room's messages loss in case of network issues.
-
Fixed late PhenixChannelExpress.joinChannel callback call in case of network issues.
-
Updated third-party library dependencies, including update to address potential expat vulnerability
-
Removed hardcoded TLS certificate and RSA key
v2022.0.3 Notes
CDN Domain support
The SDK can now send HTTP requests to URLs that redirect to non-Phenix CDNs for replays or for VOD playlists.
To use alternate CDN domains, use the capability cdn-domain on viewing channels, with the CDN domain as its value. Do not include the protocol prefix (e.g., https://) in the value. For example: cdn-domain=mycdn.mycompany.com
The platform will replace the default streaming domain with the specified CDN domain in playlist URLs for the primary manifest of the content.
PCast™ URI in tokens
A PCast™ URI contained in the token will now be used instead of a URI passed as a parameter. Putting the URI in the token is now the preferred behavior, and passing in a PCast™ URI as a parameter is now deprecated. To include the URI in the token, add the uri
capability as described in the EdgeAuth library documentation.
If the token contains a URI that differs from the one passed as a parameter, the URI from the token is used and a warning is written to the log.
Room/Channel ID/Alias in tokens
A room/channel ID or alias passed in the token will be used to join the respective room or channel. As with the PCast™ URI, putting the Room or Channel ID or Alias in the token is now the preferred behavior, and passing in that information as a parameter is now deprecated and will generate a deprecation warning in the log. To include the Room or Channel information in the token, add the roomId, channelId, roomAlias or channelAlias capability as described in the EdgeAuth library documentation.
If a value is provided both as a direct parameter and in the token, the values must match; otherwise the operation will fail.
Improved network usage
When using previous releases, Room members rejoining after network changes would sometimes cause zombie room members. This has been improved and the behavior in case of network changes is more consistent.
In addition, network usage is reduced when downloading stream replay segments.
Fixed chat room messages loss in case of network issues
Previously, any messages still cached by the SDK during reconnection after a network change were silently discarded. Now they are preserved and will be returned by the next call to GetLastMessages. In addition, an issue has been fixed where new messages were discarded instead of old ones when there were many cached and incoming messages.
Upon lost network connectivity, the SDK will now keep trying to reconnect instead of ceasing to retry after a few minutes.
v2021.0.15 Pre-release Notes
Release Date: 2021.08.18
Features/Improvements
No customer-impacting changes.
v2021.0.14 Pre-release Notes
Release Date: 2021.08.09
Features/Improvements
No customer-impacting changes.
v2021.0.15 Pre-release Notes
Release Date: 2021.08.18
Features/Improvements
No customer-impacting changes.
v2021.0.14 Pre-release Notes
Release Date: 2021.08.09
Features/Improvements
No customer-impacting changes.
v2021.0.11 Pre-release Notes
Release Date: 2021.06.08
Features/Improvements
- Increased internal timeout when connecting to PCast™ platform to avoid SDK initialization failures on clients with lossy network connections
Fixes
- Fixed memory leaks occurring when stopping a room publisher
v2021.0.8 Pre-release Notes
Release Date: 2021.05.14
Features/Improvements
- User media stream instances will no longer get stopped because of network disruptions or switches so they can be retained for as long as needed by an app
Notes on Integrating the Android SDK
UserMediaStream on Android.
v2021.0.7 Pre-release Notes
Release Date: 2021.05.06
Features/Improvements
- None
Issues addressed in this release
-
Fixed null pointer crash in AudioPlaybackJniAdapter
-
Fixed sporadic crashes
v2021.0.5 Pre-release Notes
Release Date: 2021.04.12
Features/Improvements
- None
Issues addressed in this release
- Fixed bug resulting in subscribers not getting audio
v2021.0.2 Pre-release Notes
Release Date: 2021.03.02
Features/Improvements
- When no Admin API (e.g. backend) is provided, channel publisher wildcard tokens are now automatically disabled to avoid failures
Issues addressed in this release
-
Fixed audio only real-time stream rendering
-
Fixed missing callback invocation for PhenixRoomExpress.subscribeToMemberStream if member stream has ended already
-
Added missing API PhenixPublishToChannelOptionsBuilder.withoutWildcardTokens
v2021.0.0 Pre-release Notes
Release Date: 2021.01.07
Features/Improvements
-
Improved error handling when attempting to start subscribers and publishers with capabilities and edge stream tokens
-
Reduce occurrences of audio drop out and lip sync issues on Android
-
Publish and subscribe should fail when caller supplies a stream token with capabilities in conjunction with explicitly capabilities (withCapabilities) to the builder; either approach works independently but both simultaneously will fail
Issues addressed in this release
- Fixed broken time shifts for very long running streams
v2020.1.76 Pre-release Notes
Release Date: 2020.12.22
Features/Improvements
-
PhenixTimeShiftOptions.chunkRetrievalTimeout
property allows overriding the maximum amount of time the SDK will wait to download a chunk for time-shift playback -
PhenixChannelExpress.joinChannel
will now return with an "unauthorized" status (subscriber callback) when the stream token that was provided when the channel was joined is either invalid or has expired. The recourse for the app is to leave the channel(PhenixRoomService.leaveRoom())
and then re-join the channel with an updated stream token.
Issues addressed in this release
- None
Notes on Integrating the Android SDK
// The current implementation of `TimeShift` leverages HLS chunks.
// It is possible that retrieval of such chunks can take a very long time.
// This will impact playback if the playback head catches up with the end
// of the prefetch window, which will lead to a stall.
// By default, a timeout of 10 seconds for each chunk retrieval is used
// to avoid holding off playback for too long (worst case a chunk will be
// skipped and playback may pause temporarily).
// This timeout is configurable by setting the following option (it defaults
// to 0, which indicates that we should use the internal default):
var timeoutInMilliseconds = 5000L
rendererOptions.timeShiftOptions.chunkRetrievalTimeoutInMilliseconds
= timeoutInMilliseconds
v2020.1.75 Pre-release Notes
Release Date: 2020.12.11
Features/Improvements
PhenixTimeShiftOptions
viaPhenixRendererOptions
allows customization of rendition selection behavior
Issues addressed in this release
-
Fixed possible crash due race condition occurring when shutting down a renderer
-
Fixed resource leaks associated with time-shifts
Notes on Integrating the Android SDK
import com.phenixrts.common.Disposable;
import com.phenixrts.pcast.Renderer;
import com.phenixrts.pcast.TimeShift;
import java.util.Date;
// Renderer has been obtained from `MediaStream` or `ExpressSubscriber`:
var renderer: Renderer = ...
if (!renderer.isSeekable) {
// This stream does not support time shifting
return;
}
// Must be in UTC:
var timePoint = Date(...)
var timeShift = renderer.seek(timePoint)
// Observe ready status and call `loop` once TimeShift is ready.
// This ensures that when `loop` is called playback will start
// instantly.
// All observables return a `Disposable` object. This needs to be stored
// in order to keep the observable subscription alive.
// It is recommended to make this a member of the enclosing class
var disposables = mutableListOf<Disposable>()
timeShift.observableReadyForPlaybackStatus.subscribe { isReady ->
if (isReady) {
var loopDurationInMilliseconds = 30000L
timeShift.loop(loopDurationInMilliseconds)
}
}.run{ disposables.add(this) }
// When time shifted viewing is no longer desired:
// Dispose the `TimeShift` object. It will no longer be useable
// after this operation. A new instance can be obtained via `seek`
timeShift.dispose() // <-- Playback will jump back to real-time head
// It is also possible to stop a timeshift in progress so it can
// be used again by calling `loop` later
timeShift.stop() // <-- Playback will jump back to real-time head
// After `stop()` the ready status will (briefly) switch to false, then
// back to true when enough data has been re-cached.
// `TimeShift` objects can fail, either during creating when passing in
// an invalid timestamp to `Renderer.seek()` or any of the other `TimeShift`
// method. Once a `TimeShift` has failed, it should be disposed and a new
// one created.
timeShift.observableFailure.subscribe { status ->
// a non-OK `RequestStatus` is returned here
}.run { disposables.add(this) }
// Pause playback
timeShift.pause()
// Resume playback after pause
timeShift.play()
// The current playback head can be observed. Each video frame will trigger
// the observable. The head is reported as a `Date` object and represents UTC.
timeShift.observablePlaybackHead.subscribe { playbackHead ->
// a `Date` object. Avoid blocking this thread and dispatch UI updates
// as needed.
}.run { disposables.add(this) }
// `TimeShift` supports seeking to any location within the current segment.
// The segment is defined by:
// Start: Time point passed into `Renderer.seek`
// End : Start plus duration passed into `TimeShift.loop`
// Seeking is only possible if the `TimeShift` is either stopped or paused.
// Once `TimeShift` is ready for playback, the observable returned by `seek`
// will return a status code. Call `play()` to start/resume playback if the
// status is OK.
var relativeSeekTimeInMillis = -10000L // Seeks back 10 seconds
timeShift.seek(relativeSeekTimeInMillis).subscribe { status ->
if (status == RequestStatus.OK) {
timeShift.play()
} else {
// Handle error. In most cases the seek argument would have led to
// a location outside of the segment
}
}.run { disposables.add(this) }
// There is also a second version of `seek` available, which accepts a `Date`
// as its argument representing an absolute time point in UTC (also has to
// fall within the boundaries of the segment).
// A `TimeShift` stream generally consists of several so called layers. Layers
// have different bitrates, usually by varying resolution and framerate (lower
// bitrate layers tend to have lower resolutions and/or framerates).
// While a `TimeShift` is playing back content, it will automatically select
// an appropriate layer based on the pixel resolution of the rendering
// surface. The logic attempts to select a layer, whose resolution matches
// that of the rendering surface as closely as possible.
// Sometimes an app may want to further restrict the playback layer in order
// to reduce battery usage for instance. This is possible via the
// `TimeShift.limitBandwidth` API. It forces the `TimeShift` to only select
// layers with an average bitrate less or equal to the value passed into
// `limitBandwidth`.
// The limitation will remain in effect for as long as the app holds on to
// the `Disposable` object returned by the API.
// This API can be called at any time: before and during playback.
var bandwithLimitInBps = 400000L
var limitBandwidthDisposable = timeShift?.limitBandwidth(bandwithLimitInBps)
// Call `dispose()` on the `Disposable` object to release the bandwidth limit
limitbandwidthDisposable?.dispose()
// Certain behaviors of `TimeShift` can be changed by passing in
// custom options when the `Renderer` is created:
var rendererOptions = RendererOptions()
// When calling `Renderer.seek` or `TimeShift.seek` the
// bandwidth will be automatically limited to shorten the amount of time
// it takes for the `TimeShift` object to become ready.
// The downside of this approach is that once the playback starts, it will
// do so on a lower bitrate rendition of the stream and it generally takes a
// few seconds before the rendition switches to a higher bitrate.
// This behavior is enabled by default, but can be disabled by setting the
// following option to false:
rendererOptions.timeShiftOptions.lowerBandwidthWhileSeekingEnabled = false
// The size of the viewport will determine which rendition of the stream is
// selected (the rendition whose height in pixels is closest to the current
// height of the viewport). This selection process is continuous, which means
// that as the viewport size changes, so does the selected rendition.
// After a new rendition has been selected, it will not render frames
// instantly. Instead, it will take up to about 5 seconds before it will
// render frames.
// This behavior is enabled by default, but can be disabled by setting the
// following option to false:
rendererOptions.timeShiftOptions.viewportSizeBasedRenditionSelectionEnabled
= false
// The options object can be passed in directly to the `createRenderer`
// method:
var subscriber: ExpressSubscriber = ... // previously obtained
var renderer = subscriber.createRenderer(rendererOptions)
// Alternatively, it can be passed via various options builders, for example
// for `joinChannel`:
var joinChannelOptionsBuilder =
ChannelExpressFactory.createJoinChannelOptionsBuilder()
joinChannelOptionsBuilder.withRendererOptions(rendererOptions)
v2020.1.73 Pre-release Notes
Release Date: 2020.12.01
Features/Improvements
-
Improved stability in the case where Bluetooth permission is missing
-
Improved audio stream reliability by increasing audio render buffer size
-
Reduced time taken for TimeShift playback to reach higher rendition
-
Improved TimeShift playback reliability
Issues addressed in this release
- None
v2020.1.68 Pre-release Notes
Release Date: 2020.11.12
Features/Improvements
-
Shortened duration for TimeShift to become ready
-
Improved TimeShift playback reliability
-
Setting the RTP/UTC time base needs to use the correct DVR section start time
-
TimeShift seeking needs to prevent deadlocks on calling thread
-
Move callback handling in AndroidJavaAudioRenderDevice to a separate thread
-
Handle bluetooth headset connections and disconnections with AEC enabled on Android
-
Revert audio capture time-stamping logic back to using local timestamp
Issues addressed in this release
- None
Notes on Integrating the Android SDK
In order to support BlueTooth functionality, add the following to the manifest:
<uses-permission android:name="android.permission.BLUETOOTH" />
v2020.1.61 Pre-release Notes
Release Date: 2020.09.22
Features/Improvements
-
Fix for occasional failures when creating
RoomChatService
. Extra delay before creating service is no longer needed. -
Fix for failing TimeShift objects after calling
Renderer.Seek
for Live streams
Issues addressed in this release
- None
v2020.1.60 Pre-release Notes
Release Date: 2020.09.16
IMPORTANT
We only recommend this update for the VOD applications (not Live). This release has an issue that affects Live timeshifts.
Features/Improvements
- None
Issues addressed in this release
-
Fix for further potential deadlocks that may occur when calling
Renderer.Seek
-
Fix for short DVR segments not looping
-
Fix for deadlock when calling Renderer.Seek
-
Improved VOD stream startup and seeking times and stability
-
Improved performance by avoiding pixel format conversions where possible
v2020.1.56 Pre-release Notes
Release Date: 2020.08.31
Features/Improvements
- None
Issues addressed in this release
-
Added support for subscribing to messages based on mime-types
-
Fix to properly expose API in support for configurable sampling rate for BlueTooth SCO capability in Android
-
Added client side timeouts for member updates
Notes on Integrating the Android SDK
In order to support BlueTooth SCO headsets
- Configure the sample rate overrides for recording and playback to values that are required by SCO:
try {
Os.setenv("PHENIX_AUDIO_PLAYBACK_SAMPLE_RATE_OVERRIDE", "16000", true);
Os.setenv("PHENIX_AUDIO_RECORDING_SAMPLE_RATE_OVERRIDE", "8000", true);
} catch (ErrnoException e) {
// handle exception
}
- Enable SCO in the AudioManager (this example assumes the code is placed in your Application subclass):
AudioManager audioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
// call at appropriate time - detection of BT on
audioManager.startBluetoothSco();
// call at appropriate time - detection of BT off
audioManager.stopBluetoothSco();
- For both publishing and subscribing, make sure that audio echo cancellation is enabled in the respective options:
// publishing
final UserMediaOptions mediaConstraints = new UserMediaOptions();
mediaConstraints.getAudioOptions().capabilityConstraints.put(
DeviceCapability.AUDIO_ECHO_CANCELATION_MODE,
singletonList(new DeviceConstraint(AudioEchoCancelationMode.ON)));
PublishOptions publishOptions = PCastExpressFactory.createPublishOptionsBuilder()
.withMediaConstraints(mediaConstraints)
// add any other options
.buildPublishOptions();
// subscribing
final RendererOptions rendererOptions = new RendererOptions();
rendererOptions.audioEchoCancelationMode = AudioEchoCancelationMode.ON;
JoinChannelOptionsBuilder joinChannelOptionsBuilder = ChannelExpressFactory
.createJoinChannelOptionsBuilder()
.withRendererOptions(rendererOptions)
// add any other options
.buildJoinChannelOptions()
- Note that only mono streams are supported by SCO.
In order to subscribe to messages by mime-type
import com.phenixrts.chat.RoomChatServiceFactory;
import com.phenixrts.room.RoomService;
final int batchSize = ...
final RoomService roomService = ...; // previously obtained
final HashSet<String> wantedMimeTypes = new HashSet<String>();
wantedMimeTypes.add(“text/javascript”);
final RoomChatService chatService =
RoomChatServiceFactory.createRoomChatService(
roomService,
batchSize,
wantedMimeTypes
);
// “chatService” retrieves only messages of “wantedMimeTypes”
final Disposable subscriptionLastChatMessage =
chatService.getObservableLastChatMessage().subscribe((change) -> {
final ChatMessage message = (ChatMessage)change;
assert message.getObservableMimeType().getValue() == “text/javascript”;
});
final Disposable subscriptionChatMessages =
chatService.getObservableChatMessages().subscribe((change) -> {
final ChatMessage[] messages = (ChatMessage[])change;
for (int i = 0; i < messages.length; ++i) {
assert message.getObservableMimeType().getValue() ==
“text/javascript”;
}
});
chatService.getMessages(
batchSize,
afterMessageId,
beforeMessageId,
(RoomChatService service, ChatMessage[] messages, RequestStatus status) -> {
for (int i = 0; i < messages.length; ++i) {
assert message.getObservableMimeType().getValue() ==
“text/javascript”;
}
});
// send message with a specific MIME type
// with just the message, MIME type defaults to “text/plain”:
chatService.sendMessageToRoom("My First Message");
// with message and MIME type, but using default callback
chatService.sendMessageToRoom("My First Message", "text/javascript");
// with message, MIME type, and callback
chatService.sendMessageToRoom(
"My First Message",
"text/javascript",
(RequestStatus status, String message) -> { ... }
);
v2020.1.52 Pre-release Notes
Release Date: 2020.08.27
Features/Improvements
- None
Issues addressed in this release
-
Support for configurable sampling rate for BlueTooth SCO capability
-
Improvements on re-establishing connections after changing network type
-
Improved reliability of room member updates, which impacts for instance toggling audio/video muted states
-
Added support for obtaining beta iOS releases via pod spec
v2020.1.49 Pre-release Notes
Release Date: 2020.08.21
Features/Improvements
- None
Issues addressed in this release
-
Stream restart on change in network type
-
Fix for the last message observable - improve reliability on new message arrival
-
Removed unnecessary animation (iOS)
Notes
To take advantage of the new functionality in support of stream restarts on change in network type, it works as follows:
-
App calls subscribeToMemberStream and passes a callback (last argument) to get notified when we successfully subscribed.
-
Once subscribed, the app's callback is invoked.
-
If there is a network switch, the SDK will start monitoring the stream and watch for data for about 5 seconds. If there is no (or very little) data, we consider the connection lost and the SDK will restart it.
-
If a stream is restarted due to a lack of data, the callback set by the app in subscribeToMemberStream will be invoked, to indicate the restart. This will provide the app with a new ExpressSubscriber (and Renderer if the app requested one).
Based on the options initially passed to subscribeToMemberStream, the app can either let the SDK create the renderer, or the app can create a renderer itself.
-
If the app is letting the SDK manage the renderer, the SDK will stop the renderer and create a new renderer when the stream needs to be restarted.
-
If the app manages the renderer, then the app must make sure to stop and dispose of the old renderer and before creating a new one once it receives a new ExpressSubscriber.
v2020.1.47 Pre-release Notes
Release Date: 2020.08.20
Features/Improvements
- None
Issues addressed in this release
-
Added observable in RoomChatService that fires individually for each chat message as they come in
-
Android camera reconnection logic
-
Fixes for iOS renderers (includes detaching our render layers when we're done)
-
Other minor fixes to handle TimeShift.seek when time-shift is stopped
v2020.1.43 Pre-release Notes
Release Date: 2020.08.18
Features/Improvements
- None
Issues addressed in this release
-
Frame-ready API needs to relay frames from time-shifted content when a TimeShift is playing
-
Various fixes
v2020.1.40 Pre-release Notes
Release Date: 2020.08.12
Features/Improvements
- None
Issues addressed in this release
-
Fix for deadlock when layer resolution changes
-
LimitBandwidth API (on TimeShift).
v2020.1.38 Pre-release Notes
Release Date: 2020.08.07
Features/Improvements
- None
Issues addressed in this release
-
Support for “click and seek” into a timeshift segment (details on usage below)
-
Timeshift observable playback head reports position in UTC time
-
Timeshift pause and play options
-
Timeshift observable failure report
v2020.1.33 Pre-release Notes
Release Date: 2020.07.16
Features/Improvements
- None
Issues addressed in this release
-
Includes viewport based HLS layer selection
-
Prefetch window is updated based on layer bitrate for faster switching from very low bitrate layers
-
Includes a fix for iOS, which previously caused image corruption during time-shifted playback
v2020.1.30 Pre-release Notes
Release Date: 2020.07.08
Features/Improvements
- None
Issues addressed in this release
-
Audio muted status needs to be honored when rendering time-shifted content
-
Add support for Automatic Gain Control