This guide covers publishing audio and video tracks to a LiveKit room.
To publish media, use RtcClient which provides full WebRTC integration. The SDK uses webrtc-java for native WebRTC support.
import io.livekit.sdk.Room;
import io.livekit.sdk.rtc.RtcClient;
import io.livekit.sdk.rtc.LocalAudioTrack;
import io.livekit.sdk.rtc.LocalVideoTrack;
import io.livekit.sdk.rtc.MediaDeviceInfo;
RtcClient client = new RtcClient();
client.connect(url, token).join();// Audio input devices (microphones)
List<MediaDeviceInfo> microphones = client.getAudioInputDevices();
for (MediaDeviceInfo device : microphones) {
System.out.println("Mic: " + device.getLabel() + " (id: " + device.getDeviceId() + ")");
}
// Audio output devices (speakers)
List<MediaDeviceInfo> speakers = client.getAudioOutputDevices();
for (MediaDeviceInfo device : speakers) {
System.out.println("Speaker: " + device.getLabel());
}
// Video input devices (cameras)
List<MediaDeviceInfo> cameras = client.getVideoInputDevices();
for (MediaDeviceInfo device : cameras) {
System.out.println("Camera: " + device.getLabel());
}public class MediaDeviceInfo {
String getDeviceId(); // Device identifier
String getLabel(); // Human-readable name
Kind getKind(); // AUDIO_INPUT, AUDIO_OUTPUT, or VIDEO_INPUT
}// Create audio track with default device
LocalAudioTrack audioTrack = client.createAudioTrack();
if (audioTrack != null) {
client.publishAudioTrack(audioTrack);
}// Get device list
List<MediaDeviceInfo> mics = client.getAudioInputDevices();
String deviceId = mics.get(0).getDeviceId();
// Create track with specific device
LocalAudioTrack audioTrack = client.createAudioTrack(deviceId, "my-mic");
client.publishAudioTrack(audioTrack);// Create video track with default device (1280x720 @ 30fps)
LocalVideoTrack videoTrack = client.createVideoTrack();
if (videoTrack != null) {
client.publishVideoTrack(videoTrack);
}// Get camera list
List<MediaDeviceInfo> cameras = client.getVideoInputDevices();
String deviceId = cameras.get(0).getDeviceId();
// Create track with specific parameters
LocalVideoTrack videoTrack = client.createVideoTrack(
deviceId, // Device ID
"my-cam", // Track name
1920, // Width
1080, // Height
30 // Frame rate
);
client.publishVideoTrack(videoTrack);| Preset | Resolution | Frame Rate | Use Case |
|---|---|---|---|
| 360p | 640x360 | 30 | Low bandwidth |
| 720p | 1280x720 | 30 | Standard HD |
| 1080p | 1920x1080 | 30 | Full HD |
| 4K | 3840x2160 | 30 | Ultra HD |
// Unpublish by track ID
client.unpublishTrack(audioTrack.getSid());
client.unpublishTrack(videoTrack.getSid());You can also control media through LocalParticipant:
LocalParticipant local = room.getLocalParticipant();
// Enable/disable microphone
local.setMicrophoneEnabled(true);
local.setMicrophoneEnabled(false);
// Enable/disable camera
local.setCameraEnabled(true);
local.setCameraEnabled(false);Remote tracks are automatically subscribed when autoSubscribe is enabled (default). Handle them via RoomListener:
room.addListener(new RoomListener() {
@Override
public void onTrackSubscribed(Room room, Track track,
TrackPublication publication, RemoteParticipant participant) {
switch (track.getType()) {
case AUDIO:
handleAudioTrack((AudioTrack) track, participant);
break;
case VIDEO:
handleVideoTrack((VideoTrack) track, participant);
break;
}
}
@Override
public void onTrackUnsubscribed(Room room, Track track,
TrackPublication publication, RemoteParticipant participant) {
System.out.println("Track unsubscribed: " + track.getSid());
}
});
void handleAudioTrack(AudioTrack track, RemoteParticipant participant) {
System.out.println("Audio from: " + participant.getIdentity());
// Audio plays automatically through default output device
}
void handleVideoTrack(VideoTrack track, RemoteParticipant participant) {
System.out.println("Video from: " + participant.getIdentity());
// Access native WebRTC track for rendering
// RemoteVideoTrack has getNativeTrack() for integration with video renderers
}public enum TrackType {
AUDIO,
VIDEO,
DATA
}public enum TrackSource {
UNKNOWN,
CAMERA,
MICROPHONE,
SCREEN_SHARE,
SCREEN_SHARE_AUDIO
}Track publications contain metadata about published tracks:
TrackPublication pub = participant.getTrackPublicationBySource(TrackSource.CAMERA);
if (pub != null) {
System.out.println("Track SID: " + pub.getSid());
System.out.println("Track name: " + pub.getName());
System.out.println("Track type: " + pub.getType());
System.out.println("Is muted: " + pub.isMuted());
System.out.println("Is subscribed: " + pub.isSubscribed());
System.out.println("MIME type: " + pub.getMimeType());
}- Screen sharing: webrtc-java supports
ScreenCapturer/WindowCapturerbut this is not yet exposed in the SDK - Simulcast/SVC: Layer selection for adaptive streaming is not yet implemented
- Audio processing: Advanced audio options (noise suppression, echo cancellation) are not yet configurable
- Data Channels - Send arbitrary data
- E2EE - Encrypt your tracks
- API Reference - Complete API documentation