Розробка системи вебінарів для LMS (інтеграція з видеоконференціями)
Вебінарна система в LMS — це не просто ссилка на Zoom. Повнофункціональна інтеграція включає створення комнат через API, автоматичну відправлення ссилок студентам, контроль посещаємості, запис вебінарів та збереження записів у матеріалах курсу.
Вибір відеоплатформи
| Платформа | API | Особливості |
|---|---|---|
| Zoom | REST API, Webhooks | Стандарт, широкий API, гарна запис |
| Jitsi Meet | REST API, self-hosted | Безплатна, повний контроль |
| BigBlueButton | REST API, open-source | Спеціально для освіти, whiteboard, breakout rooms |
| Daily.co | REST API + SDK | Вбудованої відео прямо в LMS |
| Whereby | REST API | Простая встройка, iframe |
BigBlueButton — рекомендується для освітніх LMS: вбудований whiteboard, polls, breakout rooms, запис з розбивкою по учасникам. Self-hosted.
Інтеграція з Zoom API
class ZoomIntegration {
async createMeeting({ topic, startTime, durationMin, hostEmail }) {
const token = await this.getAccessToken();
const response = await fetch(`https://api.zoom.us/v2/users/${hostEmail}/meetings`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
topic,
type: 2,
start_time: startTime.toISOString(),
duration: durationMin,
settings: {
host_video: true,
waiting_room: true,
auto_recording: 'cloud',
mute_upon_entry: true,
},
}),
});
return response.json();
}
}
Інтеграція з BigBlueButton
class BigBlueButtonService {
public function createMeeting(string $meetingId, string $name, array $options = []): array {
$params = array_merge([
'meetingID' => $meetingId,
'name' => $name,
'record' => 'true',
'autoStartRecording' => 'false',
'allowStartStopRecording' => 'true',
], $options);
$queryString = http_build_query($params);
$checksum = sha1('create' . $queryString . $this->secret);
$params['checksum'] = $checksum;
$response = Http::get("{$this->url}/api/create", $params);
return $response->json();
}
public function getJoinUrl(string $meetingId, string $fullName, string $role): string {
$password = $role === 'moderator' ? $this->moderatorPw : $this->attendeePw;
$params = "meetingID={$meetingId}&fullName=" . urlencode($fullName) .
"&password={$password}";
$checksum = sha1('join' . $params . $this->secret);
return "{$this->url}/api/join?{$params}&checksum={$checksum}";
}
}
Відстеження посещаємості
app.post('/webhooks/zoom', async (req, res) => {
const { event, payload } = req.body;
if (event === 'meeting.participant_joined') {
await db.webinarAttendance.upsert({
webinarId: payload.object.id,
userId: await findUserByEmail(payload.object.participant.email),
joinedAt: new Date(payload.object.participant.join_time),
});
}
if (event === 'meeting.participant_left') {
await db.webinarAttendance.update({
webinarId: payload.object.id,
userId: await findUserByEmail(payload.object.participant.email),
}, {
leftAt: new Date(payload.object.participant.leave_time),
durationMin: payload.object.participant.duration,
});
}
res.status(200).json({ status: 'ok' });
});
Обробка записей
async function processWebinarRecording(meetingId, downloadUrl, token) {
const s3Key = `recordings/${meetingId}.mp4`;
const response = await fetch(downloadUrl, {
headers: { Authorization: `Bearer ${token}` }
});
await s3.upload({ Bucket: process.env.S3_BUCKET, Key: s3Key, Body: response.body }).promise();
const videoUrl = `https://${process.env.CDN_DOMAIN}/${s3Key}`;
await db.webinars.update({ meetingId }, { recordingUrl: videoUrl });
await notifyAbsentStudents(meetingId, videoUrl);
}
Вбудованої відео через Daily.co
function WebinarRoom({ roomUrl, token }) {
const callFrame = useRef(null);
useEffect(() => {
callFrame.current = DailyIframe.createFrame({
url: roomUrl,
token,
iframeStyle: { width: '100%', height: '600px' },
});
callFrame.current.on('participant-counts-updated', ({ present }) => {
trackAttendance(present);
});
callFrame.current.join();
return () => callFrame.current.destroy();
}, [roomUrl]);
return <div id="daily-container" />;
}
Терміни
Інтеграція з Zoom API: створення зустрічей, відправлення ссилок студентам, базова посещаємість — 4–5 днів. Запис з загрузкою в S3 — 2–3 дні. Self-hosted BigBlueButton з повною інтеграцією в LMS — 7–10 днів. Daily.co вбудованої відео — 3–4 дні.







