Premiers pas avec RealtimeKit
Ce guide vous guidera dans l’intégration du plugin Capacitor RealtimeKit pour ajouter la visioconférence optimisée par Cloudflare Calls à votre application.
##Installation
Installez le plugin en utilisant npm :
npm install @capgo/capacitor-realtimekitnpx cap syncDépendances
Section titled “Dépendances”Ce plugin utilise le Cloudflare RealtimeKit SDK :
- iOS : RealtimeKitCoreiOS (installé automatiquement via Swift Package Manager)
- Android :
com.cloudflare.realtimekit:ui-androidversion0.2.2
Personnalisation de la version Android RealtimeKit
Section titled “Personnalisation de la version Android RealtimeKit”Dans le build.gradle de votre application :
buildscript { ext { realtimekitUiVersion = '0.2.2' // or your desired version }}iOSConfiguration
Section titled “iOSConfiguration”Ajoutez les éléments suivants au Info.plist de votre application :
<key>NSCameraUsageDescription</key><string>We need camera access for video calls</string>
<key>NSMicrophoneUsageDescription</key><string>We need microphone access for audio calls</string>
<key>NSPhotoLibraryUsageDescription</key><string>We need photo library access to share images</string>
<key>NSBluetoothPeripheralUsageDescription</key><string>We need Bluetooth access for audio routing</string>
<key>UIBackgroundModes</key><array> <string>audio</string> <string>voip</string> <string>fetch</string> <string>remote-notification</string></array>AndroidConfiguration
Section titled “AndroidConfiguration”Ajoutez les autorisations suivantes à votre AndroidManifest.xml :
<uses-permission android:name="android.permission.CAMERA" /><uses-permission android:name="android.permission.RECORD_AUDIO" /><uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-feature android:name="android.hardware.camera" android:required="false" /><uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />Utilisation de base
Section titled “Utilisation de base”Importer le plugin
Section titled “Importer le plugin”import { CapacitorRealtimekit } from '@capgo/capacitor-realtimekit';Initialiser le plugin
Section titled “Initialiser le plugin”async function initializeRealtimeKit() { try { await CapacitorRealtimekit.initialize(); console.log('RealtimeKit initialized'); } catch (error) { console.error('Failed to initialize RealtimeKit:', error); }}Démarrer une réunion
Section titled “Démarrer une réunion”async function startMeeting(meetingUrl: string) { try { await CapacitorRealtimekit.startMeeting({ url: meetingUrl }); console.log('Meeting started'); } catch (error) { console.error('Failed to start meeting:', error); }}Exemple complet
Section titled “Exemple complet”Voici un service complet de visioconférence :
import { CapacitorRealtimekit } from '@capgo/capacitor-realtimekit';
export interface MeetingConfig { url: string; displayName?: string; audioEnabled?: boolean; videoEnabled?: boolean;}
export class VideoConferenceService { private isInitialized = false; private currentMeetingUrl: string | null = null;
async initialize(): Promise<boolean> { if (this.isInitialized) { console.log('RealtimeKit already initialized'); return true; }
try { await CapacitorRealtimekit.initialize(); this.isInitialized = true; console.log('RealtimeKit initialized successfully'); return true; } catch (error) { console.error('Failed to initialize RealtimeKit:', error); return false; } }
async startMeeting(config: MeetingConfig): Promise<void> { if (!this.isInitialized) { const initialized = await this.initialize(); if (!initialized) { throw new Error('Failed to initialize RealtimeKit'); } }
try { await CapacitorRealtimekit.startMeeting({ url: config.url });
this.currentMeetingUrl = config.url; console.log('Meeting started:', config.url); } catch (error) { console.error('Failed to start meeting:', error); throw error; } }
async joinMeeting(meetingUrl: string, displayName?: string): Promise<void> { const config: MeetingConfig = { url: meetingUrl, displayName: displayName };
await this.startMeeting(config); }
getCurrentMeetingUrl(): string | null { return this.currentMeetingUrl; }
isInMeeting(): boolean { return this.currentMeetingUrl !== null; }
async getPluginVersion(): Promise<string> { try { const result = await CapacitorRealtimekit.getPluginVersion(); return result.version; } catch (error) { console.error('Failed to get plugin version:', error); return 'unknown'; } }}
// Usageconst videoService = new VideoConferenceService();
// Initialize on app startawait videoService.initialize();
// Start a meetingawait videoService.startMeeting({ url: 'https://your-cloudflare-calls-url.com/meeting/123'});
// Join an existing meetingawait videoService.joinMeeting( 'https://your-cloudflare-calls-url.com/meeting/456', 'John Doe');Configuration des appels Cloudflare
Section titled “Configuration des appels Cloudflare”Pour utiliser ce plugin, vous devez configurer Cloudflare Calls :
1. Créer un compte Cloudflare
Section titled “1. Créer un compte Cloudflare”Inscrivez-vous sur Cloudflare si vous n’avez pas de compte.
2. Activer les appels API
Section titled “2. Activer les appels API”- Accédez à votre tableau de bord Cloudflare
- Accédez à la section Appels
- Activez les appels API
- Obtenez vos identifiants API
3. Créer des URL de réunion
Section titled “3. Créer des URL de réunion”Vous avez besoin d’un service backend pour créer des URL de réunion. Exemple utilisant Cloudflare Workers :
// Cloudflare Worker exampleexport default { async fetch(request: Request): Promise<Response> { const { pathname } = new URL(request.url);
if (pathname === '/create-meeting') { const meetingId = generateMeetingId(); const meetingUrl = `https://your-app.calls.cloudflare.com/${meetingId}`;
return new Response(JSON.stringify({ meetingId, meetingUrl }), { headers: { 'Content-Type': 'application/json' } }); }
return new Response('Not found', { status: 404 }); }};
function generateMeetingId(): string { return Math.random().toString(36).substring(2, 15);}Utilisation avancée
Section titled “Utilisation avancée”Réunion avec configuration personnalisée
Section titled “Réunion avec configuration personnalisée”class MeetingManager { private videoService: VideoConferenceService;
constructor() { this.videoService = new VideoConferenceService(); }
async createAndJoinMeeting(userName: string): Promise<string> { // Initialize if needed await this.videoService.initialize();
// Call your backend to create a meeting const meetingUrl = await this.createMeetingOnBackend();
// Join the meeting await this.videoService.joinMeeting(meetingUrl, userName);
return meetingUrl; }
async createMeetingOnBackend(): Promise<string> { const response = await fetch('https://your-api.com/create-meeting', { method: 'POST', headers: { 'Content-Type': 'application/json' } });
const data = await response.json(); return data.meetingUrl; }
async shareMeetingLink(meetingUrl: string) { // Use Capacitor Share API if ('share' in navigator) { await (navigator as any).share({ title: 'Join my meeting', text: 'Join me for a video call', url: meetingUrl }); } }}Gestion des autorisations
Section titled “Gestion des autorisations”import { Capacitor } from '@capacitor/core';
async function checkAndRequestPermissions(): Promise<boolean> { if (Capacitor.getPlatform() === 'web') { // Request browser permissions try { const stream = await navigator.mediaDevices.getUserMedia({ audio: true, video: true });
// Stop the stream, we just needed permission stream.getTracks().forEach(track => track.stop()); return true; } catch (error) { console.error('Permission denied:', error); return false; } }
// On native platforms, permissions are requested automatically return true;}
// Use before starting a meetingconst hasPermissions = await checkAndRequestPermissions();if (hasPermissions) { await videoService.startMeeting({ url: meetingUrl });}Intégration de React
Section titled “Intégration de React”import { useEffect, useState } from 'react';import { VideoConferenceService } from './VideoConferenceService';
function VideoCallComponent() { const [videoService] = useState(() => new VideoConferenceService()); const [isReady, setIsReady] = useState(false);
useEffect(() => { videoService.initialize().then(setIsReady); }, []);
const joinMeeting = async (meetingUrl: string) => { if (!isReady) { console.error('Video service not ready'); return; }
try { await videoService.joinMeeting(meetingUrl, 'User Name'); } catch (error) { console.error('Failed to join meeting:', error); } };
return ( <div> <button onClick={() => joinMeeting('https://your-meeting-url')} disabled={!isReady} > Join Meeting </button> </div> );}Intégration Vue
Section titled “Intégration Vue”import { ref, onMounted } from 'vue';import { VideoConferenceService } from './VideoConferenceService';
export default { setup() { const videoService = new VideoConferenceService(); const isReady = ref(false);
onMounted(async () => { isReady.value = await videoService.initialize(); });
const joinMeeting = async (meetingUrl: string) => { if (!isReady.value) { console.error('Video service not ready'); return; }
try { await videoService.joinMeeting(meetingUrl, 'User Name'); } catch (error) { console.error('Failed to join meeting:', error); } };
return { isReady, joinMeeting }; }};## meilleures pratiques
- Initialiser tôt : initialisez RealtimeKit au démarrage de votre application
- Gérer les erreurs : enveloppez toujours les appels dans des blocs try-catch
- Demander des autorisations : assurez-vous des autorisations de la caméra/du microphone avant de commencer
- Test du réseau : vérifiez la connectivité Internet avant de rejoindre
- Audio de fond : configurez les modes d’arrière-plan pour iOS
- Expérience utilisateur : afficher les états de chargement lors de l’initialisation
- Nettoyer les URL : validez les URL des réunions avant utilisation
Problèmes courants
Section titled “Problèmes courants”La réunion ne démarre pas
Section titled “La réunion ne démarre pas”async function troubleshootMeeting(meetingUrl: string) { // Check initialization const version = await videoService.getPluginVersion(); console.log('Plugin version:', version);
// Verify URL format if (!meetingUrl.startsWith('https://')) { console.error('Invalid meeting URL, must use HTTPS'); return; }
// Try starting meeting try { await videoService.startMeeting({ url: meetingUrl }); } catch (error) { console.error('Meeting failed:', error); }}Autorisation refusée
Section titled “Autorisation refusée”Le iOS, assurez-vous qu’Info.plist dispose de toutes les descriptions d’utilisation requises. Sur Android, vérifiez que les autorisations AndroidManifest.xml sont présentes.
Problèmes audio sur iOS
Section titled “Problèmes audio sur iOS”Assurez-vous que le mode audio d’arrière-plan est configuré dans Info.plist :
<key>UIBackgroundModes</key><array> <string>audio</string> <string>voip</string></array>Prochaines étapes
Section titled “Prochaines étapes”- Explorez la API Reference pour une documentation complète de la méthode
- Lire la Documentation des appels Cloudflare
- Consultez l’exemple d’application
- Voir le tutoriel pour une mise en œuvre complète