diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index f8a4c5fb..b8d3c2fd 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -223,8 +223,8 @@ jobs: if: github.ref == 'refs/heads/master' run: ./gradlew publish env: - OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }} - OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} + CENTRAL_USERNAME: ${{ secrets.CENTRAL_USERNAME }} + CENTRAL_PASSWORD: ${{ secrets.CENTRAL_PASSWORD }} SIGNING_KEY_ID: ${{ secrets.SIGNING_KEY_ID }} SIGNING_PASSWORD: ${{ secrets.SIGNING_PASSWORD }} SIGNING_KEY: ${{ secrets.SIGNING_KEY }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 78e37fc2..4a30c7d4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,8 +18,8 @@ jobs: - name: Deploy to Sonatype run: ./gradlew publish env: - OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }} - OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} + CENTRAL_USERNAME: ${{ secrets.CENTRAL_USERNAME }} + CENTRAL_PASSWORD: ${{ secrets.CENTRAL_PASSWORD }} SIGNING_KEY_ID: ${{ secrets.SIGNING_KEY_ID }} SIGNING_PASSWORD: ${{ secrets.SIGNING_PASSWORD }} SIGNING_KEY: ${{ secrets.SIGNING_KEY }} \ No newline at end of file diff --git a/scripts/deploy-variables.gradle b/scripts/deploy-variables.gradle index 189b025d..1d436c6b 100644 --- a/scripts/deploy-variables.gradle +++ b/scripts/deploy-variables.gradle @@ -1,8 +1,8 @@ ext["signing.keyId"] = '' ext["signing.password"] = '' ext["signing.key"] = '' -ext["ossrhUsername"] = '' -ext["ossrhPassword"] = '' +ext["centralUsername"] = '' +ext["centralPassword"] = '' ext["sonatypeStagingProfileId"] = '' File secretPropsFile = project.rootProject.file('local.properties') @@ -13,8 +13,8 @@ if (secretPropsFile.exists()) { p.each { name, value -> ext[name] = value } } else { // Use system environment variables - ext["ossrhUsername"] = System.getenv('OSSRH_USERNAME') - ext["ossrhPassword"] = System.getenv('OSSRH_PASSWORD') + ext["centralUsername"] = System.getenv('CENTRAL_USERNAME') + ext["centralPassword"] = System.getenv('CENTRAL_PASSWORD') ext["signing.keyId"] = System.getenv('SIGNING_KEY_ID') ext["signing.password"] = System.getenv('SIGNING_PASSWORD') ext["signing.key"] = System.getenv('SIGNING_KEY') diff --git a/webrtc-android-framework/publish-remote.gradle b/webrtc-android-framework/publish-remote.gradle index 58a530d0..639f9393 100644 --- a/webrtc-android-framework/publish-remote.gradle +++ b/webrtc-android-framework/publish-remote.gradle @@ -71,12 +71,12 @@ afterEvaluate { repositories { maven { credentials { - username ossrhUsername - password ossrhPassword + username centralUsername + password centralPassword } - def releasesRepoUrl = 'https://oss.sonatype.org/service/local/repositories/releases/content' - def snapshotsRepoUrl = 'https://oss.sonatype.org/content/repositories/snapshots' + def releasesRepoUrl = "https://ossrh-staging-api.central.sonatype.com/service/local/staging/deploy/maven2/" + def snapshotsRepoUrl = "https://central.sonatype.com/repository/maven-snapshots/" url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl } } diff --git a/webrtc-android-framework/src/main/java/io/antmedia/webrtcandroidframework/api/DefaultWebRTCListener.java b/webrtc-android-framework/src/main/java/io/antmedia/webrtcandroidframework/api/DefaultWebRTCListener.java index 091a962b..4feca6a7 100644 --- a/webrtc-android-framework/src/main/java/io/antmedia/webrtcandroidframework/api/DefaultWebRTCListener.java +++ b/webrtc-android-framework/src/main/java/io/antmedia/webrtcandroidframework/api/DefaultWebRTCListener.java @@ -10,6 +10,7 @@ import de.tavendo.autobahn.WebSocket; import io.antmedia.webrtcandroidframework.core.StreamInfo; import io.antmedia.webrtcandroidframework.websocket.Broadcast; +import io.antmedia.webrtcandroidframework.websocket.Subscriber; /** * Default implementation of {@link IWebRTCListener} @@ -280,4 +281,16 @@ protected void callbackCalled(String messageText) { Log.d(DefaultWebRTCListener.class.getName(), messageText); } + @Override + public void onSubscriberCount(String streamId, int count) { + String messageText = "On Subscriber Count "+streamId; + callbackCalled(messageText); + } + + @Override + public void onSubscriberList(String streamId, Subscriber[] subscribers) { + String messageText = "On Subscriber List "+streamId; + callbackCalled(messageText); + } + } \ No newline at end of file diff --git a/webrtc-android-framework/src/main/java/io/antmedia/webrtcandroidframework/api/IWebRTCClient.java b/webrtc-android-framework/src/main/java/io/antmedia/webrtcandroidframework/api/IWebRTCClient.java index 78362306..9ac35367 100644 --- a/webrtc-android-framework/src/main/java/io/antmedia/webrtcandroidframework/api/IWebRTCClient.java +++ b/webrtc-android-framework/src/main/java/io/antmedia/webrtcandroidframework/api/IWebRTCClient.java @@ -86,6 +86,13 @@ void publish(String streamId, String token, boolean videoCallEnabled, boolean au */ void play(String streamId, String token, String[] tracks, String subscriberId, String subscriberCode, String viewerInfo); + /** + * This is used to play a WebRTC stream with a parameter object + * + * @param params the play parameters + */ + void play(PlayParams params); + /** * This is used to join a peer to peer call * @@ -368,4 +375,26 @@ void publish(String streamId, String token, boolean videoCallEnabled, boolean au */ boolean isSendVideoEnabled(); + /** + * Called to get the subscriber count for a broadcast + * + * @param streamId: id for the broadcast + */ + void getSubscriberCount(String streamId); + + /** + * Called to get the subscriber list for a broadcast + * + * @param streamId: id for the broadcast + * @param offset: offset of the list + * @param size: size of the list + */ + void getSubscriberList(String streamId, long offset, long size); + + /** + * Called to get the debug info for the viewer + * + * @param streamId: id for the broadcast + */ + void getDebugInfo(String streamId); } diff --git a/webrtc-android-framework/src/main/java/io/antmedia/webrtcandroidframework/api/IWebRTCListener.java b/webrtc-android-framework/src/main/java/io/antmedia/webrtcandroidframework/api/IWebRTCListener.java index f38a3558..6c6791b4 100644 --- a/webrtc-android-framework/src/main/java/io/antmedia/webrtcandroidframework/api/IWebRTCListener.java +++ b/webrtc-android-framework/src/main/java/io/antmedia/webrtcandroidframework/api/IWebRTCListener.java @@ -7,6 +7,7 @@ import de.tavendo.autobahn.WebSocket; import io.antmedia.webrtcandroidframework.core.StreamInfo; import io.antmedia.webrtcandroidframework.websocket.Broadcast; +import io.antmedia.webrtcandroidframework.websocket.Subscriber; /** * Created by karinca on 23.10.2017. @@ -251,4 +252,15 @@ public interface IWebRTCListener { * It's called when user left P2P room. */ void onLeft(String streamId); + + + /** + * It's called when Subscriber Count received. + */ + void onSubscriberCount(String streamId, int count); + + /** + * It's called when Subscriber List received. + */ + void onSubscriberList(String streamId, Subscriber[] subscribers); } diff --git a/webrtc-android-framework/src/main/java/io/antmedia/webrtcandroidframework/api/PlayParams.java b/webrtc-android-framework/src/main/java/io/antmedia/webrtcandroidframework/api/PlayParams.java new file mode 100644 index 00000000..f3efbbef --- /dev/null +++ b/webrtc-android-framework/src/main/java/io/antmedia/webrtcandroidframework/api/PlayParams.java @@ -0,0 +1,54 @@ +package io.antmedia.webrtcandroidframework.api; + +public class PlayParams { + private String streamId; + private String token; + private String[] tracks; + private String subscriberId; + private String subscriberName; // new field + private String subscriberCode; + private String viewerInfo; + private boolean disableTracksByDefault; // new field + + // Constructors + public PlayParams() {} + + public PlayParams(String streamId, String token, String[] tracks, + String subscriberId, String subscriberName, + String subscriberCode, String viewerInfo, + boolean disableTracksByDefault) { + this.streamId = streamId; + this.token = token; + this.tracks = tracks; + this.subscriberId = subscriberId; + this.subscriberName = subscriberName; + this.subscriberCode = subscriberCode; + this.viewerInfo = viewerInfo; + this.disableTracksByDefault = disableTracksByDefault; + } + + // Getters and Setters + public String getStreamId() { return streamId; } + public void setStreamId(String streamId) { this.streamId = streamId; } + + public String getToken() { return token; } + public void setToken(String token) { this.token = token; } + + public String[] getTracks() { return tracks; } + public void setTracks(String[] tracks) { this.tracks = tracks; } + + public String getSubscriberId() { return subscriberId; } + public void setSubscriberId(String subscriberId) { this.subscriberId = subscriberId; } + + public String getSubscriberName() { return subscriberName; } + public void setSubscriberName(String subscriberName) { this.subscriberName = subscriberName; } + + public String getSubscriberCode() { return subscriberCode; } + public void setSubscriberCode(String subscriberCode) { this.subscriberCode = subscriberCode; } + + public String getViewerInfo() { return viewerInfo; } + public void setViewerInfo(String viewerInfo) { this.viewerInfo = viewerInfo; } + + public boolean isDisableTracksByDefault() { return disableTracksByDefault; } + public void setDisableTracksByDefault(boolean disableTracksByDefault) { this.disableTracksByDefault = disableTracksByDefault; } +} diff --git a/webrtc-android-framework/src/main/java/io/antmedia/webrtcandroidframework/core/PermissionHandler.java b/webrtc-android-framework/src/main/java/io/antmedia/webrtcandroidframework/core/PermissionHandler.java index f3a2dabd..983f06d9 100644 --- a/webrtc-android-framework/src/main/java/io/antmedia/webrtcandroidframework/core/PermissionHandler.java +++ b/webrtc-android-framework/src/main/java/io/antmedia/webrtcandroidframework/core/PermissionHandler.java @@ -61,6 +61,10 @@ public static boolean checkCameraPermissions(Activity activity) { } public static boolean checkPublishPermissions(Activity activity, boolean bluetoothEnabled) { + return checkPublishPermissions(activity, bluetoothEnabled, true); + } + + public static boolean checkPublishPermissions(Activity activity, boolean bluetoothEnabled, boolean videoEnabled) { ArrayList permissions = new ArrayList<>(); permissions.addAll(Arrays.asList(REQUIRED_MINIMUM_PERMISSIONS)); permissions.addAll(Arrays.asList(PUBLISH_PERMISSIONS)); @@ -69,6 +73,10 @@ public static boolean checkPublishPermissions(Activity activity, boolean bluetoo permissions.addAll(Arrays.asList(BLUETOOTH_PERMISSIONS)); } + if(!videoEnabled) { + permissions.remove(Manifest.permission.CAMERA); + } + return hasPermissions(activity, permissions); } diff --git a/webrtc-android-framework/src/main/java/io/antmedia/webrtcandroidframework/core/StatsCollector.java b/webrtc-android-framework/src/main/java/io/antmedia/webrtcandroidframework/core/StatsCollector.java index 52e8b405..f11c4a9c 100644 --- a/webrtc-android-framework/src/main/java/io/antmedia/webrtcandroidframework/core/StatsCollector.java +++ b/webrtc-android-framework/src/main/java/io/antmedia/webrtcandroidframework/core/StatsCollector.java @@ -277,12 +277,16 @@ private void parseStats(RTCStatsReport report) { } if (value.getMembers().containsKey(FRAMES_RECEIVED)) { - long framesReceived = (long) value.getMembers().get(FRAMES_RECEIVED); + Number framesReceivedNumber = (Number) value.getMembers().get(FRAMES_RECEIVED); + long framesReceived = framesReceivedNumber.longValue(); + videoTrackStats.setFramesReceived(framesReceived); } if (value.getMembers().containsKey(FRAMES_DROPPED)) { - long framesDropped = (long) value.getMembers().get(FRAMES_DROPPED); + Number framesDroppedNumber = (Number) value.getMembers().get(FRAMES_DROPPED); + long framesDropped = framesDroppedNumber.longValue(); + videoTrackStats.setFramesDropped(framesDropped); } @@ -298,9 +302,14 @@ private void parseStats(RTCStatsReport report) { trackIdentifier = trackIdentifier.substring(VIDEO_TRACK_ID.length()); videoTrackStats.setTrackId(trackIdentifier); playStats.getVideoTrackStatsMap().put(trackIdentifier, videoTrackStats); + } else if (value.getMembers().containsKey(TRACK_ID)) { + String trackId = (String) value.getMembers().get(TRACK_ID); + RTCStats track = report.getStatsMap().get(trackId); + String trackIdentifier = (String) track.getMembers().get(TRACK_IDENTIFIER); + trackIdentifier = trackIdentifier.substring(VIDEO_TRACK_ID.length()); + videoTrackStats.setTrackId(trackIdentifier); + playStats.getVideoTrackStatsMap().put(trackIdentifier, videoTrackStats); } - - } } else if (AUDIO.equals(value.getMembers().get(KIND))) { if(value.getMembers().containsKey(SSRC)){ @@ -333,6 +342,14 @@ private void parseStats(RTCStatsReport report) { audioTrackStat.setTrackId(trackIdentifier); playStats.getAudioTrackStatsMap().put(trackIdentifier, audioTrackStat); } + else if (value.getMembers().containsKey(TRACK_ID)) { + String trackId = (String) value.getMembers().get(TRACK_ID); + RTCStats track = report.getStatsMap().get(trackId); + String trackIdentifier = (String) track.getMembers().get(TRACK_IDENTIFIER); + trackIdentifier = trackIdentifier.substring(AUDIO_TRACK_ID.length()); + audioTrackStat.setTrackId(trackIdentifier); + playStats.getAudioTrackStatsMap().put(trackIdentifier, audioTrackStat); + } } } diff --git a/webrtc-android-framework/src/main/java/io/antmedia/webrtcandroidframework/core/WebRTCClient.java b/webrtc-android-framework/src/main/java/io/antmedia/webrtcandroidframework/core/WebRTCClient.java index 872f0241..8e6c929f 100644 --- a/webrtc-android-framework/src/main/java/io/antmedia/webrtcandroidframework/core/WebRTCClient.java +++ b/webrtc-android-framework/src/main/java/io/antmedia/webrtcandroidframework/core/WebRTCClient.java @@ -82,10 +82,12 @@ import javax.annotation.Nullable; import io.antmedia.webrtcandroidframework.api.IWebRTCClient; +import io.antmedia.webrtcandroidframework.api.PlayParams; import io.antmedia.webrtcandroidframework.api.WebRTCClientConfig; import io.antmedia.webrtcandroidframework.apprtc.AppRTCAudioManager; import io.antmedia.webrtcandroidframework.websocket.AntMediaSignallingEvents; import io.antmedia.webrtcandroidframework.websocket.Broadcast; +import io.antmedia.webrtcandroidframework.websocket.Subscriber; import io.antmedia.webrtcandroidframework.websocket.WebSocketHandler; public class WebRTCClient implements IWebRTCClient, AntMediaSignallingEvents { @@ -178,10 +180,13 @@ public PeerInfo(String id, Mode mode) { public boolean videoCallEnabled; public boolean audioCallEnabled; public String subscriberId; + public String subscriberName; public String subscriberCode; public String streamName; public String mainTrackId; public String metaData; + public boolean disableTracksByDefault = false; + public boolean restartIce = false; public SessionDescription getLocalDescription() { @@ -983,7 +988,7 @@ private void publishPlayIfRequested() { if (peerMode == Mode.PLAY && peerInfo.peerConnection == null) { Log.i(TAG, "Processing play request for peer streamId: " + peerInfo.id); - wsHandler.startPlay(peerInfo.id, peerInfo.token, null, peerInfo.subscriberId, peerInfo.subscriberCode, peerInfo.metaData); + wsHandler.startPlay(peerInfo.id, peerInfo.token, null, peerInfo.subscriberId, peerInfo.subscriberName, peerInfo.subscriberCode, peerInfo.metaData, peerInfo.disableTracksByDefault); } } } @@ -1004,10 +1009,10 @@ public void publish(String streamId, String token, boolean videoCallEnabled, boo } }); - createPeerInfo(streamId, token, videoCallEnabled, audioCallEnabled, subscriberId, subscriberCode, streamName, mainTrackId, null, Mode.PUBLISH); + createPeerInfo(streamId, token, videoCallEnabled, audioCallEnabled, subscriberId, "", subscriberCode, streamName, mainTrackId, null, false, Mode.PUBLISH); init(); - if(!PermissionHandler.checkPublishPermissions(config.activity, config.bluetoothEnabled)){ + if(!PermissionHandler.checkPublishPermissions(config.activity, config.bluetoothEnabled, videoCallEnabled || this.config.videoCallEnabled)){ Toast.makeText(config.activity,"Publish permissions not granted. Cant publish.", Toast.LENGTH_LONG).show(); Log.e(TAG,"Publish permissions not granted. Cant publish."); return; @@ -1023,17 +1028,19 @@ public void publish(String streamId, String token, boolean videoCallEnabled, boo } } - private void createPeerInfo(String streamId, String token, boolean videoCallEnabled, boolean audioCallEnabled, String subscriberId, String subscriberCode, String streamName, String mainTrackId, String metaData, Mode mode) { + private void createPeerInfo(String streamId, String token, boolean videoCallEnabled, boolean audioCallEnabled, String subscriberId, String subscriberName, String subscriberCode, String streamName, String mainTrackId, String metaData, boolean disableTracksByDefault, Mode mode) { PeerInfo peerInfo; peerInfo = new PeerInfo(streamId, mode); peerInfo.token = token; peerInfo.videoCallEnabled = videoCallEnabled || config.videoCallEnabled; peerInfo.audioCallEnabled = audioCallEnabled || config.audioCallEnabled; peerInfo.subscriberId = subscriberId; + peerInfo.subscriberName = subscriberName; peerInfo.subscriberCode = subscriberCode; peerInfo.streamName = streamName; peerInfo.mainTrackId = mainTrackId; peerInfo.metaData = metaData; + peerInfo.disableTracksByDefault = disableTracksByDefault; peers.put(streamId, peerInfo); } @@ -1045,14 +1052,15 @@ public void play(String streamId, String[] tracks) { play(streamId, "", tracks, "", "", ""); } - public void play(String streamId, String token, String[] tracks, String subscriberId, String subscriberCode, String viewerInfo) { - Log.i(TAG, "Play: " + streamId); + @Override + public void play(PlayParams params) { + Log.i(TAG, "Play: " + params.getStreamId()); this.handler.post(() -> { if (config.webRTCListener != null) { - config.webRTCListener.onPlayAttempt(streamId); + config.webRTCListener.onPlayAttempt(params.getStreamId()); } }); - createPeerInfo(streamId, token, false, false, subscriberId, subscriberCode, "", "", viewerInfo, Mode.PLAY); + createPeerInfo(params.getStreamId(), params.getToken(), false, false, params.getSubscriberId(), params.getSubscriberName(), params.getSubscriberCode(), "", "", params.getViewerInfo(), params.isDisableTracksByDefault(), Mode.PLAY); if (!isReconnectionInProgress()) { init(); @@ -1066,16 +1074,21 @@ public void play(String streamId, String token, String[] tracks, String subscrib initializeAudioManager(); - Log.i(TAG, "Play: "+streamId); + Log.i(TAG, "Play: "+params.getStreamId()); if (isWebSocketConnected()) { - Log.i(TAG, "Play request sent through ws for stream: " + streamId); - wsHandler.startPlay(streamId, token, tracks, subscriberId, subscriberCode, viewerInfo); + Log.i(TAG, "Play request sent through ws for stream: " + params.getStreamId()); + wsHandler.startPlay(params.getStreamId(), params.getToken(), params.getTracks(), params.getSubscriberId(), params.getSubscriberName(), params.getSubscriberCode(), params.getViewerInfo(), params.isDisableTracksByDefault()); } else { Log.w(TAG, "Websocket is not connected. Set play requested. It will be processed when ws is connected."); } } + public void play(String streamId, String token, String[] tracks, String subscriberId, String subscriberCode, String viewerInfo) { + PlayParams params = new PlayParams(streamId, token, tracks, subscriberId, "", subscriberCode, viewerInfo, false); + play(params); + } + public void join(String streamId) { join(streamId, ""); } @@ -1370,18 +1383,18 @@ public void onIceDisconnected(String streamId) { config.webRTCListener.onIceDisconnected(streamId); } - if (streamStoppedByUser) { - release(true); - return; - } + if (streamStoppedByUser) { + release(true); + return; + } - if (config.reconnectionEnabled) { - rePublishPlay(); - } + if (config.reconnectionEnabled) { + rePublishPlay(); + } - if(isConference()){ - releaseRemoteRenderers(); - } + if (isConference()) { + releaseRemoteRenderers(); + } }); } @@ -2871,4 +2884,42 @@ public void setLocalAudioTrack(@androidx.annotation.Nullable AudioTrack localAud this.localAudioTrack = localAudioTrack; } + @Override + public void onSubscriberCount(String streamId, int count) { + this.handler.post(() -> { + if (config.webRTCListener != null) { + config.webRTCListener.onSubscriberCount(streamId, count); + } + }); + } + + @Override + public void onSubscriberList(String streamId, Subscriber[] subscribers) { + this.handler.post(() -> { + if (config.webRTCListener != null) { + config.webRTCListener.onSubscriberList(streamId, subscribers); + } + }); + } + + @Override + public void getSubscriberCount(String streamId) { + if (wsHandler != null && wsHandler.isConnected()) { + wsHandler.getSubscriberCount(streamId); + } + } + + @Override + public void getSubscriberList(String streamId, long offset, long size) { + if (wsHandler != null && wsHandler.isConnected()) { + wsHandler.getSubscriberList(streamId, offset, size); + } + } + + @Override + public void getDebugInfo(String streamId) { + if (wsHandler != null && wsHandler.isConnected()) { + wsHandler.getDebugInfo(streamId); + } + } } \ No newline at end of file diff --git a/webrtc-android-framework/src/main/java/io/antmedia/webrtcandroidframework/websocket/AntMediaSignallingEvents.java b/webrtc-android-framework/src/main/java/io/antmedia/webrtcandroidframework/websocket/AntMediaSignallingEvents.java index cbdfb403..b63d531e 100644 --- a/webrtc-android-framework/src/main/java/io/antmedia/webrtcandroidframework/websocket/AntMediaSignallingEvents.java +++ b/webrtc-android-framework/src/main/java/io/antmedia/webrtcandroidframework/websocket/AntMediaSignallingEvents.java @@ -152,4 +152,18 @@ public interface AntMediaSignallingEvents { * @param streamId Peer to peer room name/id. */ void onLeft(String streamId); + + /** + * It's called when subscriber count received from server + * @param streamId Stream Id + * @param count Count + */ + void onSubscriberCount(String streamId, int count); + + /** + * It's called when subscriber list received from server + * @param streamId Stream Id + * @param subscribers subscriber array + */ + void onSubscriberList(String streamId, Subscriber[] subscribers); } \ No newline at end of file diff --git a/webrtc-android-framework/src/main/java/io/antmedia/webrtcandroidframework/websocket/Subscriber.java b/webrtc-android-framework/src/main/java/io/antmedia/webrtcandroidframework/websocket/Subscriber.java new file mode 100644 index 00000000..8f82642a --- /dev/null +++ b/webrtc-android-framework/src/main/java/io/antmedia/webrtcandroidframework/websocket/Subscriber.java @@ -0,0 +1,59 @@ +package io.antmedia.webrtcandroidframework.websocket; + + +public class Subscriber { + + private String subscriberId; + + private String subscriberName; + private String streamId; + private boolean connected; + private int currentConcurrentConnections = 0; + private int concurrentConnectionsLimit = 1; + + public void setSubscriberId(String subscriberId) { + this.subscriberId = subscriberId; + } + + public String getSubscriberId() { + return subscriberId; + } + + public void setStreamId(String streamId) { + this.streamId = streamId; + } + + public String getStreamId() { + return streamId; + } + public boolean isConnected() { + return connected; + } + public void setConnected(boolean connected) { + this.connected = connected; + } + + public int getCurrentConcurrentConnections() { + return currentConcurrentConnections; + } + + public void setCurrentConcurrentConnections(int currentConcurrentConnections) { + this.currentConcurrentConnections = currentConcurrentConnections; + } + + public int getConcurrentConnectionsLimit() { + return concurrentConnectionsLimit; + } + + public void setConcurrentConnectionsLimit(int concurrentConnectionsLimit) { + this.concurrentConnectionsLimit = concurrentConnectionsLimit; + } + + public String getSubscriberName() { + return subscriberName; + } + + public void setSubscriberName(String subscriberName) { + this.subscriberName = subscriberName; + } +} \ No newline at end of file diff --git a/webrtc-android-framework/src/main/java/io/antmedia/webrtcandroidframework/websocket/WebSocketConstants.java b/webrtc-android-framework/src/main/java/io/antmedia/webrtcandroidframework/websocket/WebSocketConstants.java index b8a30604..a5fe6f05 100644 --- a/webrtc-android-framework/src/main/java/io/antmedia/webrtcandroidframework/websocket/WebSocketConstants.java +++ b/webrtc-android-framework/src/main/java/io/antmedia/webrtcandroidframework/websocket/WebSocketConstants.java @@ -78,10 +78,41 @@ private WebSocketConstants() { public static final String ERROR_CODE = "error_code"; + public static final String LINK_SESSION = "linkSession"; + + public static final String REGISTER_ORIGIN_SERVER = "registerOriginServer"; + + public static final String REGISTER_EDGE_SERVER = "registerEdgeServer"; + + public static final String REGISTER_BROADCAST = "registerBroadcast"; + public static final String NO_STREAM_EXIST = "no_stream_exist"; public static final String JOIN_ROOM_COMMAND = "joinRoom"; + + /** + * This is the command that is sent from the server when a stream is started so that player can send a play command + * or take any action + */ + public static final String STREAMING_STARTED = "streaming_started"; + + /** + * Command to get ICE server configuration to frontend from server + */ + public static final String GET_ICE_SERVER_CONFIG = "getIceServerConfig"; + + public static final String ICE_SERVER_CONFIG_NOTIFICATION = "iceServerConfig"; + + public static final String STUN_SERVER_URI = "stunServerUri"; + + public static final String TURN_SERVER_USERNAME = "turnServerUsername"; + + public static final String TURN_SERVER_CREDENTIAL = "turnServerCredential"; + + /** + * Please use {@link #MAIN_TRACK} instead + */ public static final String ROOM = "room"; public static final String JOIN_COMMAND = "join"; @@ -102,6 +133,13 @@ private WebSocketConstants() { public static final String LEAVED_THE_ROOM = "leavedFromRoom"; + /** + * This is error definition and it's sent when one requests to get room information + * and there is no active stream or no room + */ + public static final String ROOM_NOT_ACTIVE = "no_active_streams_in_room"; + + /** * this token is used to access resources or start broadcast when token security is enabled */ @@ -114,6 +152,11 @@ private WebSocketConstants() { */ public static final String SUBSCRIBER_ID = "subscriberId"; + /** + * this subscriber name is the human readable name for a subscriber + */ + public static final String SUBSCRIBER_NAME = "subscriberName"; + /** * this subscriber code is used to access resources or start broadcast when time based subscriber security is enabled */ @@ -151,6 +194,13 @@ private WebSocketConstants() { */ public static final String NOT_ALLOWED_UNREGISTERED_STREAM = "not_allowed_unregistered_streams"; + + /** + * This is sent back to the user if mainTrack + */ + public static final String MAX_SUBTRACK_COUNT_REACHED = "main_track_has_max_subtrack_count__not_allowed_to_add_more_subtracks"; + + /** * This is sent back to the user when there is no room specified in * joining the video conference @@ -176,8 +226,16 @@ private WebSocketConstants() { public static final String STREAM_TIME_INVALID = "stream_not_active_or_expired"; + /** + * This is sent back to the user if token is not valid + */ public static final String UNAUTHORIZED = "unauthorized_access"; + /** + * This is sent back to the user when subscriber is blocked to play or publish + */ + public static final String BLOCKED = "user_blocked"; + /** * This is sent back to the user when a new play message received while * it is playing or it is just to play @@ -324,7 +382,7 @@ private WebSocketConstants() { * Error definition, it's send when remote description is not set, it's generally due to * encoder incompatibilities */ - public static final Object NOT_SET_REMOTE_DESCRIPTION = "notSetRemoteDescription"; + public static final String NOT_SET_REMOTE_DESCRIPTION = "notSetRemoteDescription"; /** * P2P Mode used in session user parameters @@ -404,6 +462,12 @@ private WebSocketConstants() { */ public static final String LICENCE_SUSPENDED = "license_suspended_please_renew_license"; + /** + * It's sent to determine mainTrackId if exists + */ + public static final String MAIN_TRACK = "mainTrack"; + + /** * It's sent as parameter conference mode */ @@ -419,6 +483,11 @@ private WebSocketConstants() { */ public static final String AMCU = "amcu"; + /** + * It's sent for conference in MCU mode + */ + public static final String MULTI_TRACK = "multitrack"; + /** * It's sent for conference in legacy mode */ @@ -430,15 +499,75 @@ private WebSocketConstants() { public static final String SESSION_RESTORED_DESCRIPTION = "session_restored"; /** - * It's sent to determine mainTrackId if exists + * It's the field that maps sdp mid to stream id */ - public static final String MAIN_TRACK = "mainTrack"; + public static final String ID_MAPPING = "idMapping"; + + /** + * It can be used to add some meta data to a broadcast + */ + public static final String META_DATA = "metaData"; + + /** + * Command to update the meta data for a broadcast + */ + public static final String UPDATE_STREAM_META_DATA_COMMAND = "updateStreamMetaData"; + + /** + * Command to inform AMS if a stream is pinned in conference mode + */ + public static final String ASSIGN_VIDEO_TRACK_COMMAND = "assignVideoTrackCommand"; + + /** + * Command to change visible streams in conference mode, used for pagination + */ + public static final String UPDATE_VIDEO_TRACK_ASSIGNMENTS_COMMAND = "updateVideoTrackAssignmentsCommand"; + + /** + * Command to set max video track count in conference + */ + public static final String SET_MAX_VIDEO_TRACK_COUNT_COMMAND = "setMaxVideoTrackCountCommand"; + + /** + * Command to get debug info in conference + */ + public static final String GET_DEBUG_INFO_COMMAND = "getDebugInfo"; + + /** + * Generated debug info in conference + */ + public static final String DEBUG_INFO = "debugInfo"; + + /** + * Track id that is pinned for a stream + */ + public static final String VIDEO_TRACK_ID = "videoTrackId"; + + /** + * Start index of a list for pagination + */ + public static final String OFFSET = "offset"; + + /** + * Length of a page for pagination + */ + public static final String SIZE = "size"; + + /** + * maximum number of tracks + */ + public static final String MAX_TRACK_COUNT = "maxTrackCount"; /** * Command to get broadcast object */ public static final String GET_BROADCAST_OBJECT_COMMAND = "getBroadcastObject"; + /** + * Command to get video track assignments + */ + public static final String GET_VIDEO_TRACK_ASSIGNMENTS_COMMAND = "getVideoTrackAssignmentsCommand"; + /** * broadcast object notification */ @@ -449,6 +578,161 @@ private WebSocketConstants() { */ public static final String BROADCAST = "broadcast"; + public static final String AUTH_TOKEN_NOT_VALID_ERROR_DEFINITION = "authenticationTokenNotValid"; + + public static final String MISSING_PARAMETER_DEFINITION = "missingParameter"; + + /** + * Information field in websocket communication + */ + public static final String INFORMATION = "information"; + + /** + * Success field in websocket communication. If it's value true, the operation is successful. + * If it's value is false, the operation is failed + */ + public static final String SUCCESS = "success"; + + /** + * Topic field to send push notification + */ + public static final String PUSH_NOTIFICATION_TOPIC = "pushNotificationTopic"; + + /** + * Subscriber id list to send push notification + */ + public static final String SUBSCRIBER_ID_LIST_TO_NOTIFY = "subscriberIdsToNotify"; + + /** + * Participant role in the room + */ + public static final String ROLE = "role"; + + /** + * Participant role in the room + */ + public static final String DISABLE_TRACKS_BY_DEFAULT = "disableTracksByDefault"; + + /** + * Command to get subtrack infos for a main track + */ + public static final String GET_SUBTRACKS_COMMAND = "getSubtracks"; + + /** + * Command to get subtrack count for a main track + */ + public static final String GET_SUBTRACKS_COUNT_COMMAND = "getSubtracksCount"; + + /** + * subtrack (broadcast) object list notification + */ + public static final String SUBTRACK_LIST_NOTIFICATION = "subtrackList"; + + + /** + * Command to get subscriber list size + */ + public static final String GET_SUBSCRIBER_LIST_SIZE = "getSubscriberCount"; + + /** + * subscriber count notification + */ + public static final String SUBSCRIBER_COUNT = "subscriberCount"; + + /** + * Command to get subscribers for a stream + */ + public static final String GET_SUBSCRIBER_LIST = "getSubscribers"; + + /** + * subscribers list notification + */ + public static final String SUBSCRIBER_LIST_NOTIFICATION = "subscriberList"; + + /** + * status field in websocket communication + */ + public static final String STATUS = "status"; + + /** + * sort field used for sorting subtracks + */ + public static final String SORT_BY = "sortBy"; + + /** + * order (asc, desc) field used for ordering subtracks + */ + public static final String ORDER_BY = "orderBy"; + + /** + * search field used for searching subtracks + */ + public static final String SEARCH = "search"; + + + /* + * count field in websocket communication + */ + public static final String COUNT = "count"; + + /** + * subtrack (broadcast) object count notification + */ + public static final String SUBTRACK_COUNT_NOTIFICATION = "subtrackCount"; + + /** + * subtrack (broadcast) object list + */ + public static final String SUBTRACK_LIST = "subtrackList"; + + /** + * subscribers list + */ + public static final String SUBCRIBER_LIST = "subscriberList"; + + /** + * This is the error definition that is sent when the stream does not get video or audio packet for the timeout duration. + * Currently it's implemented for WebRTC ingest + */ + public static final String NO_PACKET_RECEIVED_FOR_TIMEOUT_DURATION = "noPacketReceivedForTimeoutDuration"; + + /** + * This is the error definition that is sent when mainTrack cannot be created or updated in publishing process. + */ + public static final String MAINTRACK_DB_OPERATION_FAILED = "mainTrackDBOperationFailed"; + + + /** + * This is passed in play websocket method to define the publisher stream id (if available) which uses same websocket channel with player + * For example in conference case a participant use same websocket to publish its stream and to play the others + */ + public static final String USER_PUBLISH_ID = "userPublishId"; + + /** + * Notification to notify a new subtrack addition to a main track + */ + public static final String SUBTRACK_ADDED = "subtrackAdded"; + + /** + * Notification to notify a new subtrack removal to a main track + */ + public static final String SUBTRACK_REMOVED = "subtrackRemoved"; + + /** + * This is the error definition that is sent when the stream does not exist or not streaming + */ + public static final String STREAM_NOT_EXIST_OR_NOT_STREAMING_DEFINITION = "stream_not_exist_or_not_streaming"; + + /** + * This is the error definition that is sent when the stream exits but not available as WebRTC because webrtc is not enabled + */ + public static final String WEBRTC_NOT_ENABLED_TO_PLAYBACK_DEFINITION = "webrtc_not_enabled"; + + /** + * This is the definition that is sent when the is about to start for auto/start stop streams + */ + public static final String STREAMING_STARTS_SOON_DEFINITION = "streaming_starts_soon"; + public static final int WEBSOCKET_CONNECTION_TIMEOUT = 10000; //10 sec -} +} \ No newline at end of file diff --git a/webrtc-android-framework/src/main/java/io/antmedia/webrtcandroidframework/websocket/WebSocketHandler.java b/webrtc-android-framework/src/main/java/io/antmedia/webrtcandroidframework/websocket/WebSocketHandler.java index 19c5fcad..86405df6 100644 --- a/webrtc-android-framework/src/main/java/io/antmedia/webrtcandroidframework/websocket/WebSocketHandler.java +++ b/webrtc-android-framework/src/main/java/io/antmedia/webrtcandroidframework/websocket/WebSocketHandler.java @@ -277,11 +277,26 @@ else if (definition.equals(WebSocketConstants.BROADCAST_OBJECT_NOTIFICATION)) { String broadcastJson = json.getString(WebSocketConstants.BROADCAST); Broadcast broadcast = gson.fromJson(broadcastJson, Broadcast.class); signallingListener.onBroadcastObject(broadcast); - }else if(definition.equals(WebSocketConstants.RESOLUTION_CHANGE_INFO_COMMAND)){ + } + else if(definition.equals(WebSocketConstants.RESOLUTION_CHANGE_INFO_COMMAND)){ int resolution = json.getInt(WebSocketConstants.STREAM_HEIGHT); signallingListener.onResolutionChange(streamId, resolution); } + else if(definition.equals(WebSocketConstants.SUBSCRIBER_COUNT)){ + int count = json.getInt(WebSocketConstants.COUNT); + signallingListener.onSubscriberCount(streamId, count); + } + else if(definition.equals(WebSocketConstants.SUBSCRIBER_LIST_NOTIFICATION)){ + JSONArray subscriberList = json.getJSONArray(WebSocketConstants.SUBCRIBER_LIST); + Subscriber[] subscribers = new Subscriber[subscriberList.length()]; + for (int i = 0; i < subscriberList.length(); i++) { + String subscriberJson = subscriberList.getString(i); + Subscriber subscriber = gson.fromJson(subscriberJson, Subscriber.class); + subscribers[i] = subscriber; + } + signallingListener.onSubscriberList(streamId, subscribers); + } } else if (commandText.equals(WebSocketConstants.TRACK_LIST)) { JSONArray trackList = json.getJSONArray(WebSocketConstants.TRACK_LIST); @@ -338,6 +353,32 @@ public void onBinaryMessage(byte[] bytes) { } + public void getSubscriberCount(String streamId) { + checkIfCalledOnValidThread(); + JSONObject json = new JSONObject(); + try { + json.put(WebSocketConstants.COMMAND, WebSocketConstants.GET_SUBSCRIBER_LIST_SIZE); + json.put(WebSocketConstants.STREAM_ID, streamId); + sendTextMessage(json.toString()); + } catch (JSONException e) { + e.printStackTrace(); + } + } + + public void getSubscriberList(String streamId, long offset, long size) { + checkIfCalledOnValidThread(); + JSONObject json = new JSONObject(); + try { + json.put(WebSocketConstants.COMMAND, WebSocketConstants.GET_SUBSCRIBER_LIST); + json.put(WebSocketConstants.STREAM_ID, streamId); + json.put(WebSocketConstants.OFFSET, offset); + json.put(WebSocketConstants.SIZE, size); + sendTextMessage(json.toString()); + } catch (JSONException e) { + e.printStackTrace(); + } + } + public void startPublish(String streamId, String token, boolean videoEnabled, boolean audioEnabled, String subscriberId, String subscriberCode, String streamName, String mainTrackId){ checkIfCalledOnValidThread(); JSONObject json = new JSONObject(); @@ -358,7 +399,7 @@ public void startPublish(String streamId, String token, boolean videoEnabled, bo } } - public void startPlay(String streamId, String token, String[] tracks, String subscriberId, String subscriberCode, String viewerInfo){ + public void startPlay(String streamId, String token, String[] tracks, String subscriberId, String subscriberName, String subscriberCode, String viewerInfo, boolean disableTracksByDefault){ checkIfCalledOnValidThread(); JSONObject json = new JSONObject(); try { @@ -375,8 +416,10 @@ public void startPlay(String streamId, String token, String[] tracks, String sub json.put(WebSocketConstants.TRACK_LIST, jsonArray); json.put(WebSocketConstants.SUBSCRIBER_ID, subscriberId); + json.put(WebSocketConstants.SUBSCRIBER_NAME, subscriberName); json.put(WebSocketConstants.SUBSCRIBER_CODE, subscriberCode); json.put(WebSocketConstants.VIEWER_INFO, viewerInfo); + json.put(WebSocketConstants.DISABLE_TRACKS_BY_DEFAULT, disableTracksByDefault); sendTextMessage(json.toString()); } catch (JSONException e) { @@ -685,4 +728,15 @@ public void setWsReconnectionHandler(Handler wsReconnectionHandler) { this.wsReconnectionHandler = wsReconnectionHandler; } + public void getDebugInfo(String streamId) { + checkIfCalledOnValidThread(); + JSONObject json = new JSONObject(); + try { + json.put(WebSocketConstants.COMMAND, WebSocketConstants.GET_DEBUG_INFO_COMMAND); + json.put(WebSocketConstants.STREAM_ID, streamId); + sendTextMessage(json.toString()); + } catch (JSONException e) { + e.printStackTrace(); + } + } } diff --git a/webrtc-android-framework/src/test/java/io/antmedia/webrtcandroidframework/WebRTCClientTest.java b/webrtc-android-framework/src/test/java/io/antmedia/webrtcandroidframework/WebRTCClientTest.java index 36dfefa7..b59bc10b 100644 --- a/webrtc-android-framework/src/test/java/io/antmedia/webrtcandroidframework/WebRTCClientTest.java +++ b/webrtc-android-framework/src/test/java/io/antmedia/webrtcandroidframework/WebRTCClientTest.java @@ -74,6 +74,7 @@ import io.antmedia.webrtcandroidframework.api.IDataChannelObserver; import io.antmedia.webrtcandroidframework.api.IWebRTCClient; import io.antmedia.webrtcandroidframework.api.IWebRTCListener; +import io.antmedia.webrtcandroidframework.api.PlayParams; import io.antmedia.webrtcandroidframework.apprtc.AppRTCAudioManager; import io.antmedia.webrtcandroidframework.core.BlackFrameSender; import io.antmedia.webrtcandroidframework.core.CustomVideoCapturer; @@ -209,6 +210,7 @@ public void testStreamPlayParameters() { String streamId = "stream" + RandomStringUtils.random(5); String token = "token" + RandomStringUtils.random(5); String subscriberId = "mySubscriber" + RandomStringUtils.random(5); + String subscriberName = "name" + RandomStringUtils.random(5); String subscriberCode = "code" + RandomStringUtils.random(5); String viewerInfo = "info" + RandomStringUtils.random(5); @@ -220,9 +222,20 @@ public void testStreamPlayParameters() { webRTCClient.setAudioEnabled(audioCallEnabled); webRTCClient.setVideoEnabled(videoCallEnabled); - webRTCClient.play(streamId, token, null, subscriberId, subscriberCode, viewerInfo); + PlayParams params = new PlayParams(); + params.setStreamId(streamId); + params.setToken(token); + params.setTracks(null); + params.setSubscriberId(subscriberId); + params.setSubscriberName(subscriberName); + params.setSubscriberCode(subscriberCode); + params.setViewerInfo(viewerInfo); + params.setDisableTracksByDefault(false); - verify(wsHandler, times(1)).startPlay(streamId, token, null, subscriberId, subscriberCode, viewerInfo); + + webRTCClient.play(params); + + verify(wsHandler, times(1)).startPlay(streamId, token, null, subscriberId, subscriberName, subscriberCode, viewerInfo, false); ArgumentCaptor jsonCaptor = ArgumentCaptor.forClass(String.class); verify(wsHandler, times(1)).sendTextMessage(jsonCaptor.capture()); @@ -233,9 +246,12 @@ public void testStreamPlayParameters() { json.put(WebSocketConstants.STREAM_ID, streamId); json.put(WebSocketConstants.TOKEN, token); json.put(WebSocketConstants.SUBSCRIBER_ID, subscriberId); + json.put(WebSocketConstants.SUBSCRIBER_NAME, subscriberName); json.put(WebSocketConstants.SUBSCRIBER_CODE, subscriberCode); json.put(WebSocketConstants.VIEWER_INFO, viewerInfo); json.put(WebSocketConstants.TRACK_LIST, new JSONArray()); + json.put(WebSocketConstants.DISABLE_TRACKS_BY_DEFAULT, false); + } catch (JSONException e) { e.printStackTrace(); } @@ -324,7 +340,7 @@ public void testJoinRoomParameters() { , "", "", "", roomName); webRTCClient.joinToConferenceRoom(roomName); - verify(wsHandler, timeout(1000)).startPlay(roomName, "", null, "", "", ""); + verify(wsHandler, timeout(1000)).startPlay(roomName, "", null, "", "", "", "", false); ArgumentCaptor jsonCaptor = ArgumentCaptor.forClass(String.class); verify(wsHandler, times(2)).sendTextMessage(jsonCaptor.capture()); @@ -351,9 +367,11 @@ public void testJoinRoomParameters() { jsonPlay.put(WebSocketConstants.STREAM_ID, roomName); jsonPlay.put(WebSocketConstants.TOKEN, ""); jsonPlay.put(WebSocketConstants.SUBSCRIBER_ID, ""); + jsonPlay.put(WebSocketConstants.SUBSCRIBER_NAME, ""); jsonPlay.put(WebSocketConstants.SUBSCRIBER_CODE, ""); jsonPlay.put(WebSocketConstants.VIEWER_INFO, ""); jsonPlay.put(WebSocketConstants.TRACK_LIST, new JSONArray()); + jsonPlay.put(WebSocketConstants.DISABLE_TRACKS_BY_DEFAULT, false); } catch (JSONException e) { e.printStackTrace(); } @@ -706,7 +724,7 @@ public void testWSAndListenerMessages() { , "", "", "", room); webRTCClient.joinToConferenceRoom(room); - verify(wsHandler, timeout(1000)).startPlay(room, "", null, "", "", ""); + verify(wsHandler, timeout(1000)).startPlay(room, "", null, "", "", "", "", false); webRTCClient.leaveFromConference(room); verify(wsHandler, timeout(1000)).stop(streamId); @@ -1162,7 +1180,7 @@ public void tesHandlePublishPlayRequestWhenWSNotConnected() { String player1 = "player1"; webRTCClient.play(player1); - verify(wsHandler, never()).startPlay(anyString(), anyString(), any(String[].class), anyString(), anyString(), anyString()); + verify(wsHandler, never()).startPlay(anyString(), anyString(), any(String[].class), anyString(), anyString(), anyString(), anyString(), anyBoolean()); assertEquals(2, webRTCClient.getPeersForTest().size()); WebRTCClient.PeerInfo playPeer = webRTCClient.getPeersForTest().get(player1); @@ -1170,7 +1188,7 @@ public void tesHandlePublishPlayRequestWhenWSNotConnected() { webRTCClient.onWebSocketConnected(); verify(wsHandler, times(1)).startPublish(eq(publishPeer.id), anyString(), anyBoolean(), anyBoolean(), anyString(), anyString(), anyString(), anyString()); - verify(wsHandler, times(1)).startPlay(eq(playPeer.id), anyString(), any(String[].class), anyString(), anyString(), anyString()); + verify(wsHandler, times(1)).startPlay(eq(playPeer.id), anyString(), any(String[].class), anyString(), anyString(), anyString(), anyString(), anyBoolean()); } diff --git a/webrtc-android-framework/src/test/java/io/antmedia/webrtcandroidframework/WebSocketHandlerTest.java b/webrtc-android-framework/src/test/java/io/antmedia/webrtcandroidframework/WebSocketHandlerTest.java index 079b2c23..3ccccdea 100644 --- a/webrtc-android-framework/src/test/java/io/antmedia/webrtcandroidframework/WebSocketHandlerTest.java +++ b/webrtc-android-framework/src/test/java/io/antmedia/webrtcandroidframework/WebSocketHandlerTest.java @@ -176,10 +176,11 @@ public void testStartPlay() throws JSONException { String token = "token123"; String[] tracks = {"track1", "track2"}; String subscriberId = "subscriber123"; + String subscriberName = "subscriberName"; String subscriberCode = "code123"; String viewerInfo = "viewerInfo"; - webSocketHandler.startPlay(streamId, token, tracks, subscriberId, subscriberCode, viewerInfo); + webSocketHandler.startPlay(streamId, token, tracks, subscriberId, subscriberName, subscriberCode, viewerInfo, false); ArgumentCaptor jsonCaptor = ArgumentCaptor.forClass(String.class); verify(webSocketHandler, times(1)).sendTextMessage(jsonCaptor.capture()); @@ -191,7 +192,9 @@ public void testStartPlay() throws JSONException { expectedJson.put(WebSocketConstants.TRACK_LIST, new JSONArray(tracks)); expectedJson.put(WebSocketConstants.SUBSCRIBER_ID, subscriberId); expectedJson.put(WebSocketConstants.SUBSCRIBER_CODE, subscriberCode); + expectedJson.put(WebSocketConstants.SUBSCRIBER_NAME, subscriberName); expectedJson.put(WebSocketConstants.VIEWER_INFO, viewerInfo); + expectedJson.put(WebSocketConstants.DISABLE_TRACKS_BY_DEFAULT, false); assertEquals(expectedJson.toString(), jsonCaptor.getValue()); } diff --git a/webrtc-android-sample-app/src/main/java/io/antmedia/webrtc_android_sample_app/basic/PublishActivity.java b/webrtc-android-sample-app/src/main/java/io/antmedia/webrtc_android_sample_app/basic/PublishActivity.java index 1c553685..90e1d54f 100644 --- a/webrtc-android-sample-app/src/main/java/io/antmedia/webrtc_android_sample_app/basic/PublishActivity.java +++ b/webrtc-android-sample-app/src/main/java/io/antmedia/webrtc_android_sample_app/basic/PublishActivity.java @@ -80,6 +80,7 @@ public void createWebRTCClient(){ .setBluetoothEnabled(bluetoothEnabled) .setWebRTCListener(createWebRTCListener()) .setDataChannelObserver(createDatachannelObserver()) + .setAudioCallEnabled(false) .build(); startStreamingButton = findViewById(R.id.start_streaming_button);