Primeros pasos con RealtimeKit
Esta guía lo guiará a través de la integración del complemento Capacitor RealtimeKit para agregar videoconferencias impulsadas por Cloudflare Calls a su aplicación.
Instalación
Section titled “Instalación”Instale el complemento usando npm:
npm install @capgo/capacitor-realtimekitnpx cap syncDependencias
Section titled “Dependencias”Este complemento utiliza Cloudflare RealtimeKit SDK:
- iOS: RealtimeKitCoreiOS (instalado automáticamente a través del Administrador de paquetes Swift)
- Android:
com.cloudflare.realtimekit:ui-androidversión0.2.2
Personalizando Android Versión RealtimeKit
Section titled “Personalizando Android Versión RealtimeKit”En build.gradle de tu aplicación:
buildscript { ext { realtimekitUiVersion = '0.2.2' // or your desired version }}iOS Configuración
Section titled “iOS Configuración”Agregue lo siguiente al Info.plist de su aplicación:
<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>Android Configuración
Section titled “Android Configuración”Agregue los siguientes permisos a su 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" />Uso básico
Section titled “Uso básico”Importar el complemento
Section titled “Importar el complemento”import { CapacitorRealtimekit } from '@capgo/capacitor-realtimekit';Inicializar el complemento
Section titled “Inicializar el complemento”async function initializeRealtimeKit() { try { await CapacitorRealtimekit.initialize(); console.log('RealtimeKit initialized'); } catch (error) { console.error('Failed to initialize RealtimeKit:', error); }}Iniciar una reunión
Section titled “Iniciar una reunión”async function startMeeting(meetingUrl: string) { try { await CapacitorRealtimekit.startMeeting({ url: meetingUrl }); console.log('Meeting started'); } catch (error) { console.error('Failed to start meeting:', error); }}Ejemplo completo
Section titled “Ejemplo completo”Aquí tienes un servicio integral de videoconferencia:
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');Configuración de llamadas de Cloudflare
Section titled “Configuración de llamadas de Cloudflare”Para utilizar este complemento, debe configurar Llamadas de Cloudflare:
1. Crear una cuenta de Cloudflare
Section titled “1. Crear una cuenta de Cloudflare”Regístrate en Cloudflare si no tienes una cuenta.
2. Habilitar llamadas API
Section titled “2. Habilitar llamadas API”- Navegue a su panel de Cloudflare
- Vaya a la sección Llamadas
- Habilite las llamadas API
- Obtenga sus credenciales API
3. Crear URL de reunión
Section titled “3. Crear URL de reunión”Necesita un servicio de backend para crear URL de reuniones. Ejemplo de uso de trabajadores de Cloudflare:
// 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);}Uso avanzado
Section titled “Uso avanzado”Reunión con configuración personalizada
Section titled “Reunión con configuración personalizada”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 }); } }}Manejo de permisos
Section titled “Manejo de permisos”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 });}Integración de reacción
Section titled “Integración de reacción”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> );}Integración de Vue
Section titled “Integración de 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 }; }};Mejores prácticas
Section titled “Mejores prácticas”- Inicializar temprano: inicialice RealtimeKit cuando se inicie su aplicación
- Manejar errores: siempre envuelva las llamadas en bloques try-catch
- Solicitar permisos: asegúrese de tener permisos de cámara/micrófono antes de comenzar
- Probar red: verifique la conectividad a Internet antes de unirse
- Audio de fondo: configure los modos de fondo para iOS
- Experiencia de usuario: muestra los estados de carga durante la inicialización
- Limpiar URL: valide las URL de la reunión antes de usarlas
Problemas comunes
Section titled “Problemas comunes”La reunión no comienza
Section titled “La reunión no comienza”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); }}Permiso denegado
Section titled “Permiso denegado”El iOS, asegúrese de que Info.plist tenga todas las descripciones de uso requeridas. En Android, verifique que los permisos de AndroidManifest.xml estén presentes.
Problemas de audio en iOS
Section titled “Problemas de audio en iOS”Asegúrese de que el modo de audio de fondo esté configurado en Info.plist:
<key>UIBackgroundModes</key><array> <string>audio</string> <string>voip</string></array>Próximos pasos
Section titled “Próximos pasos”- Explore la Referencia API para obtener documentación completa del método
- Leer Documentación de llamadas de Cloudflare
- Consulte la aplicación de ejemplo
- Consulte el tutorial para una implementación completa.