Skip to Content
Dial v1 live 🎉
SdkVideo Conferencing

Video Conferencing

Create multi-party video collaboration spaces with screen sharing, recording, and more.

Creating a Conference Room

Basic Room

const room = await userDialer.conference.create({ name: 'Web3 Team Standup', maxParticipants: 10, video: true, audio: true }); console.log('Room ID:', room.id); console.log('Join URL:', room.url);

With Options

const room = await userDialer.conference.create({ name: 'Product Demo', maxParticipants: 50, video: true, audio: true, settings: { recordingEnabled: true, screenShareEnabled: true, chatEnabled: true, // Enable in-room messaging waitingRoom: true, muteOnJoin: false, videoQuality: '1080p' } });

Room Object

interface ConferenceRoom { id: string; name: string; host: string; // Wallet address participants: Participant[]; maxParticipants: number; createdAt: Date; url: string; status: 'waiting' | 'active' | 'ended'; recording?: { isRecording: boolean; startedAt?: Date; url?: string; }; }

Joining a Room

By Room ID

await userDialer.conference.join({ roomId: room.id, video: true, audio: true, displayName: 'Alice.eth' });

By URL

await userDialer.conference.joinByUrl({ url: 'https://dial.wtf/rooms/abc123', video: true, audio: true });

Participants

Participant Object

interface Participant { id: string; walletAddress: string; displayName: string; isHost: boolean; isMuted: boolean; isVideoEnabled: boolean; isScreenSharing: boolean; joinedAt: Date; }

Get Participants

const participants = await userDialer.conference.getParticipants(roomId); console.log(`${participants.length} participants in room`);

Listen for Participant Events

userDialer.on('conference:participant:joined', (participant) => { console.log(`${participant.displayName} joined`); }); userDialer.on('conference:participant:left', (participant) => { console.log(`${participant.displayName} left`); });

Media Controls

Audio Controls

// Mute yourself await userDialer.conference.muteAudio(roomId); // Unmute yourself await userDialer.conference.unmuteAudio(roomId); // Mute specific participant (host only) await userDialer.conference.muteParticipant(roomId, participantId); // Mute all participants (host only) await userDialer.conference.muteAll(roomId);

Video Controls

// Disable your video await userDialer.conference.disableVideo(roomId); // Enable your video await userDialer.conference.enableVideo(roomId); // Request participant to enable video await userDialer.conference.requestVideo(roomId, participantId);

Screen Sharing

Start Screen Share

const screenShare = await userDialer.conference.startScreenShare(roomId); console.log('Screen share started');

Stop Screen Share

await userDialer.conference.stopScreenShare(roomId);

Listen for Screen Share

userDialer.on('conference:screenshare:started', ({ participantId }) => { console.log(`${participantId} started screen sharing`); }); userDialer.on('conference:screenshare:stopped', ({ participantId }) => { console.log(`${participantId} stopped screen sharing`); });

Recording

Start Recording

const recording = await userDialer.conference.startRecording(roomId); console.log('Recording started:', recording.id);

Stop Recording

const recordedFile = await userDialer.conference.stopRecording(roomId); console.log('Recording URL:', recordedFile.url); console.log('Duration:', recordedFile.duration);

Get Recordings

const recordings = await userDialer.conference.getRecordings(roomId); recordings.forEach(rec => { console.log(`Recording: ${rec.url}`); console.log(`Duration: ${rec.duration}s`); console.log(`Size: ${rec.size}MB`); });

In-Room Messaging

Party Line Messaging - Real-time ephemeral messaging within active video conference rooms.

In-room messaging is designed for party lines and video conferencing, providing real-time chat that exists only during the conference session. These messages are not persisted after the room ends.

Send Message

await userDialer.conference.sendMessage(roomId, { content: 'Hello everyone!', type: 'text' }); // Send with mentions await userDialer.conference.sendMessage(roomId, { content: '@alice Great point!', type: 'text', mentions: ['0xAlice...'] }); // Share media in room await userDialer.conference.sendMessage(roomId, { type: 'image', media: { file: imageFile, caption: 'Check this out' } });

Receive Messages

userDialer.on('conference:message', ({ roomId, message, sender }) => { console.log(`[${roomId}] ${sender.displayName}: ${message.content}`); // Display with sender's profile console.log('Avatar:', sender.avatar); console.log('Wallet:', sender.walletAddress); });

Message Types

In-room messaging supports:

  • Text messages - Plain text and formatted messages
  • Emojis and reactions - React to messages and video
  • Links - Share URLs with automatic preview
  • Media - Share images and GIFs
  • Mentions - Tag participants with @mentions

Note: In-room messages are ephemeral and only available during the active conference session. For persistent messaging, use Bucket Messaging or Matrix Messaging.

Layout Management

Set Layout

// Grid view (default) await userDialer.conference.setLayout(roomId, 'grid'); // Speaker view (focus on active speaker) await userDialer.conference.setLayout(roomId, 'speaker'); // Spotlight view (focus on specific participant) await userDialer.conference.setLayout(roomId, 'spotlight', { spotlightParticipantId: participantId });

Room Management

End Room (Host Only)

await userDialer.conference.end(roomId);

Remove Participant (Host Only)

await userDialer.conference.removeParticipant(roomId, participantId);

Transfer Host

await userDialer.conference.transferHost(roomId, newHostParticipantId);

Advanced Features

Breakout Rooms

// Create breakout rooms const breakoutRooms = await userDialer.conference.createBreakoutRooms(roomId, { numberOfRooms: 3, autoAssign: true // or manually assign participants }); // Move participant to breakout room await userDialer.conference.moveToBreakout(roomId, participantId, breakoutRooms[0].id); // Close all breakout rooms await userDialer.conference.closeBreakoutRooms(roomId);

Polls

// Create poll const poll = await userDialer.conference.createPoll(roomId, { question: 'Should we launch next week?', options: ['Yes', 'No', 'Need more time'], duration: 60 // seconds }); // Vote await userDialer.conference.vote(roomId, poll.id, optionIndex); // Get results const results = await userDialer.conference.getPollResults(roomId, poll.id);

Raise Hand

// Raise hand await userDialer.conference.raiseHand(roomId); // Lower hand await userDialer.conference.lowerHand(roomId); // Listen for raised hands userDialer.on('conference:hand:raised', ({ participantId }) => { console.log(`${participantId} raised their hand`); });

Complete Example: React Conference Component

import { useState, useEffect } from 'react'; import { DialClient, ConferenceRoom, Participant } from '@dial/sdk'; export function VideoConference({ dial, roomId }) { const [room, setRoom] = useState<ConferenceRoom | null>(null); const [participants, setParticipants] = useState<Participant[]>([]); const [isMuted, setIsMuted] = useState(false); const [isVideoEnabled, setIsVideoEnabled] = useState(true); const [isScreenSharing, setIsScreenSharing] = useState(false); useEffect(() => { joinRoom(); setupEventListeners(); return () => { leaveRoom(); }; }, [roomId]); const joinRoom = async () => { const joinedRoom = await userDialer.conference.join({ roomId, video: true, audio: true, displayName: 'Alice.eth' }); setRoom(joinedRoom); setParticipants(joinedRoom.participants); }; const setupEventListeners = () => { userDialer.on('conference:participant:joined', (participant) => { setParticipants(prev => [...prev, participant]); }); userDialer.on('conference:participant:left', (participant) => { setParticipants(prev => prev.filter(p => p.id !== participant.id) ); }); }; const leaveRoom = async () => { if (room) { await userDialer.conference.leave(room.id); } }; const toggleMute = async () => { if (isMuted) { await userDialer.conference.unmuteAudio(roomId); } else { await userDialer.conference.muteAudio(roomId); } setIsMuted(!isMuted); }; const toggleVideo = async () => { if (isVideoEnabled) { await userDialer.conference.disableVideo(roomId); } else { await userDialer.conference.enableVideo(roomId); } setIsVideoEnabled(!isVideoEnabled); }; const toggleScreenShare = async () => { if (isScreenSharing) { await userDialer.conference.stopScreenShare(roomId); } else { await userDialer.conference.startScreenShare(roomId); } setIsScreenSharing(!isScreenSharing); }; return ( <div className="conference"> <div className="participants-grid"> {participants.map(participant => ( <div key={participant.id} className="participant"> <video ref={(el) => { if (el) { const stream = userDialer.conference.getParticipantStream( roomId, participant.id ); el.srcObject = stream; } }} autoPlay playsInline /> <div className="participant-info"> <span>{participant.displayName}</span> {participant.isMuted && <span>🔇</span>} </div> </div> ))} </div> <div className="controls"> <button onClick={toggleMute}> {isMuted ? '🔇 Unmute' : '🔊 Mute'} </button> <button onClick={toggleVideo}> {isVideoEnabled ? '📹 Disable Video' : '🚫 Enable Video'} </button> <button onClick={toggleScreenShare}> {isScreenSharing ? '⏹️ Stop Share' : '🖥️ Share Screen'} </button> <button onClick={leaveRoom} className="danger"> 📞 Leave </button> </div> </div> ); }

Quality Settings

// Set video quality await userDialer.conference.setVideoQuality(roomId, { resolution: '720p', // '360p', '480p', '720p', '1080p' frameRate: 30, bitrate: 1500 // kbps }); // Enable/disable adaptive quality await userDialer.conference.setAdaptiveQuality(roomId, true);

Analytics

// Get room statistics const stats = await userDialer.conference.getStats(roomId); console.log('Total duration:', stats.duration); console.log('Peak participants:', stats.peakParticipants); console.log('Total messages:', stats.messageCount); console.log('Network quality:', stats.networkQuality);

Next Steps

Last updated on