iOS SDK Version Comparison
This page provides information about APIs and features that will no longer be supported by the beta iOS SDK release but may be in use by developers that are using prior versions of the SDK. Links to the beta version of the documentation are provided when possible.
A copy of the current documentation is shown with a blue background for easier identification when comparing to beta documentation.
All beta documentation is watermarked BETA to allow easy identification.
v2022.0.4 and Earlier
PCast™ Express
Newer versions of PCast™ Express do not support certain arguments in
- PhenixPCastExpressOptionsBuilder
- PublishOptionsBuilder
- SubscribeOptionsBuilder
Using these arguments with the newer SDK will result in a failure such as unrecognised option
.
Some APIs, such as Publishing Remote Media (Ingest), are not supported by newer versions of the SDK.
In addition, token arguments are required when using the newer SDK (e.g., withStreamToken
or withAuthenticationToken
), and not including tokens will result in a failure such as bad-request
.
Initializing PCast™ Express
Beta version: Initializing
Current version:
import PhenixSdk
let pcastExpressOptions = PhenixPCastExpressFactory.createPCastExpressOptionsBuilder()
.withBackendUri("https://example.yourdomain.com/phenix/")
.buildPCastExpressOptions()
let pcastExpress = PhenixPCastExpressFactory.createPCastExpress(pcastExpressOptions)
PhenixPCastExpressOptionsBuilder
Name | Type | Default | Description |
---|---|---|---|
withBackendUri (required) | NSString | Url to your backend. We send requests here to authenticate and get streaming tokens. | |
withAuthenticationData (optional) | NSString | Your authentication data for the user. On every request, this will be sent to your backend through a HTTP POST request and all its attributes would be accessible on the request body. Needs to be valid JSON. | |
withAuthenticationToken (optional) | NSString | The authentication token generated using the Phenix EdgeAuth library. | |
withUnrecoverableErrorCallback (optional) | PhenixPCastExpressUnrecoverableErrorCallback | Function to be called when authentication fails or a failure occurs that is unrecoverable. | |
withPCastUri (optional) | NSString | Allows overriding default PCast™ URI. | |
withPCastInitializationOptions (optional) | PhenixPCastInitializeOptions | Use custom options when initializing PCast™. | |
withAuthenticationRouteOverride (optional) | NSString | auth | Allows override of default route for authentication tokens |
withStreamRouteOverride (optional) | NSString | stream | Allows override of default route for stream tokens |
buildPCastExpressOptions | none | Builds the PhenixPCastExpressOptions |
Publishing Local Media
Beta version: Publishing Local Media
Current version:
import PhenixSdk
let pcastExpress: PhenixPCastExpress = ... // previously obtained
let userMediaConstraints = PhenixUserMediaOptions()
userMediaConstraints.video.enabled = true
userMediaConstraints.video.capabilityConstraints[PhenixDeviceCapability.facingMode.rawValue] =
[PhenixDeviceConstraint.initWith(PhenixFacingMode.user)]
userMediaConstraints.audio.enabled = true
userMediaConstraints.audio.capabilityConstraints[PhenixDeviceCapability.audioEchoCancelationMode.rawValue] =
[PhenixDeviceConstraint.initWith(PhenixAudioEchoCancelationMode.on)]
let publishOptions = PhenixPCastExpressFactory.createPublishOptionsBuilder()
.withCapabilities(["real-time"])
.withMediaConstraints(userMediaConstraints)
.buildPublishOptions()
pcastExpress.publish(publishOptions) { (status: PhenixRequestStatus, publisher: PhenixExpressPublisher?) in
if status == .ok {
// Do something with publisher
} else {
// Handle error
}
}
// Create a publisher with an automatically started preview renderer
let renderLayer: CALayer = ... // previously obtained
let publishOptionsWithPreview = PhenixPCastExpressFactory.createPublishOptionsBuilder()
.withCapabilities(["real-time"])
.withMediaConstraints(userMediaConstraints)
.withPreviewRenderer(renderLayer)
.buildPublishOptions()
pcastExpress.publish(withPreview: publishOptionsWithPreview) {
(status: PhenixRequestStatus, publisher: PhenixExpressPublisher?, preview: PhenixRenderer?) in
if status == .ok {
// Do something with publisher and preview renderer
} else {
// Handle error
}
}
✂ Unchanged content not shown
PhenixPublishOptionsBuilder
Name | Type | Default | Description |
---|---|---|---|
withMediaConstraints (required) | PhenixUserMediaOptions | getUserMedia options Constraints to get the user media. | |
withUserMedia (optional) | PhenixUserMediaStream | alternative to withMediaConstraints - you can pass user media stream returned from getUserMedia. | |
withCapabilities (optional) | NSArray of NSString | The list of all capabilities to publish with. Default is empty array. | |
withPreviewRenderer (optional) | CALayer | Render layer on which to display local preview. If none of the withPreview... methods are called, no preview renderer will be instantiated. | |
withPreviewRenderer (optional) | none | Will trigger instantiation of preview renderer. Useful for audio only type streams that do not require a render surface. | |
withPreviewRendererOptions (optional) | PhenixRendererOptions | Options passed to preview renderer. Will trigger instantiation of preview renderer. | |
withMonitor (optional) | PhenixMonitorSetupFailedCallback, PhenixMonitorStreamEndedCallback, PhenixMonitorOptions | Options for monitoring a publisher for failure. | |
withConnectOptions (optional) | NSArray of NSStrings | List of options for publishing. | |
withTags (optional) | NSArray of NSStrings | Tags for the stream. | |
withStreamToken (optional) | NSString | The publish token generated using the Phenix EdgeAuth library. | |
buildPublishOptions | none | Builds the PhenixPublishOptions |
Publishing Remote Media (Ingest)
Beta version: This API is not supported by the beta version of the iOS SDK. To publish remote media, please use the REST API for publishing a stream from a URI.
Current version:
Publish from remote sources into the Phenix platform. This enables us to distribute your source media using the Phenix platform. After publishing users may subscribe to the stream using either pcast subscribe or express subscribe.
import PhenixSdk
let pcastExpress: PhenixPCastExpress = ... // previously obtained
let publishRemoteOptions = PhenixPCastExpressFactory.createPublishRemoteOptionsBuilder()
.withStreamUri("http://mycdn.example.com/mystream.mp4")
.withCapabilities([""])
.buildPublishRemoteOptions()
pcastExpress.publishRemote(publishRemoteOptions) { (status: PhenixRequestStatus, publisher: PhenixExpressPublisher?) in
if status == .ok {
// Do something with publisher
} else {
// Handle error
}
}
Publishing Remote Media Parameters
Name | Type | Description |
---|---|---|
options (required) | PhenixPublishRemoteOptions | Publish Remote options |
callback (required) | function | Callback for error/success handling |
PhenixPublishRemoteOptionsBuilder
Name | Type | Default | Description |
---|---|---|---|
withCapabilities (required) | NSArray of NSString | The list of all capabilities to publish with. | |
withStreamUri (required) | NSString | Link to remote media (mp4, rtmp, etc.) | |
withStreamToken (optional) | NSString | The publish token generated using the Phenix EdgeAuth library. | |
withConnectOptions (optional) | NSArray of NSStrings | List of options for publishing from a remote source. | |
withTags (optional) | NSArray of NSStrings | Tags for the stream | |
withMaximumFrameRateConstraint (optional) | double | Maximum frame rate constraint. | |
withExactFrameRateConstraint (optional) | double | Exact frame rate constraint. | |
withPrerollSkipDuration (optional) | NSTimeInterval | 500 | The amount of time to skip at the beginning of the media. |
buildPublishRemoteOptions | none | Builds the PhenixPublishRemoteOptions |
Publishing Remote Media Callback Arguments
Name | Type | Description |
---|---|---|
status | PhenixRequestStatus | The status of the operation. |
publisher | PhenixExpressPublisher | Phenix publisher object |
Subscribing to Published Media
Beta version: Subscribing to Published Media
Current version:
import PhenixSdk
let pcastExpress: PhenixPCastExpress = ... // previously obtained
let renderLayer: CALayer = ... // previously obtained
let subscribeOptions = PhenixPCastExpressFactory.createSubscribeOptionsBuilder()
.withStreamId("us-west#us-west1-b.zzzzzzzz.20000000.xxxxxxxx")
.withCapabilities(["real-time"])
.withRenderer(renderLayer)
.buildSubscribeOptions()
pcastExpress.subscribe(subscribeOptions) { (status: PhenixRequestStatus, subscriber: PhenixExpressSubscriber?, renderer: PhenixRenderer?) in
if status == .ok {
// Do something with subscriber
if let renderer = renderer {
// Returned if `withRenderer...` option was enabled - Do something with renderer
}
} else {
// Handle error
}
}
✂ Unchanged content not shown
Subscribe Options
Name | Type | Default | Description |
---|---|---|---|
withStreamId (required) | NSString | The stream ID of the published stream | |
withCapabilities (required) | NSArray of NSString | The list of all capabilities to subscribe with. | |
withStreamToken (optional) | NSString | The subscribe token generated using the Phenix EdgeAuth library. | |
withRenderer (optional) | CALayer | Render layer on which to display stream. If none of the withRenderer... methods are called, no renderer will be instantiated. | |
withRenderer (optional) | none | Will trigger instantiation of renderer. Useful for audio only type streams that do not require a render surface. | |
withRendererOptions (optional) | PhenixRendererOptions | Options passed to renderer. Will trigger instantiation of renderer. | |
withMonitor (optional) | PhenixMonitorSetupFailedCallback, PhenixMonitorStreamEndedCallback, PhenixMonitorOptions | Options for monitoring a subscriber for failure. | |
withConnectOptions (optional) | NSArray of NSStrings | List of options for subscribing. | |
withTags (optional) | NSArray of NSStrings | Tags for the stream | |
buildSubscribeOptions | none | Builds the PhenixSubscribeOptions |
PhenixExpressSubscriber
Shares most methods with regular PhenixMediaStream returned by PhenixPCast, see Subscribe to a Stream.
Name | Signature | Returns | Description |
---|---|---|---|
createRenderer | () | PhenixRenderer | Creates a new renderer. This should only be called if none of the withRenderer... builder methods were invoked. |
createRenderer | (PhenixRendererOptions) | PhenixRenderer | Creates a new renderer with PhenixRendererOptions. This should only be called if none of the withRenderer... builder methods were invoked. |
getAudioTracks | () | NSArray of PhenixMediaStreamTrack | Returns all associated audio tracks of this stream |
getVideoTracks | () | NSArray of PhenixMediaStreamTrack | Returns all associated video tracks of this stream |
getTracks | () | NSArray of PhenixMediaStreamTrack | Returns all associated tracks of this stream |
stop | () | void | Stops subscription. This will trigger the stream ended event. |
disableAudio | () | void | Mutes audio. |
enableVideo | () | void | Unmutes video. |
disableVideo | () | void | Mutes video (black frames). |
Monitor
Note: On iOS, the monitor options are currently ignored, but the callbacks for stream setup and stream ended will be triggered.
Monitor callbacks and options can be passed to subscribe and publish options builders. The first callback gets invoked only when we internally fail to setup a stream. The second callback gets invoked whenever a stream ends, whether it is due to failure or not. The retry PhenixOptionalAction allows you to retry publishing or subscribing the failed stream. You must test first whether there is a retry action present by calling isPresent
as it may not be possible to retry the stream (example: a stream that ended normally cannot be retried). You may call dismiss
on the retry action, but you do not have to (the action is automatically dismissed when no longer referenced). You also may defer invoking the retry action.
Example Monitor for subscribing
import PhenixSdk
let monitorOptions = PhenixPCastExpressFactory.createMonitorOptionsBuilder().buildMonitorOptions();
let subscribeOptions = PhenixPCastExpressFactory.createSubscribeOptionsBuilder()
.withStreamId("us-west#us-west1-b.zzzzzzzz.20000000.xxxxxxxx")
.withStreamToken("DIGEST:eyJhc...")
.withMonitor({ (status: PhenixRequestStatus, retry: PhenixOptionalAction?) in
// Stream failed to setup, check if retry is a possibility:
if let retry = retry, retry.isPresent() {
if determineWhetherToRetry() {
retry.perform()
} else {
// Not technically necessary, but here for clarity
retry.dismiss()
}
}
},
{ (reason: PhenixStreamEndedReason, description: String?, retry: PhenixOptionalAction?) in
// Stream has ended, check if due to failure
if let retry = retry, retry.isPresent() {
if reason == .failed {
retry.perform()
} else {
// Not technically necessary, but here for clarity
retry.dismiss()
}
}
},
monitorOptions)
.buildSubscribeOptions()
PhenixOptionalAction
Name | Signature | Returns | Description |
---|---|---|---|
perform | () | void | Performs the action. This will cause a failure if isPresent is false. |
dismiss | () | void | Dismisses the action (if any). Can be called multiple times, will result in isPresent to return false. Dropping reference to PhenixOptionsAction has same effect. |
isPresent | () | bool | Indicates whether an action can be performed. |
PhenixMonitorSetupFailedCallback Callback Arguments
Name | Type | Description |
---|---|---|
status | PhenixRequestStatus | The status of the operation. |
retry | PhenixOptionalAction | Optionally allow retrying the failed stream. |
PhenixMonitorStreamEndedCallback Callback Arguments
Name | Type | Description |
---|---|---|
reason | PhenixStreamEndedReason | Reason for stream ended. |
description | NSString | Optional additional ended reason description. Carries custom message. |
retry | PhenixOptionalAction | Optionally allow retrying the failed stream. For normally ended streams isPresent will always return false. |
Channel Express
Newer versions of Channel Express do not support certain arguments in
- PublishOptionsBuilder
- PublishRemoteOptionsBuilder (this builder not supported by newer versions of the SDK)
- JoinRoomOptionsBuilder (this builder not supported by newer versions of the SDK)
- PCastExpressOptionsBuilder
Using these arguments with the newer SDK will result in a failure such as unrecognised option
.
These arguments are documented in either the PCast™ Express or Room Express sections of this page.
In addition, token arguments are required when using the newer SDK (e.g., withStreamToken
or withAuthenticationToken
), and not including tokens will result in a failure such as bad-request
.
Initializing Express Channel
Beta version: Initializing
Current version:
import PhenixSdk
let pcastExpressOptions = PhenixPCastExpressFactory.createPCastExpressOptionsBuilder()
.withAuthenticationToken("DIGEST:eyJhc...")
.buildPCastExpressOptions()
let roomExpressOptions = PhenixRoomExpressFactory.createRoomExpressOptionsBuilder()
.withPCastExpressOptions(pcastExpressOptions)
.buildRoomExpressOptions()
let channelExpressOptions = PhenixChannelExpressFactory.createChannelExpressOptionsBuilder()
.withRoomExpressOptions(roomExpressOptions)
.buildChannelExpressOptions()
let channelExpress = PhenixChannelExpressFactory.createChannelExpress(channelExpressOptions)
ChannelExpressOptionsBuilder
Name | Type | Default | Description |
---|---|---|---|
withRoomExpressOptions (required) | PhenixRoomExpressOptions | See PhenixRoomExpressOptionsBuilder | |
buildChannelExpressOptions | none | Builds the PhenixChannelExpressOptions |
View a Channel
Beta version: View a Channel
Current version:
Join a channel and automatically view the most recent content published to that channel.
import PhenixSdk
let channelExpress: PhenixChannelExpress = ... // previously obtained
let renderLayer: CALayer = ... // previously obtained
// Just an example (you can omit renderer options if defaults are ok)
let rendererOptions = PhenixRendererOptions()
options.aspectRatioMode = .letterbox
let joinRoomOptions = PhenixRoomExpressFactory.createJoinRoomOptionsBuilder()
.withRoomAlias("MyAwesomeChannel")
.buildJoinRoomOptions()
let joinChannelOptions = PhenixChannelExpressFactory.createJoinChannelOptionsBuilder()
.withJoinRoomOptions(joinRoomOptions)
.withStreamToken("DIGEST:eyJhc...")
.withStreamSelectionStrategy(.mostRecent)
.withRenderer(renderLayer)
.withRendererOptions(rendererOptions)
.buildJoinChannelOptions()
channelExpress.joinChannel(
joinChannelOptions,
{ [weak self] (requestStatus: PhenixRequestStatus, roomService: PhenixRoomService?) in
guard requestStatus == .ok, let strongSelf = self else {
// Handle channel join error
return
}
// Important: Store room service reference, otherwise we will leave channel again immediately:
strongSelf.currentRoomService = roomService
},
{ [weak self]
(requestStatus: PhenixRequestStatus,
expressSubscriber: PhenixExpressSubscriber?,
renderer: PhenixRenderer?) in
guard let strongSelf = self else {
return
}
if (requestStatus == .ok) {
// Successfully subscribed to a stream. No need to hold on to any references
} else if (requestStatus == .noStreamPlaying) {
// No stream playing in channel, update UI accordingy
} else {
// We failed to subscribe and retry attempts must have failed
}
});
View Channel Parameters
Name | Type | Description |
---|---|---|
options (required) | Options | Options to join channel with |
joinChannelCallback (required) | Function | Function to call on success/failure of joining the channel. |
subscriberCallback (required) | Function | Function to call on when the most recent presenter changes. |
PhenixJoinChannelOptionsBuilder
Name | Type | Default | Description |
---|---|---|---|
withJoinRoomOptions (required) | PhenixJoinRoomOptions | See PhenixJoinRoomOptionsBuilder. | |
withStreamToken (required) | NSString | The publish token generated using the Phenix EdgeAuth library. | |
withRenderer (optional) | CALayer | Render layer on which to display stream. If none of the withRenderer... methods are called, no renderer will be instantiated. | |
withRenderer (optional) | none | Will trigger instantiation of renderer. Useful for audio only type streams that do not require a render surface. | |
withRendererOptions (optional) | PhenixRendererOptions | Options passed to renderer. Will trigger instantiation of renderer. | |
withStreamSelectionStrategy (optional) | PhenixStreamSelectionStrategy | PhenixStreamSelectionStrategyMostRecent | Determines how member streams are selected for subscriptions. |
buildJoinChannelOptions | none | Builds the PhenixJoinChannelOptions |
Stream Selection Strategy
Strategy | Description |
---|---|
PhenixStreamSelectionStrategyMostRecent | Select the most recent stream. Viewing stream changes any time a stream starts or is updated in the room. |
PhenixStreamSelectionStrategyHighAvailability | Select streams for increased reliability and redundancy. Viewing stream will only change in the event of a failure of the prior selected stream. |
Express Join Channel Callback Arguments
Name | Type | Description |
---|---|---|
status | PhenixRequestStatus | The status of the operation |
roomService | PhenixRoomService | Phenix room service object |
View Channel Subscriber Callback Status Codes
Status | Description |
---|---|
PhenixRequestStatusOk | Successfully subscribed to presenter |
PhenixRequestStatusNoStreamPlaying | No presenter in channel to subscribe to. Wait for presenter to join. |
varies | Subscribe to presenter failed for other reasons |
Publish to a Channel
Beta version: Publish to a Channel
Current version:
Publish a local or remote media to a channel. Users that are viewing the channel will see your media.
import PhenixSdk
let channelExpress: PhenixChannelExpress = ... // previously obtained
let renderLayer: CALayer = ... // previously obtained
// Using ChannelOptions means that the channel may or may not already exist.
// If the channel ID is known in advance, it is recommended to use `withChannelId` instead
// of `withChannelOptions` when assembling the `PhenixPublishToChannelOptions` below
let channelOptions = PhenixRoomServiceFactory.createChannelOptionsBuilder()
.withName("MyAwesomeChannel")
// Not required but if it is provided we will use this as the alias instead
// of pre-generating one for you:
.withAlias("MyAwesomeChannelAlias")
.buildChannelOptions()
// Example constraints. Audio and video are enabled by default
let mediaConstraints = PhenixUserMediaOptions()
mediaConstraints.video.capabilityConstraints[PhenixDeviceCapability.facingMode.rawValue] =
[PhenixDeviceConstraint.initWith(.user)]
mediaConstraints.video.capabilityConstraints[PhenixDeviceCapability.frameRate.rawValue] =
[PhenixDeviceConstraint.initWith(15)]
mediaConstraints.video.capabilityConstraints[PhenixDeviceCapability.height.rawValue] =
[PhenixDeviceConstraint.initWith(720)]
mediaConstraints.video.capabilityConstraints[PhenixDeviceCapability.width.rawValue] =
[PhenixDeviceConstraint.initWith(1280)]
mediaConstraints.audio.capabilityConstraints[PhenixDeviceCapability.audioEchoCancelationMode.rawValue] =
[PhenixDeviceConstraint.initWith(PhenixAudioEchoCancelationMode.on)]
let publishOptions = PhenixPCastExpressFactory.createPublishOptionsBuilder()
.withStreamToken("DIGEST:eyJhc...")
.withMediaConstraints(mediaConstraints)
.withPreviewRenderer(renderLayer)
.buildPublishOptions()
let publishToChannelOptions = PhenixChannelExpressFactory.createPublishToChannelOptionsBuilder()
.withChannelOptions(channelOptions)
.withPublishOptions(publishOptions)
.buildPublishToChannelOptions()
channelExpress.publish(
toChannel: publishToChannelOptions,
withPreviewCallback: { [weak self] (
status: PhenixRequestStatus,
roomService: PhenixRoomService?,
publisher: PhenixExpressPublisher?,
previewRenderer: PhenixRenderer?) in
guard status == .ok, let strongSelf = self else {
// Handle channel publish error
return
}
// Important: Store publisher reference, otherwise we will stop publishing again immediately:
strongSelf.currentPublisher = publisher
})
// OR (without a preview):
channelExpress.publish(
toChannel: publishToChannelOptions,
withCallback: { [weak self] (
status: PhenixRequestStatus,
roomService: PhenixRoomService?,
publisher: PhenixExpressPublisher?) in
guard status == .ok, let strongSelf = self else {
// Handle channel publish error
return
}
// Important: Store publisher reference, otherwise we will stop publishing again immediately:
strongSelf.currentPublisher = publisher
})
Publish To Channel Parameters
Name | Type | Description |
---|---|---|
options (required) | Options | Options to publish to channel with |
publisherCallback (required) | Function | Function to call on success/failure of publishing to the channel |
PhenixPublishToChannelOptionsBuilder
Name | Type | Default | Description |
---|---|---|---|
withChannelOptions (required) | PhenixChannelOptions | See PhenixChannelOptionsBuilder. If omitted, then withChannelId needs to be provided. | |
withChannelId (required) | String | ID of channel to publish to. If omitted, then withChannelOptions needs to be provided. | |
withPublishOptions (required) | PhenixPublishOptions | Either provide this or remote publish options. | |
withPublishRemoteOptions (required) | PhenixRemotePublishOptions | Either provide this or publish options. | |
withMemberRole (optional) | PhenixMemberRole | PhenixMemberRolePresenter | Role of member to join channel as (used if not already in channel). |
withStreamType (optional) | PhenixStreamType | PhenixStreamTypePresentation | Type of stream to publish |
withScreenName (optional) | String | random unique string | Your screen name |
withViewerStreamSelectionStrategy (optional) | PhenixStreamSelectionStrategy | PhenixStreamSelectionStrategyMostRecent | Stream selection strategy; must match the strategy channel viewers are using. |
buildPublishToChannelOptions | none | Builds the PhenixPublishToChannelOptions |
PhenixChannelOptionsBuilder
Name | Type | Default | Description |
---|---|---|---|
withName (required) | String | Name of channel | |
withAlias (optional) | String | generated | Channel Alias |
withDescription (optional) | String | empty | Channel description |
buildChannelOptions | none | Builds the PhenixChannelOptions |
Publish To Channel Callback Arguments
Name | Type | Description |
---|---|---|
status | PhenixRequestStatus | The status of the operation |
roomService | RoomService | Phenix room service |
publisher | PhenixExpressPublisher | Phenix publisher object |
Create a Channel (deprecated)
Beta version: Creating a Channel is no longer supported by the iOS SDK. Please use the REST API to create a Channel.
Current version:
Creation of Channels from client SDKs is deprecated. Channels should be created by the backend using the REST API.
import PhenixSdk
let channelExpress: PhenixChannelExpress = ... // previously obtained
let channelOptions = PhenixRoomServiceFactory.createChannelOptionsBuilder()
.withName("MyAwesomeChannel")
.withAlias("MyAwesomeChannelAlias") // Not required but if it is provided we will use this as the alias instead
// of pre-generating one for you.
.buildChannelOptions()
channelExpress.createChannel(
channelOptions,
{ (status: PhenixRequestStatus, channel: PhenixImmutableRoom?) in
guard status == .ok else {
// Handle room create error
return
}
// use `channel` to e.g. join
})
Express Create Channel Parameters
Name | Type | Description |
---|---|---|
options (required) | PhenixChannelOptions | Options to create channel with |
callback (required) | Function | Function to call on success/failure of creating to the channel. See Create Channel Callback Arguments |
Express Create Channel Callback Arguments
Name | Type | Description |
---|---|---|
status | PhenixRequestStatus | The status of the operation. |
channel | PhenixImmutableRoom | Immutable Phenix room object |
Room Express
Newer versions of Room Express do not support certain arguments in
- PublishOptionsBuilder
- PublishRemoteOptionsBuilder (this builder not supported by newer versions of the SDK)
- JoinRoomOptionsBuilder
- SubscribeToMemberStreamOptionsBuilder
- PCastExpressOptionsBuilder
Newer versions of Room Express do not support wildcard tokens in the PhenixPublishToRoomOptionsBuilder.
Initializing Room Express
Beta version: Initializing
Current version:
import PhenixSdk
let pcastExpressOptions = PhenixPCastExpressFactory.createPCastExpressOptionsBuilder()
.withAuthenticationToken("DIGEST:eyJhc...")
.buildPCastExpressOptions()
let roomExpressOptions = PhenixRoomExpressFactory.createRoomExpressOptionsBuilder()
.withPCastExpressOptions(pcastExpressOptions)
.buildRoomExpressOptions()
let roomExpress = PhenixRoomExpressFactory.createRoomExpress(roomExpressOptions)
PhenixRoomExpressOptionsBuilder
Name | Type | Default | Description |
---|---|---|---|
withPCastExpressOptions (required) | PhenixPCastExpressOptions | See PhenixPCastExpressOptionsBuilder | |
buildRoomExpressOptions | none | Builds the PhenixRoomExpressOptions |
Join a Room (Express)
Beta version: Join a Room
Current version:
import PhenixSdk
let roomExpress: PhenixRoomExpress = ... // previously obtained
let joinRoomOptions = PhenixRoomExpressFactory.createJoinRoomOptionsBuilder()
.withRoomAlias("myRoom42")
.withCapabilities(["streaming"])
.buildJoinRoomOptions()
roomExpress.joinRoom(joinRoomOptions, { (status: PhenixRequestStatus, roomService: PhenixRoomService?) in
if status == .ok {
// Hold on to roomService reference for as long as you wish to stay in the room
} else {
// Handle error
}
})
// With optional member update notification:
roomExpress.joinRoom(
joinRoomOptions,
{ (status: PhenixRequestStatus, roomService: PhenixRoomService?) in
if status == .ok {
// Hold on to roomService reference for as long as you wish to stay in the room
} else {
// Handle error
}
},
{ (members: [PhenixMember]?) in
// Do something with room members
})
✂ Unchanged content not shown
PhenixJoinRoomOptionsBuilder
Name | Type | Default | Description |
---|---|---|---|
withRoomId (required) | NSString | Id of channel to view | |
withRoomAlias (optional) | NSString | Alias, alternative to ID | |
withCapabilities (required) | NSArray of NSString | The list of all capabilities to subscribe with. | |
withRole (optional) | PhenixMemberRole | PhenixMemberRoleAudience | The Member Role to join with |
withScreenName (optional) | NSString | The member screen name to join with. A random string will be generated if not provided. | |
withStreams (optional) | NSArray of PhenixStream | [] | The member streams to join with. Empty if not provided |
buildJoinRoomOptions | none | Builds the PhenixJoinRoomOptions |
Subscribe to a Member's Stream
Beta version: Subscribe to a Member's Stream
Current version:
import PhenixSdk
let roomExpress: PhenixRoomExpress = ... // previously obtained
let room: PhenixImmutableRoom = ... // previously obtained
let renderLayer: CALayer = ... // previously obtained
// Just an example showing how to get a stream from a member.
// In a real-world app you would want to subscribe to the room-members-observable on the room
// to receive updates when the list of members changes, and then subscribe to the streams-observable
// on each member to access their streams.
let member = room.getObservableMembers().getValue()[0] as! PhenixMember
let memberStream = member.getObservableStreams().getValue[0] as! PhenixStream
let options = PhenixRoomExpressFactory.createSubscribeToMemberStreamOptionsBuilder()
.withRenderer(renderLayer)
.buildSubscribeToMemberStreamOptions()
roomExpress.subscribe(
toMemberStream: memberStream,
options,
{ [weak self] (
status: PhenixRequestStatus,
subscriber: PhenixExpressSubscriber?,
renderer: PhenixRenderer?) in
guard status == .ok, let strongSelf = self else {
// Handle subscribe error
return
}
// Important: Store subscriber reference, otherwise we will stop subscription immediately:
strongSelf.currentSubscriber = subscriber
})
✂ Unchanged content not shown
PhenixSubscribeToMemberStreamOptionsBuilder
Name | Type | Default | Description |
---|---|---|---|
withCapabilities (optional) | NSArray of NSString | [] | The list of all capabilities to subscribe with |
withRenderer (optional) | CALayer | none | Render layer on which to display stream. If none of the withRenderer... methods are called, no renderer will be instantiated. |
withRenderer (optional) | none | false | Will trigger instantiation of renderer. Useful for audio only type streams that do not require a render surface |
withRendererOptions (optional) | PhenixRendererOptions | none | Options passed to renderer. Will trigger instantiation of renderer |
withMonitor (optional) | PhenixMonitorSetupFailedCallback, PhenixMonitorStreamEndedCallback, PhenixMonitorOptions | none | Options for monitoring a subscriber for failure |
withConnectOptions (optional) | NSArray of NSStrings | [] | List of options for subscribing |
withTags (optional) | NSArray of NSStrings | [] | Tags for the stream |
buildSubscribeToMemberStreamOptions | none |
Publish to a Room
Beta version: Publish to a Room
Current version:
Publish local or remote media to a room. An error will be returned if a room corresponding to the Room Options passed does not exist. If you have not entered the room via joinRoom or publishToRoom methods then a model for Self will be created.
import PhenixSdk
let roomExpress: PhenixRoomExpress = ... // previously obtained
let renderLayer: CALayer = ... // previously obtained
let mediaConstraints = PhenixUserMediaOptions()
// Customize constraints if needed
let localPublishOptions = PhenixPCastExpressFactory.createPublishOptionsBuilder()
.withCapabilities(["hd", "streaming"])
.withMediaConstraints(mediaConstraints)
.withPreviewRenderer(renderLayer)
.buildPublishOptions()
let roomOptions = PhenixRoomServiceFactory.createRoomOptionsBuilder()
.withName("MyAwesomeRoom")
.buildRoomOptions()
let localPublishToRoomOptions = PhenixRoomExpressFactory.createPublishToRoomOptionsBuilder()
.withStreamType(.user)
.withMemberRole(.participant)
.withRoomOptions(roomOptions)
.withPublishOptions(localPublishOptions)
.buildPublishToRoomOptions()
roomExpress.publish(
toRoom: localPublishToRoomOptions,
withCallback: { [weak self] (
status: PhenixRequestStatus,
roomService: PhenixRoomService?,
publisher: PhenixExpressPublisher?) in
guard status == .ok, let strongSelf = self else {
// Handle publish error
return
}
// Important: Store publisher reference, otherwise we will stop publisher immediately:
strongSelf.currentPublisher = publisher
})
// OR for a remote stream:
let remotePublishOptions = PhenixPCastExpressFactory.createPublishRemoteOptionsBuilder()
.withStreamUri("http://example.com/mystream.mp4")
.buildPublishRemoteOptions()
let remotePublishToRoomOptions = PhenixRoomExpressFactory.createPublishToRoomOptionsBuilder()
.withStreamType(.user)
.withMemberRole(.participant)
.withRoomOptions(roomOptions)
.withPublishRemoteOptions(remotePublishOptions)
.buildPublishToRoomOptions()
// Remaining code is the same as for local stream
✂ Unchanged content not shown
PhenixPublishToRoomOptionsBuilder
Name | Type | Default | Description |
---|---|---|---|
withRoomOptions (required) | PhenixRoomOptions | If omitted, then withRoomId needs to be provided. | |
withRoomId (required) | NSString | ID of room to publish to. If omitted, then withRoomOptions needs to be provided. | |
withPublishOptions _(required) _ | PhenixPublishOptions | Either local or remote publish options are required | |
withPublishRemoteOptions (required) | PhenixPublishRemoteOptions | Either local or remote publish options are required | |
withMemberRole (required) | PhenixMemberRole | Role of member to join room as (used if not already in room). See Member Roles | |
withStreamType (required) | PhenixStreamType | Type of stream to publish. See Stream Types | |
withScreenName (optional) | NSString | automatically generated | Screen name of self member |
withViewerStreamSelectionStrategy (optional) | PhenixStreamSelectionStrategy | PhenixStreamSelectionStrategyMostRecent | Stream Selection Strategy |
withWildcardTokens (optional) | true | Generate wildcard stream tokens to be appended to member's stream uri. Reduces time for subscribing to published stream. | |
buildPublishToRoomOptions | none | Builds the PhenixPublishToRoomOptions |
PCast
Newer versions of PCast™ do not support certain arguments in
- PhenixPCastOptionsBuilder
- PublishOptionsBuilder
- SubscribeOptionsBuilder
Using these arguments with the newer SDK will result in a failure such as unrecognised option
.
Some APIs, such as Publishing Remote Media (Ingest), are not supported by newer versions of the SDK.
In addition, token arguments are required when using the newer SDK (e.g., withStreamToken
or withAuthenticationToken
), and not including tokens will result in a failure such as bad-request
.
Connect And Authenticate
Beta version: Connect and Authenticate
Current version:
@import PhenixSdk;
// Generated via EdgeAuth library
NSString* authenticationToken = ...;
// Previously initialized
id<PhenixPCast> pcast = ...;
[pcast start:
authenticationToken:
^(id<PhenixPCast> pcast, PhenixRequestStatus status, NSString* sessionId) {
if (status == PhenixRequestStatusOk) {
NSLog(@"PCast started...");
} else {
NSLog(@"Failed to start PCast...");
}
}:
^(id<PhenixPCast> pcast) {
NSLog(@"We are online...");
}:
^(id<PhenixPCast> pcast) {
NSLog(@"We are offline...");
}];
Authentication Parameters
Name | Type | Description |
---|---|---|
authenticationToken (required) | string | The authentication token generated using the Phenix EdgeAuth library |
authenticationCallback (required) | lambda (pcast, status, sessionId) | Called upon successful authentication or when authentication failed or has to be redone. Upon successful authentication, the authenticationCallback will be called with status=PhenixRequestStatusOk. If at any time a new authenticationToken is required, then the authenticationCallback is called with status=PhenixRequestStatusUnauthorized to indicate that we are no longer authenticated. |
onlineCallback (required) | lambda (pcast) | Called when the client is connected to the streaming platform |
offlineCallback (required) | lambda (pcast) | Called when the client is disconnected from the streaming platform. Ongoing streams may continue while we are temporarily disconnected. However, no new streams can be started while being disconnected. The client automatically tries to reconnect and will call onlineCallback when it succeeds in doing so or eventually call authenticationCallback to indicate that re-authentication is required. |
Authentication Callback Status Codes
Status | Valid Fields | Description |
---|---|---|
PhenixRequestStatusOk | sessionId | Authentication succeeded, the sessionId is populated |
PhenixRequestStatusUnauthorized | none | Authentication failed or re-authentication required |
varies | none | Authentication failed for other reasons |
Get Local User Media
Beta version: Get Local User Media
Current version:
@import PhenixSdk;
// Previously initialized and started
id<PhenixPCast> pcast = ...;
PhenixUserMediaOptions* gumOptions = [PhenixUserMediaOptions new]
// Customize options if desired
gumOptions.video.capabilityConstraints
[[NSNumber numberWithInteger:PhenixDeviceCapabilityFacingMode]] =
@[ [PhenixDeviceConstraint initWithFacingMode:PhenixFacingModeUser] ];
gumOptions.video.capabilityConstraints
[[NSNumber numberWithInteger: PhenixDeviceCapabilityFlashMode]] =
@[ [PhenixDeviceConstraint initWithFlashMode:PhenixFlashModeAlwaysOff] ];
gumOptions.video.capabilityConstraints
[[NSNumber numberWithInteger: PhenixDeviceCapabilityHeight]] =
@[ [PhenixDeviceConstraint initWithDouble:720:PhenixConstraintTypeExact] ];
gumOptions.video.capabilityConstraints
[[NSNumber numberWithInteger: PhenixDeviceCapabilityWidth]] =
@[ [PhenixDeviceConstraint initWithDouble:800:PhenixConstraintTypeMin],
[PhenixDeviceConstraint initWithDouble:1500:PhenixConstraintTypeMax] ];
gumOptions.audio.enabled = NO;
[pcast getUserMedia:
gumOptions:
^(id<PhenixPCast> pcast,
PhenixRequestStatus status,
id<PhenixUserMediaStream> userMediaStream) {
// Check status and store 'userMediaStream'
}];
Get Local User Media Parameters
Name | Type | Description |
---|---|---|
options (required) | PhenixUserMediaOptions | The options defining the requested user media stream |
userMediaCallback (required) | lambda (pcast, status, userMediaStream) | Upon acquiring of the user media stream, the userMediaCallback will be called with status=PhenixRequestStatusOk. If the user media is currently used by another application, then you may receive a code status=PhenixRequestStatusConflict . If the operation fails with status=PhenixRequestStatusFailed then please check the logs for more information |
Device Capability
Note: iPhone models earlier than the iPhone 6 will be limited to publishing at 720p due to hardware limitations.
Name | Description |
---|---|
PhenixDeviceCapabilityWidth | Width in pixels |
PhenixDeviceCapabilityHeight | Height in pixels |
PhenixDeviceCapabilityFrameRate | Number of frames per second |
PhenixDeviceCapabilityFacingMode | Facing mode |
PhenixDeviceCapabilityFlashMode | Flash mode |
PhenixDeviceCapabilityDeviceId | Device ID string (obtain from here) |
PhenixDeviceCapabilityLocation | Device Location |
PhenixDeviceCapabilityPolarPattern | Polar pattern |
PhenixDeviceCapabilityAudioEchoCancelationMode | Audio echo cancelation mode |
PhenixVideoSourceRotationMode | Video source rotation mode |
Constraint Type
Name | Description |
---|---|
PhenixConstraintTypeMin | Hard constraint: Capability must have at least the specified value |
PhenixConstraintTypeMax | Hard constraint: Capability must have at most the specified value |
PhenixConstraintTypeExact | Hard constraint: Capability must have exactly the specified value |
PhenixConstraintTypeIdeal | Soft constraint: Capability should have specified value, but other values are acceptable (default) |
Facing Mode
Name | Description |
---|---|
PhenixFacingModeAutomatic | Select a facing mode automatically (default) |
PhenixFacingModeEnvironment | Facing the surrounding environment (e.g., back camera) |
PhenixFacingModeUser | Facing the user (e.g., front camera) |
Flash Mode
Only applicable to video devices
Name | Description |
---|---|
PhenixFlashModeAutomatic | Flash is turned on automatically when needed (default) |
PhenixFlashModeAlwaysOn | Flash is on (if available) |
PhenixFlashModeAlwaysOff | Flash is off |
Device Location
Name | Description |
---|---|
PhenixLocationAutomatic | Select any device (default) |
PhenixLocationUpper | Mounted on top of phone/tablet |
PhenixLocationLower | Mounted at bottom of phone/tablet |
Polar Pattern
Only applicable to audio devices
Name | Description |
---|---|
PhenixPolarPatternAutomatic | Automatically select pattern (default) |
PhenixPolarPatternOmnidirectional | Equally sensitive to sound from any direction |
PhenixPolarPatternCardioid | Most sensitive to sound from the direction in which the data source points and is (nearly) insensitive to sound from the opposite direction |
PhenixPolarPatternSubcardioid | Most sensitive to sound from the direction in which the data source points and is less sensitive to sound from the opposite direction |
Audio Echo Cancelation Mode
Only applicable to audio devices
Name | Description |
---|---|
PhenixAudioEchoCancelationModeAutomatic | Automatically select AEC (default) |
PhenixAudioEchoCancelationModeOn | Enable AEC if available |
PhenixAudioEchoCancelationModeOff | Disabled AEC |
Video source rotation mode
Only applicable to video devices. Determines how to orient captured video frames.
Follow device rotation will ensure that video frames match the orientation in which the user is holding the device, regardless of how the app UI may be oriented. This is generally the behavior expected by a user, i.e. if the user is holding the device sideways, then video should be in landscape mode.
Following UI rotation allows your app to keep the video orientation locked to the UI rotation, regardless of how the user is holding the device. This makes it possible for instance to lock your UI in portrait mode, and have portrait video output even if the user is holding the device sideways.
Name | Description |
---|---|
PhenixVideoSourceRotationModeAutomatic | Automatically select rotation mode (default) |
PhenixVideoSourceRotationModeFollowDeviceRotation | Video frames oriented according to how device is held |
PhenixVideoSourceRotationModeFollowUiRotation | Video frames oriented according to UI orientation |
Updating Options
Sometimes you find it useful to change the camera while a stream is running or just would like to turn on the flash light temporarily.
@import PhenixSdk;
// Previously obtained via 'getUserMedia'
id<PhenixUserMediaStream> userMediaStream = ...;
// Previously initialized and used with 'getUserMedia'
PhenixUserMediaOptions* gumOptions;
[gumOptions.video.capabilityConstraints
[[NSNumber numberWithInteger:PhenixDeviceCapabilityFacingMode]][0]
updateFacingMode:PhenixFacingModeEnvironment];
gumOptions.video.capabilityConstraints
[[NSNumber numberWithInteger:PhenixDeviceCapabilityFlashMode]][0]
updateFlashMode: PhenixFlashModeAlwaysOn];
[userMediaStream applyOptions:gumOptions];
Room
Newer versions of Room do not support certain arguments in some APIs, and other APIs have been deprecated, such as
- createRoom
- destroyRoom
Newer versions of Room do not support wildcard tokens in the PhenixPublishToRoomOptionsBuilder.
Initializing Room
Beta version: Initializing
Current version:
First you will need to initialize a room service object. This object is used for creating, joining, and leaving a room. As well, use this object for managing the room you enter (active room), members, and the model of your Self.
Note: PhenixPCast must be initialized and started when invoking createRoomService
so that a valid session ID is present.
import PhenixSdk
let pcast: PhenixPCast = ... // previously obtained
let roomService = PhenixRoomServiceFactory.createRoomService(pcast)!
Initializing Parameters
Name | Type | Description |
---|---|---|
pcast (required) | PhenixPCast | Instantiated PCast™ object. Must already be authenticated |
PhenixRoomService
Name | Signature | Returns | Description |
---|---|---|---|
getRoomInfo | (roomId, alias, callback) | PhenixRoom | See Get Room Info |
createRoom | (room, callback) | PhenixRoom | See Create a Room |
joinRoom | (roomId, alias, callback) | PhenixRoom | See Join a Room |
leaveRoom | (callback) | void | See Leave a Room |
destroyRoom | (callback) | void | See Destroy a Room |
getSelf | () | Observable of PhenixMember | Observable of self member |
getObservableActiveRoom | () | Observable of PhenixRoom | Observable of the active room |
Get Room Info
Beta version: Getting Room info is no longer supported by the iOS SDK.
Current version:
Get room info with the provided room details without joining the room.
import PhenixSdk
let roomService: PhenixRoomService = ... // previously obtained
// Either provide alias or roomId, other can be nil or empty
let roomId = "us-central#demo#exampleRoomId"
let alias: String? = nil
roomService.getRoomInfo(
roomId,
alias,
{ (roomService: PhenixRoomService?, status: PhenixRequestStatus, room: PhenixRoom?) in
if status == .ok {
// Do something with room
} else {
// Handle error
}
})
Get Room Info Parameters
Name | Type | Description |
---|---|---|
roomId (required) | String | ID of the room |
alias (optional) | String | Alternative to roomId - alias of the room |
getRoomInfoCallback (required) | Function | Callback with the status of the request and the room model |
Get Room Info Callback Arguments
Name | Type | Description |
---|---|---|
roomService | PhenixRoomService | The room service making the callback |
status | PhenixRequestStatus | The status of the operation |
room | PhenixRoom | Immutable room object |
Get Room Info Callback Status Codes
Status | Description |
---|---|
ok | Get room info succeeded |
not-found | Get room info failed. Room does not exist - verify room data or create the room |
varies | Get room info failed for other reasons |
Create a Room (deprecated)
Beta version: Creating a Room info is no longer supported by the iOS SDK. Rooms should be created by the backend using the REST API.
Current version:
Creation of Rooms from client SDKs is deprecated. Rooms should be created by the backend using the REST API.
Create a room with the provided details
import PhenixSdk
let roomService: PhenixRoomService = ... // previously obtained
let roomName = "My Room Name"
let description = "Deep thoughts only"
let roomOptions = PhenixRoomServiceFactory.createRoomOptionsBuilder()
.withName(roomName)
.withDescription(description)
.withType(.multiPartyChat)
.buildRoomOptions()
roomService.createRoom(
roomOptions,
{ (roomService: PhenixRoomService?, status: PhenixRequestStatus, room: PhenixRoom?) in
if status == .ok {
// Do something with room
} else {
// Handle error
}
})
Create Room Parameters
Name | Type | Description |
---|---|---|
options (required) | PhenixRoomOptions | Room creation options |
callback (required) | Function | Callback with the status of the request and the room model |
Create Room Callback Arguments
Name | Type | Description |
---|---|---|
roomService | PhenixRoomService | The room service making the callback |
status | PhenixRequestStatus | The status of the operation |
room | PhenixRoom | Immutable room object |
Create Room Callback Status Codes
Status | Description |
---|---|
PhenixRequestStatusOk | Create room succeeded. This can also mean that the room already existed |
varies | Create room failed for other reasons |
PhenixRoomOptionsBuilder
Name | Type | Default | Description |
---|---|---|---|
withName (required) | String | Name of room | |
withType (required) | PhenixRoomType | Room type | |
withAlias (optional) | String | generated | Room Alias |
withDescription (optional) | String | empty | Room description |
buildRoomOptions | none | Builds the PhenixRoomOptions |
Join a Room (Low-Level)
Beta version: Joining a Room info is no longer supported by the Low-Level iOS APIs. Use the Room Express API to join a Room.
Current version:
Join a room with the Self model. After successfully joining a room that room becomes the active room and can be returned via the getObservableActiveRoom method.
import PhenixSdk
let roomService: PhenixRoomService = ... // previously obtained
// Need to provide either room ID or alias (other can be nil)
let roomId: String? = nil
let alias = "exampleRoom"
roomService.joinRoom(
roomId,
alias,
{ (roomService: PhenixRoomService?, status: PhenixRequestStatus, room: PhenixRoom?) in
if status == .ok {
// Do something with room
} else {
// Handle error
}
})
Join Room Parameters
Name | Type | Description |
---|---|---|
roomId (required) | String | ID of the room |
alias (optional) | String | Alternative to roomId - alias of the room |
callback (required) | Function | Callback with the status of the request and the room model |
Join Room Callback Arguments
Name | Type | Description |
---|---|---|
roomService | PhenixRoomService | The room service making the callback |
status | PhenixRequestStatus | The status of the operation |
room | PhenixRoom | Immutable room object |
Join Room Callback Status Codes
Status | Description |
---|---|
ok | Join room succeeded |
not-found | Join room failed. Room does not exist - create room first |
varies | Join room failed for other reasons |
Destroy a Room
Beta version: Destroying or deleting a Room info is no longer supported by the iOS SDK. Rooms should be deleted by the backend using the REST API.
Current version:
Destroys the current active room assuming your self member has the permissions.
import PhenixSdk
let roomService: PhenixRoomService = ... // previously obtained
roomService.destroyRoom({ (roomService: PhenixRoomService?, status: PhenixRequestStatus) in
if status == .ok {
// Successfully destroyed room, no action required
} else {
// Handle error
}
})
Destroy Room Parameters
Name | Type | Description |
---|---|---|
callback (required) | Function | Callback with the status of the request |
Destroy Room Callback Arguments
Name | Type | Description |
---|---|---|
roomService | PhenixRoomService | The room service making the callback |
status | PhenixRequestStatus | The status of the operation |
Destroy Room Callback Status Codes
Status | Description |
---|---|
ok | Destroy room succeeded |
varies | Destroy room failed for other reasons |