שילוב LiveKit לוועידות וידאו באתר שלך
LiveKit — שרת WebRTC בקוד פתוח עם ארכיטקטורת SFU המספק חביון נמוך וקנה מידה לאלפי משתתפים. אתה מקבל שליטה מלאה על הנתונים והממשק, ללא מגבלות משתתפים או עמלות נסתרות. עם זאת, בפרויקטים אמיתיים אנו נתקלים בבעיות טיפוסיות: הגדרת ICE שגויה, בעיות NAT ובחירות ארכיטקטורת SFU לא אופטימליות, המובילות לקפיצות חביון של 5–10 שניות. הניסיון שלנו עם למעלה מ-50 שילובי WebRTC מראה שהגדרה נכונה של LiveKit פותרת בעיות אלה מהשורש.
כיצד להפחית חביון בשיחות וידאו עם LiveKit
ארכיטקטורת SFU (Selective Forwarding Unit) מבטיחה חביון מתחת ל-200 אלפיות השנייה גם בערוצים חלשים. בניגוד ל-Jitsi, LiveKit משתמש בקודקים מותאמים (VP9, H.264) ובקצב סיביות אדפטיבי. עם 50 משתתפים, הפרש החביון מגיע לפי 3–5 לטובת LiveKit. יתר על כן, אינך משלם דמי רישוי: עלות השרת עבור 1000 משתמשים היא מינימלית.
כיצד לשלב את LiveKit: מקרה בוחן של פלטפורמת חינוך
לאחרונה יישמנו את LiveKit עבור לקוח — פלטפורמת חינוך עם 5000 משתמשים. הארכיטקטורה המקורית השתמשה ב-Jitsi, אך לאחר המעבר ל-LiveKit, החביון ירד מ-800 אלפיות השנייה ל-150 אלפיות השנייה, ועלויות השרת ירדו ב-40%. השתמשנו ב-LiveKit Server 1.5 על Docker, בקצה אחורי של Node.js עם LiveKit SDK, ובחזית של React 18 עם @livekit/components-react.
התקנת LiveKit Server
---
# docker-compose.yml services: livekit:
image: livekit/livekit-server:latest
command: --dev
ports:
- "7880:7880"
- "7881:7881"
- "7882:7882/udp"
environment:
LIVEKIT_KEYS: "APIkey: APIsecret"
לסביבת ייצור, השתמש בתצורה עם IP חיצוני ושרתי TURN:
# livekit.yaml port: 7880 rtc: tcp_port: 7881 udp_port: 7882 use_external_ip: true keys: APIkey: APIsecret כיצד לשלב את LiveKit באפליקציית React?
קצה אחורי: יצירת טוקן
import { AccessToken, RoomServiceClient } from 'livekit-server-sdk';
const roomService = new RoomServiceClient(
process.env.LIVEKIT_URL,
process.env.LIVEKIT_API_KEY,
process.env.LIVEKIT_API_SECRET
);
await roomService.createRoom({
name: `room-${meetingId}`,
maxParticipants: 50,
emptyTimeout: 10 * 60
});
function generateToken(roomName: string, participant: Participant): string {
const at = new AccessToken(
process.env.LIVEKIT_API_KEY,
process.env.LIVEKIT_API_SECRET,
{
identity: participant.id,
name: participant.name,
ttl: '2h'
}
);
at.addGrant({
roomJoin: true,
room: roomName,
canPublish: true,
canSubscribe: true,
canPublishData: true
});
return at.toJwt();
}
app.post('/api/meetings/:id/join', authenticate, async (req, res) => {
const meeting = await meetingRepo.findById(req.params.id);
if (!meeting) return res.status(404).json({ error: 'Meeting not found' });
const token = generateToken(`room-${meeting.id}`, {
id: req.user.id,
name: req.user.displayName
});
res.json({ token, serverUrl: process.env.LIVEKIT_URL });
});
לקוח (React)
import { LiveKitRoom, VideoConference, RoomAudioRenderer } from '@livekit/components-react';
function VideoRoom({ roomId }) {
const [token, setToken] = useState(null);
const [serverUrl, setServerUrl] = useState('');
useEffect(() => {
fetch(`/api/meetings/${roomId}/join`, { method: 'POST' })
.then(r => r.json())
.then(({ token, serverUrl }) => {
setToken(token);
setServerUrl(serverUrl);
});
}, [roomId]);
if (!token) return <div>Подключение...</div>;
return (
<LiveKitRoom token={token} serverUrl={serverUrl} connect video audio>
<VideoConference />
<RoomAudioRenderer />
</LiveKitRoom>
);
}זוהי הסט המינימלי. לממשק מותאם אישית, השתמש ב-# docker-compose.yml services: livekit: image: livekit/livekit-server:latest command: --dev ports: - "7880:7880" - "7881:7881" - "7882:7882/udp" environment: LIVEKIT_KEYS: "APIkey: APIsecret" וב-# livekit.yaml port: 7880 rtc: tcp_port: 7881 udp_port: 7882 use_external_ip: true keys: APIkey: APIsecret .
הקלטת פגישות
import { EgressClient, EncodedFileType } from 'livekit-server-sdk';
const egressClient = new EgressClient(
process.env.LIVEKIT_URL,
process.env.LIVEKIT_API_KEY,
process.env.LIVEKIT_API_SECRET
);
const egress = await egressClient.startRoomCompositeEgress(
`room-${meetingId}`,
{
file: {
fileType: EncodedFileType.MP4,
s3: {
accessKey: process.env.AWS_ACCESS_KEY,
secret: process.env.AWS_SECRET,
bucket: 'recordings',
key: `meetings/${meetingId}/${Date.now()}.mp4`
}
}
}
); השוואת LiveKit עם חלופות
| פרמטר | LiveKit | Jitsi | Daily.co |
|---|---|---|---|
| רישיון | קוד פתוח (Apache 2.0) | Apache 2.0 | קנייני |
| מקסימום משתתפים | 1000+ | 50–100 | 50 (חינם) |
| חביון (50 משתתפים) | < 200 אלפיות השנייה | 300–600 אלפיות השנייה | 200–400 אלפיות השנייה |
| אירוח עצמי | כן | כן | לא |
| עלות קנה מידה | קוד פתוח + שרת | קוד פתוח + שרת | קנייני |
LiveKit מהיר פי 3 בחביון מ-Jitsi ואין לו עלויות נסתרות.
כיצד להשיג פעולה יציבה עם 1000 משתתפים?
עבור 1000+ משתתפים, השתמש באשכולות SFU. LiveKit תומך בקנה מידה אופקי באמצעות Redis ו-NATS. הגדר שרתי TURN (לדוגמה, Coturn) למעבר NAT. חשוב: בחר שרתים במספר אזורים לחביון נמוך. כמו כן, אפשר קצב סיביות אדפטיבי והשתמש באפשרות import { AccessToken, RoomServiceClient } from 'livekit-server-sdk'; const roomService = new RoomServiceClient( process.env.LIVEKIT_URL, process.env.LIVEKIT_API_KEY, process.env.LIVEKIT_API_SECRET ); await roomService.createRoom({ name: `room-${meetingId}`, maxParticipants: 50, emptyTimeout: 10 * 60 }); function generateToken(roomName: string, participant: Participant): string { const at = new AccessToken( process.env.LIVEKIT_API_KEY, process.env.LIVEKIT_API_SECRET, { identity: participant.id, name: participant.name, ttl: '2h' } ); at.addGrant({ roomJoin: true, room: roomName, canPublish: true, canSubscribe: true, canPublishData: true }); return at.toJwt(); } app.post('/api/meetings/:id/join', authenticate, async (req, res) => { const meeting = await meetingRepo.findById(req.params.id); if (!meeting) return res.status(404).json({ error: 'Meeting not found' }); const token = generateToken(`room-${meeting.id}`, { id: req.user.id, name: req.user.displayName }); res.json({ token, serverUrl: process.env.LIVEKIT_URL }); }); בצד הלקוח.
תכונות LiveKit: השוואת גרסאות
| תכונה | קוד פתוח | ענן (Enterprise) |
|---|---|---|
| הקלטה (Egress) | כן | כן (מובנה) |
| סטרימינג (RTMP/WHIP) | כן | כן |
| צ'אט ושיתוף קבצים | דרך WebSocket | מובנה |
| רקעים וירטואליים | דורש עיבוד | מובנה |
| אנליטיקה | מדדי Prometheus | לוח מחוונים |
| תמיכה | קהילה | 24/7 |
תהליך העבודה
שלבי השילוב
- אנליטיקה — הערכת התשתית הקיימת, מספר המשתמשים, דרישות הקלטה וממשק משתמש.
- עיצוב — בחירת ארכיטקטורה (SFU יחיד או אשכול), הגדרת שרתי TURN, תוכנית גיבוי.
- יישום — פיתוח קצה אחורי (אימות, ניהול חדרים), שילוב רכיבי React.
- בדיקות — מבחני עומס עד 500 משתתפים, בדיקות חביון ואיכות שמע.
- פריסה — פריסת שרת, הגדרת ניטור, בדיקות עומס.
מה כלול בשילוב
- הגדרת LiveKit Server על השרת שלך או שלנו (Docker).
- פיתוח מודול קצה אחורי ליצירת טוקנים וניהול חדרים.
- שילוב רכיבי React מ-
import { LiveKitRoom, VideoConference, RoomAudioRenderer } from '@livekit/components-react'; function VideoRoom({ roomId }) { const [token, setToken] = useState(null); const [serverUrl, setServerUrl] = useState(''); useEffect(() => { fetch(`/api/meetings/${roomId}/join`, { method: 'POST' }) .then(r => r.json()) .then(({ token, serverUrl }) => { setToken(token); setServerUrl(serverUrl); }); }, [roomId]); if (!token) return <div>Подключение...</div>; return ( <LiveKitRoom token={token} serverUrl={serverUrl} connect video audio> <VideoConference /> <RoomAudioRenderer /> </LiveKitRoom> ); }עם אפשרות לממשק משתמש מותאם אישית. - הגדרת הקלטה דרך Egress API (S3, MinIO).
- תיעוד ושבועיים של תמיכה לאחר המסירה.
- אחריות ל-30 יום על פעולה יציבה של שיחות וידאו.
לוח זמנים
- שילוב בסיסי (שרת + טוקנים + ממשק React) — בין 5 ל-10 ימי עסקים.
- שילוב מורחב (ממשק מותאם אישית, הקלטה, פאנל ניהול) — בין 15 ל-25 ימי עסקים.
LiveKit תומך גם בהצפנה מקצה לקצה ובאימות JWT. בשילוב שלנו, אנו מגדירים אבטחה כברירת מחדל.
כיצד להזמין שילוב?
צור קשר להערכה חינמית של הפרויקט שלך. ננתח את הדרישות ונציע פתרון אופטימלי. קבל ייעוץ — כתוב לטלגרם או למייל. יישום LiveKit משתלם בשל הפחתת עלויות התשתית כבר מהחודש הראשון. הזמן שילוב LiveKit לפרויקט שלך היום.







