A technical demo showing how to connect to a Daily.co / Tavus video call room and directly subscribe to participant video and audio streams, bypassing the standard join screen UI.
This demo leverages the Daily.js library to directly consume media streams from a Daily.co/Tavus room. The core functionality is implemented in vanilla JavaScript without additional frameworks.
callObject = DailyIframe.createCallObject();
await callObject.join({
url: roomUrl,
userName: "Local" // Name of the joining participant
});The app waits for existing participants to be detected after joining:
const participants = callObject.participants();
const existingParticipant = Object.values(participants).find(
(participant) => participant.local === false
);Instead of using Daily's standard UI components, this demo directly accesses the WebRTC media tracks:
// For video
if (existingParticipant.tracks.video.state === 'playable') {
const videoElement = document.getElementById('participant-video');
videoElement.srcObject = new MediaStream([existingParticipant.tracks.video.persistentTrack]);
}
// For audio
if (existingParticipant.tracks.audio.state === 'playable') {
const audioStream = new MediaStream([existingParticipant.tracks.audio.persistentTrack]);
const audio = new Audio();
audio.srcObject = audioStream;
audio.autoplay = true;
}- Uses
DailyIframe.createCallObject()instead of embedding a Daily iframe - Accesses raw
persistentTrackproperties to get WebRTC MediaStreamTracks - Creates new MediaStream objects to assign to standard HTML5 media elements
- No complex UI state management - focuses purely on demonstrating the streaming capabilities
- Integration with custom UIs where Daily's built-in interface isn't desired
- Headless connection to Daily/Tavus rooms for specialized applications
- Technical demonstrations of Daily.js API capabilities
- Clone this repository
- Open
index.htmlin a browser - Enter a valid Daily.co/Tavus room URL
- Examine the console logs to see participant data