Room Express
Single-step configuration based API for setting up a room - a solution for all your other streaming applications including Group Broadcast, Group Chat, and One to One Chat. The Room Express extends the lower-level Room Service API to provide easy solutions to:
- Join, create, and publish to a room
- Subscribe to streams of members in a room
Initializing
1import android.content.Context;2import com.phenixrts.common.RequestStatus;3import com.phenixrts.environment.android.AndroidContext;4import com.phenixrts.express.PCastExpress;5import com.phenixrts.express.PCastExpressFactory;6import com.phenixrts.express.PCastExpressOptions;7import com.phenixrts.express.RoomExpress;8import com.phenixrts.express.RoomExpressFactory;9import com.phenixrts.express.RoomExpressOptions;10import com.phenixrts.pcast.PCastInitializeOptions;1112// IMPORTANT: Before accessing any of the static factories, make sure the context is passed to Phenix:13final Context context = ...; // e.g. Activity.getApplication();14AndroidContext.setContext(context);1516final PCastExpressOptions pcastExpressOptions =17 PCastExpressFactory.createPCastExpressOptionsBuilder()18 .withBackendUri("https://example.yourdomain.com/phenix/")19 .withUnrecoverableErrorCallback((RequestStatus status, String description) -> {20 // Best to restart app, or attempt to re-create PCastExpress21 })22 .buildPCastExpressOptions();2324final RoomExpressOptions roomExpressOptions =25 RoomExpressFactory.createRoomExpressOptionsBuilder()26 .withPCastExpressOptions(pcastExpressOptions)27 .buildPCastExpressOptions();2829final RoomExpress roomExpress = RoomExpressFactory.createRoomExpress(roomExpressOptions);
RoomExpressOptionsBuilder
Name | Type | Default | Description |
---|---|---|---|
withPCastExpressOptions (required) | PCastExpressOptions | See PCastExpressOptionsBuilder | |
buildRoomExpressOptions | none | Builds the RoomExpressOptions |
Join a Room
Join a room and optionally, automatically subscribe to member changes.
1import com.phenixrts.common.RequestStatus;2import com.phenixrts.express.JoinRoomOptions;3import com.phenixrts.express.RoomExpress;4import com.phenixrts.express.RoomExpressFactory;5import com.phenixrts.room.Member;6import com.phenixrts.room.RoomService;78final RoomExpress roomExpress = ...; // previously obtained910final JoinRoomOptions joinRoomOptions = RoomExpressFactory.createJoinRoomOptionsBuilder()11 .withRoomAlias("myRoom42")12 .withCapabilities(new String[] {"streaming"})13 .buildJoinRoomOptions();1415roomExpress.joinRoom(joinRoomOptions, (RequestStatus status, RoomService roomService) -> {16 if (status == RequestStatus.OK) {17 // Hold on to roomService reference for as long as you wish to stay in the room18 } else {19 // Handle error20 }21});2223// With optional member update notification:24this.roomExpress.joinRoom(25 joinRoomOptions,26 (RequestStatus status, RoomService roomService) -> {27 if (status == RequestStatus.OK) {28 // Hold on to roomService reference for as long as you wish to stay in the room29 } else {30 // Handle error31 }32 },33 (Member[] members) -> {34 // Do something with room members35 });
Express Join Room Parameters
Name | Type | Description |
---|---|---|
options (required) | JoinRoomOptions | Options to join room with |
joinRoomCallback (required) | RoomExpress.JoinRoomCallback | Function to call on success/failure of joining the room |
membersChangedCallback (optional) | RoomExpress.MembersChangedCallback | Function to call on when the participant members in the room changes. Returns array of Members. Callback is guaranteed to be called at least once when room is joined. |
JoinRoomOptionsBuilder
Name | Type | Default | Description |
---|---|---|---|
withRoomId (required) | String | Id of channel to view | |
withRoomAlias (optional) | String | Alias, alternative to ID | |
withCapabilities (required) | String[] | The list of all capabilities to subscribe with. | |
withRole (optional) | MemberRole | MemberRole.AUDIENCE | The Member Role to join with |
withScreenName (optional) | String | The member screen name to join with. A random string will be generated if not provided. | |
withStreams (optional) | Stream[] | [] | The member streams to join with. Empty if not provided |
buildJoinRoomOptions | none | Builds the JoinRoomOptions |
Express Join Room Callback Arguments
Name | Type | Description |
---|---|---|
status | RequestStatus | The status of the operation. |
roomService | RoomService | Phenix room service object |
Subscribe to a Member's Stream
Subscribe to a room member's stream and automatically handle audio and video state changes.
1import android.view.SurfaceView;2import com.phenixrts.common.RequestStatus;3import com.phenixrts.express.RoomExpress;4import com.phenixrts.express.RoomExpressFactory;5import com.phenixrts.express.SubscribeToMemberStreamOptions;6import com.phenixrts.room.ImmutableRoom;7import com.phenixrts.room.Member;8import com.phenixrts.room.Stream;9import com.phenixrts.pcast.android.AndroidVideoRenderSurface;1011final RoomExpress roomExpress = ...; // previously obtained12final ImmutableRoom room = ...; // previously obtained13final SurfaceView view = ...; // previously obtained1415final AndroidVideoRenderSurface renderSurface = new AndroidVideoRenderSurface(view.getHolder());1617// Just an example showing how to get a stream from a member.18// In a real-world app you would want to subscribe to the room-members-observable on the room19// to receive updates when the list of members changes, and then subscribe to the streams-observable20// on each member to access their streams.21final Member member = room.getObservableMembers().getValue()[0];22final Stream memberStream = member.getObservableStreams().getValue()[0];2324final SubscribeToMemberStreamOptions options =25 RoomExpressFactory.createSubscribeToMemberStreamOptionsBuilder()26 .withRenderer(renderSurface)27 .buildSubscribeToMemberStreamOptions();2829roomExpress.subscribeToMemberStream(30 memberStream,31 options,32 (status, subscriber, renderer) -> {33 if (status != RequestStatus.OK) {34 // Handle subscribe error35 return;36 }3738 // Important: Store subscriber reference, otherwise we will stop subscription immediately:39 //currentSubscriber = subscriber;40 });
Subscribe To Member Stream Parameters
Name | Type | Description |
---|---|---|
memberStream (required) | Stream | The room member's stream to subscribe to |
options (required) | Subscribe to Member's Stream Options | PCast™ Express Subscribe Options to subscribe to member stream with |
callback (required) | Function | Function to call on success/failure of subscribing to the member stream |
SubscribeToMemberStreamOptionsBuilder
Name | Type | Default | Description |
---|---|---|---|
withCapabilities (optional) | String[] | [] | The list of all capabilities to subscribe with |
withRenderer (optional) | AndroidVideoRenderSurface | none | Render surface 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) | RendererOptions | none | Options passed to renderer. Will trigger instantiation of renderer |
withMonitor (optional) | MonitorOptions.SetupFailedCallback, MonitorOptions.StreamEndedCallback, MonitorOptions | none | Options for monitoring a subscriber for failure |
withConnectOptions (optional) | String[] | [] | List of options for subscribing |
withTags (optional) | String[] | [] | Tags for the stream |
buildSubscribeToMemberStreamOptions | none | Builds the SubscribeToMemberStreamOptions |
Subscribe To Member Stream Callback Arguments
Name | Type | Description |
---|---|---|
status | RequestStatus | The status of the operation. |
publisher | Subscriber | Phenix subscriber object |
renderer | Renderer | Optional renderer if renderer was enabled, else nil |
Publish to a Room
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.
1import android.view.SurfaceView;2import com.phenixrts.common.RequestStatus;3import com.phenixrts.express.PCastExpressFactory;4import com.phenixrts.express.PublishOptions;5import com.phenixrts.express.PublishRemoteOptions;6import com.phenixrts.express.PublishToRoomOptions;7import com.phenixrts.express.RoomExpress;8import com.phenixrts.express.RoomExpressFactory;9import com.phenixrts.pcast.DeviceCapability;10import com.phenixrts.pcast.FacingMode;11import com.phenixrts.pcast.RendererOptions;12import com.phenixrts.pcast.UserMediaOptions13import com.phenixrts.pcast.android.AndroidVideoRenderSurface;14import com.phenixrts.room.MemberRole;15import com.phenixrts.room.RoomOptions;16import com.phenixrts.room.RoomServiceFactory;17import com.phenixrts.room.StreamType;1819final RoomExpress roomExpress = ...; // previously obtained20final SurfaceView view = ...; // previously obtained2122final AndroidVideoRenderSurface renderSurface = new AndroidVideoRenderSurface(view.getHolder());2324final UserMediaOptions mediaConstraints = new UserMediaOptions();25// Customize constraints if needed2627final PublishOptions publishOptions = PCastExpressFactory.createPublishOptionsBuilder()28 .withCapabilities(new String[]{"hd", "streaming"})29 .withMediaConstraints(mediaConstraints)30 .withPreviewRenderer(renderSurface)31 .buildPublishOptions();3233// Using RoomOptions means that the room may or may not already exist.34// If the room ID is known in advance, it is recommended to use `withRoomId` instead35// of `withRoomOptions` when assembling the `PublishToRoomOptions` below36final RoomOptions roomOptions = RoomServiceFactory.createRoomOptionsBuilder()37 .withName("MyAwesomeRoom")38 .buildRoomOptions();3940final PublishToRoomOptions localPublishToRoomOptions =41 RoomExpressFactory.createPublishToRoomOptionsBuilder()42 .withStreamType(StreamType.USER)43 .withMemberRole(MemberRole.PARTICIPANT)44 .withRoomOptions(roomOptions)45 .withPublishOptions(publishOptions)46 .buildPublishToRoomOptions();4748roomExpress.publishToRoom(49 localPublishToRoomOptions,50 (publishStatus, roomService, publisher, previewRenderer) -> {51 if (publishStatus != RequestStatus.OK) {52 // Handle channel publish error53 return;54 }5556 // Important: Store publisher reference, otherwise we will stop publishing again immediately:57 currentPublisher = publisher;58 }59);6061// OR for a remote stream:62final PublishRemoteOptions remotePublishOptions = PCastExpressFactory63 .createPublishRemoteOptionsBuilder()64 .withStreamUri("http://example.com/mystream.mp4")65 .buildPublishRemoteOptions();6667final PublishToRoomOptions remotePublishToRoomOptions =68 RoomExpressFactory.createPublishToRoomOptionsBuilder()69 .withStreamType(StreamType.USER)70 .withMemberRole(MemberRole.PARTICIPANT)71 .withRoomOptions(roomOptions)72 .withPublishRemoteOptions(remotePublishOptions)73 .buildPublishToRoomOptions();7475// Remaining code is the same as for local stream
Publish To Room Parameters
Name | Type | Description |
---|---|---|
options (required) | Options | Options to publish to room with |
callback (required) | Function | Function to call on success/failure of publishing to the room |
PublishToRoomOptionsBuilder
Name | Type | Default | Description |
---|---|---|---|
withRoomOptions (required) | RoomOptions | If omitted, then withRoomId needs to be provided. | |
withRoomId (required) | String | ID of room to publish to. If omitted, then withRoomOptions needs to be provided. | |
withPublishOptions (required) | PublishOptions | Either local or remote publish options are required | |
withPublishRemoteOptions (required) | PublishRemoteOptions | Either local or remote publish options are required | |
withMemberRole (required) | MemberRole | Role of member to join room as (used if not already in room). See Member Roles | |
withStreamType (required) | StreamType | Type of stream to publish. See Stream Types | |
withScreenName (optional) | String | automatically generated | Screen name of self member |
withViewerStreamSelectionStrategy (optional) | StreamSelectionStrategy | StreamSelectionStrategy.MOST_RECENT | Stream Selection Strategy |
buildPublishToRoomOptions | none | Builds the PublishToRoomOptions |
Publish To Room Callback Arguments
Name | Type | Description |
---|---|---|
status | RequestStatus | The status of the operation. |
roomService | RoomService | Phenix room service |
publisher | Publisher | Phenix publisher object |
previewRenderer | Renderer | Optional renderer if preview renderer was enabled |
Get PCast™ Express
Get the underlying instance of the PCast™ Express. This is preferred to creating another instance as this will introduce more overhead.
1import com.phenixrts.express.PCastExpress;2import com.phenixrts.express.RoomExpress;34final RoomExpress roomExpress = ...; // previously obtained56final PCastExpress pcastExpress = roomExpress.getPCastExpress();
Clean Up
Underlying resources are kept alive for as long as you hold any references to any of the returned objects (room service, subscriber, renderer) an do not call close
on them. Once those references as well as any reference to the room express instance itself have been released (or close
has been called), all underlying resources will be automatically cleaned up and released.