Code Examples
Complete code examples for common streaming scenarios. Copy and adapt these examples for your app.
Audio Live Room
A complete audio live streaming room with host and audience support.
public class AudioLiveActivity extends AppCompatActivity {
private ConoStreamManager manager;
private ConoStreamAudioHelper audioHelper;
private boolean isHost;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_audio_live);
// Get data from intent
isHost = getIntent().getBooleanExtra("is_host", false);
String serverUrl = getIntent().getStringExtra("server_url");
String token = getIntent().getStringExtra("token");
String channelName = getIntent().getStringExtra("channel");
// Initialize manager
manager = ((MyApplication) getApplication()).getConoStreamManager();
audioHelper = new ConoStreamAudioHelper(manager, this);
// Set up callbacks
setupEventCallbacks();
// Join room based on role
if (isHost) {
audioHelper.joinAsHost(serverUrl, token, channelName);
} else {
audioHelper.joinAsAudience(serverUrl, token, channelName);
}
}
private void setupEventCallbacks() {
audioHelper.setEventCallback(new ConoStreamEventCallback() {
@Override
public void onAudioTrackPublished() {
showToast("You are now live!");
}
@Override
public void onRemoteAudioTrackSubscribed(String participantId) {
Log.d("Audio", "Subscribed to: " + participantId);
}
@Override
public void onParticipantJoined(String id, String name) {
showToast(name + " joined");
}
@Override
public void onParticipantLeft(String id, String name) {
showToast(name + " left");
}
@Override
public void onConnectionError(String error) {
showToast("Error: " + error);
finish();
}
});
}
// Mute button click handler
public void onMuteClick(View view) {
boolean isMuted = manager.isMicrophoneMuted();
manager.muteMicrophone(!isMuted);
updateMuteButton(!isMuted);
}
// Leave room
public void onLeaveClick(View view) {
audioHelper.leaveRoom();
finish();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (audioHelper != null) {
audioHelper.leaveRoom();
}
}
private void showToast(String message) {
runOnUiThread(() -> Toast.makeText(this, message, Toast.LENGTH_SHORT).show());
}
}
Video Live Room
A video live streaming room with camera preview.
public class VideoLiveActivity extends AppCompatActivity {
private ConoStreamManager manager;
private ConoStreamVideoHelper videoHelper;
private TextureViewRenderer localVideoView;
private TextureViewRenderer remoteVideoView;
private boolean isHost;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video_live);
// Find views
localVideoView = findViewById(R.id.local_video_view);
remoteVideoView = findViewById(R.id.remote_video_view);
// Get data from intent
isHost = getIntent().getBooleanExtra("is_host", false);
String serverUrl = getIntent().getStringExtra("server_url");
String token = getIntent().getStringExtra("token");
String channelName = getIntent().getStringExtra("channel");
// Initialize
manager = ((MyApplication) getApplication()).getConoStreamManager();
videoHelper = new ConoStreamVideoHelper(manager, this);
// Set up callbacks
setupEventCallbacks();
// Join room
if (isHost) {
// Host publishes video
videoHelper.joinAsHost(serverUrl, token, channelName, localVideoView);
localVideoView.setVisibility(View.VISIBLE);
} else {
// Audience just watches
videoHelper.joinAsAudience(serverUrl, token, channelName);
}
}
private void setupEventCallbacks() {
videoHelper.setEventCallback(new ConoStreamVideoEventCallback() {
@Override
public void onLocalVideoTrackPublished() {
showToast("Your video is live!");
}
@Override
public void onRemoteVideoTrackSubscribed(String participantId, VideoTrack track) {
runOnUiThread(() -> {
// Display remote video
track.addRenderer(remoteVideoView);
remoteVideoView.setVisibility(View.VISIBLE);
});
}
@Override
public void onRemoteVideoTrackUnsubscribed(String participantId) {
runOnUiThread(() -> {
remoteVideoView.setVisibility(View.GONE);
});
}
@Override
public void onParticipantJoined(String id, String name) {
showToast(name + " joined");
}
@Override
public void onParticipantLeft(String id, String name) {
showToast(name + " left");
}
});
}
// Switch camera button
public void onSwitchCameraClick(View view) {
videoHelper.switchCamera();
}
// Toggle camera on/off
public void onToggleCameraClick(View view) {
boolean isEnabled = videoHelper.isCameraEnabled();
videoHelper.enableCamera(!isEnabled);
}
@Override
protected void onDestroy() {
super.onDestroy();
if (videoHelper != null) {
videoHelper.release();
}
}
}
Co-hosting Example
Upgrading an audience member to co-host.
public class CoHostActivity extends AppCompatActivity {
private ConoStreamAudioHelper audioHelper;
private boolean isCoHost = false;
// Called when audience wants to become co-host
public void onRequestCoHostClick(View view) {
// First, check microphone permission
if (!hasMicrophonePermission()) {
requestMicrophonePermission();
return;
}
// Show dialog to host (in your app's logic)
sendCoHostRequestToHost();
}
// Called when host approves the request
public void onCoHostApproved() {
// Upgrade to co-host - starts publishing audio
audioHelper.upgradeToCoHost();
isCoHost = true;
// Update UI
showCoHostUI();
showToast("You are now a co-host!");
}
// Called when co-host wants to step down
public void onStepDownClick(View view) {
// Downgrade back to audience
audioHelper.downgradeToAudience();
isCoHost = false;
// Update UI
showAudienceUI();
showToast("You are now an audience member");
}
private void showCoHostUI() {
// Show mute button, hide request button, etc.
findViewById(R.id.btn_mute).setVisibility(View.VISIBLE);
findViewById(R.id.btn_request_cohost).setVisibility(View.GONE);
findViewById(R.id.btn_step_down).setVisibility(View.VISIBLE);
}
private void showAudienceUI() {
// Hide mute button, show request button, etc.
findViewById(R.id.btn_mute).setVisibility(View.GONE);
findViewById(R.id.btn_request_cohost).setVisibility(View.VISIBLE);
findViewById(R.id.btn_step_down).setVisibility(View.GONE);
}
}
PK Battle Example
Split-screen battle between two hosts.
public class PkBattleActivity extends AppCompatActivity {
private ConoStreamVideoHelper videoHelper;
// PK views
private FrameLayout pkLayout;
private TextureViewRenderer pkLeftView; // Local host
private TextureViewRenderer pkRightView; // Opponent
private boolean isPkMode = false;
// Called when PK battle starts
public void startPkBattle(String opponentUrl, String opponentToken, String opponentChannel) {
// Switch to PK layout
pkLayout.setVisibility(View.VISIBLE);
localVideoView.setVisibility(View.GONE);
// Initialize PK renderers
initPkRenderers();
// Connect to opponent's room
videoHelper.joinPkOpponentRoom(opponentUrl, opponentToken, opponentChannel);
// Attach local video to left side
videoHelper.attachLocalVideoToPkView(pkLeftView);
// Set callback for opponent video
videoHelper.setPkOpponentCallback(new PkOpponentCallback() {
@Override
public void onPkOpponentVideoReceived(VideoTrack track) {
runOnUiThread(() -> {
track.addRenderer(pkRightView);
pkRightView.setVisibility(View.VISIBLE);
});
}
@Override
public void onPkOpponentOffline(String name) {
runOnUiThread(() -> {
showOpponentOfflineOverlay(name);
});
}
});
// Attach opponent video to right side
videoHelper.attachPkRemoteVideoToView(pkRightView);
isPkMode = true;
}
// Called when PK battle ends
public void endPkBattle() {
// Leave opponent room
videoHelper.leavePkOpponentRoom();
// Cleanup renderers
videoHelper.cleanupPkRenderers();
// Switch back to normal layout
pkLayout.setVisibility(View.GONE);
localVideoView.setVisibility(View.VISIBLE);
// Re-attach local video to main view
videoHelper.attachLocalVideoToView(localVideoView);
isPkMode = false;
}
private void initPkRenderers() {
// Initialize EGL context for renderers
EglBase eglBase = EglBase.create();
pkLeftView.init(eglBase.getEglBaseContext(), null);
pkLeftView.setMirror(true);
pkLeftView.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FILL);
pkRightView.init(eglBase.getEglBaseContext(), null);
pkRightView.setMirror(false);
pkRightView.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FILL);
}
private void showOpponentOfflineOverlay(String opponentName) {
// Show "[name] offline" overlay on right side
TextView offlineText = findViewById(R.id.pk_opponent_offline);
offlineText.setText(opponentName + " offline");
offlineText.setVisibility(View.VISIBLE);
}
}
PK Layout XML
<FrameLayout
android:id="@+id/pk_layout"
android:layout_width="match_parent"
android:layout_height="300dp"
android:visibility="gone">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<!-- Left: Local host -->
<FrameLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1">
<io.conostream.webrtc.TextureViewRenderer
android:id="@+id/pk_left_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
<!-- Divider -->
<View
android:layout_width="2dp"
android:layout_height="match_parent"
android:background="#FFFFFF" />
<!-- Right: Opponent -->
<FrameLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1">
<io.conostream.webrtc.TextureViewRenderer
android:id="@+id/pk_right_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TextView
android:id="@+id/pk_opponent_offline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textColor="#FFFFFF"
android:visibility="gone" />
</FrameLayout>
</LinearLayout>
</FrameLayout>
ℹ️
Need more examples? Contact us at support@conostream.nl for complete sample projects.