Pular para conteúdo

Integração Mobile

Este guia explica como integrar a API do Videochamada.com.br em aplicativos mobile (iOS, Android e React Native) usando WebView.

Visão Geral

A forma mais simples de integrar videochamadas em seu app mobile é usando WebView. Esta abordagem:

  • Funciona imediatamente sem implementação WebRTC nativa
  • Mantém paridade de funcionalidades com a versão web
  • Requer apenas 3 passos para implementar

Pré-requisitos

Antes de começar, você precisa:

  1. Uma conta no Videochamada.com.br
  2. Um projeto criado no painel de gerenciamento
  3. Uma API Key válida (veja Autenticação e Token)

Passo 1: Obter sua API Key

  1. Acesse o painel de gerenciamento do seu projeto
  2. Navegue até a aba API Keys
  3. Clique em + Nova Chave para gerar uma nova API Key
  4. Copie e armazene a chave de forma segura

Segurança

Nunca exponha sua API Key no código do aplicativo. Faça as chamadas à API através do seu backend.

Passo 2: Criar Chamada via API

Seu backend deve criar a chamada e retornar a URL para o app mobile.

Endpoint

POST https://api.videochamada.com.br/api/calls

Cabeçalhos

Authorization: Bearer {SUA_API_KEY}
Content-Type: application/json

Corpo da Requisição (opcional)

{
  "title": "Consulta com Dr. Silva",
  "expiresAt": "2025-12-31T23:59:59Z",
  "recording": true
}

Resposta

{
  "id": "abc123-def456",
  "status": "created",
  "url": "https://call.videochamada.com.br/call/abc123-def456"
}

URL da Chamada

Use o campo url da resposta para abrir a chamada no WebView. Você pode adicionar o parâmetro ?username=NomeDoUsuario para pré-definir o nome do participante.

Passo 3: Abrir Chamada em WebView

iOS (Swift)

import UIKit
import WebKit

class VideoCallViewController: UIViewController, WKUIDelegate, WKNavigationDelegate {

    var webView: WKWebView!
    var callUrl: String = ""
    var username: String = ""

    override func viewDidLoad() {
        super.viewDidLoad()

        // Configurar WebView com permissões de mídia
        let config = WKWebViewConfiguration()
        config.allowsInlineMediaPlayback = true
        config.mediaTypesRequiringUserActionForPlayback = []

        webView = WKWebView(frame: view.bounds, configuration: config)
        webView.uiDelegate = self
        webView.navigationDelegate = self
        webView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        view.addSubview(webView)

        // Carregar URL da chamada
        let urlString = "\(callUrl)?username=\(username.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? "")"
        if let url = URL(string: urlString) {
            webView.load(URLRequest(url: url))
        }
    }

    // Permitir acesso à câmera e microfone
    func webView(_ webView: WKWebView,
                 requestMediaCapturePermissionFor origin: WKSecurityOrigin,
                 initiatedByFrame frame: WKFrameInfo,
                 type: WKMediaCaptureType,
                 decisionHandler: @escaping (WKPermissionDecision) -> Void) {
        decisionHandler(.grant)
    }
}

Info.plist

Adicione as permissões necessárias no Info.plist:

<key>NSCameraUsageDescription</key>
<string>Necessário para videochamadas</string>
<key>NSMicrophoneUsageDescription</key>
<string>Necessário para videochamadas</string>

Android (Kotlin)

import android.Manifest
import android.content.pm.PackageManager
import android.os.Bundle
import android.webkit.*
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat

class VideoCallActivity : AppCompatActivity() {

    private lateinit var webView: WebView
    private val PERMISSION_REQUEST_CODE = 1001

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Verificar permissões
        checkPermissions()

        // Configurar WebView
        webView = WebView(this).apply {
            settings.javaScriptEnabled = true
            settings.mediaPlaybackRequiresUserGesture = false
            settings.domStorageEnabled = true

            webChromeClient = object : WebChromeClient() {
                override fun onPermissionRequest(request: PermissionRequest) {
                    runOnUiThread {
                        request.grant(request.resources)
                    }
                }
            }
        }

        setContentView(webView)

        // Carregar URL da chamada
        val callUrl = intent.getStringExtra("CALL_URL") ?: return
        val username = intent.getStringExtra("USERNAME") ?: "Participante"
        val encodedUsername = java.net.URLEncoder.encode(username, "UTF-8")

        webView.loadUrl("$callUrl?username=$encodedUsername")
    }

    private fun checkPermissions() {
        val permissions = arrayOf(
            Manifest.permission.CAMERA,
            Manifest.permission.RECORD_AUDIO
        )

        val permissionsToRequest = permissions.filter {
            ContextCompat.checkSelfPermission(this, it) != PackageManager.PERMISSION_GRANTED
        }

        if (permissionsToRequest.isNotEmpty()) {
            ActivityCompat.requestPermissions(
                this,
                permissionsToRequest.toTypedArray(),
                PERMISSION_REQUEST_CODE
            )
        }
    }

    override fun onBackPressed() {
        if (webView.canGoBack()) {
            webView.goBack()
        } else {
            super.onBackPressed()
        }
    }
}

AndroidManifest.xml

Adicione as permissões necessárias:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />

React Native

Instale a dependência:

npm install react-native-webview
import React, { useRef } from 'react';
import { StyleSheet, View, Platform, PermissionsAndroid } from 'react-native';
import { WebView } from 'react-native-webview';

const VideoCallScreen = ({ route }) => {
  const { callUrl, username } = route.params;
  const webViewRef = useRef(null);

  // Solicitar permissões no Android
  React.useEffect(() => {
    const requestPermissions = async () => {
      if (Platform.OS === 'android') {
        try {
          const grants = await PermissionsAndroid.requestMultiple([
            PermissionsAndroid.PERMISSIONS.CAMERA,
            PermissionsAndroid.PERMISSIONS.RECORD_AUDIO,
          ]);

          console.log('Permissões:', grants);
        } catch (err) {
          console.warn(err);
        }
      }
    };

    requestPermissions();
  }, []);

  const encodedUsername = encodeURIComponent(username || 'Participante');
  const fullUrl = `${callUrl}?username=${encodedUsername}`;

  return (
    <View style={styles.container}>
      <WebView
        ref={webViewRef}
        source={{ uri: fullUrl }}
        style={styles.webview}
        javaScriptEnabled={true}
        domStorageEnabled={true}
        mediaPlaybackRequiresUserAction={false}
        allowsInlineMediaPlayback={true}

        // Permissões de mídia
        mediaCapturePermissionGrantType="grant"

        // Configurações adicionais
        startInLoadingState={true}
        allowsFullscreenVideo={true}

        onError={(syntheticEvent) => {
          const { nativeEvent } = syntheticEvent;
          console.warn('WebView error:', nativeEvent);
        }}
      />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  webview: {
    flex: 1,
  },
});

export default VideoCallScreen;

Permissões iOS (Info.plist)

Para React Native no iOS, adicione ao ios/[SeuApp]/Info.plist:

<key>NSCameraUsageDescription</key>
<string>Necessário para videochamadas</string>
<key>NSMicrophoneUsageDescription</key>
<string>Necessário para videochamadas</string>

Fluxo Completo

┌─────────────────┐      ┌─────────────────┐      ┌─────────────────┐
│   App Mobile    │      │   Seu Backend   │      │  Videochamada   │
│                 │      │                 │      │      API        │
└────────┬────────┘      └────────┬────────┘      └────────┬────────┘
         │                        │                        │
         │  1. Solicitar chamada  │                        │
         │───────────────────────>│                        │
         │                        │                        │
         │                        │  2. POST /api/calls    │
         │                        │───────────────────────>│
         │                        │                        │
         │                        │  3. Retorna URL        │
         │                        │<───────────────────────│
         │                        │                        │
         │  4. Retorna URL        │                        │
         │<───────────────────────│                        │
         │                        │                        │
         │  5. Abre WebView       │                        │
         │─────────────────────────────────────────────────>
         │                        │                        │

Troubleshooting

Câmera/Microfone não funcionam

  • iOS: Verifique se as permissões estão no Info.plist
  • Android: Verifique se as permissões estão no AndroidManifest.xml e se foram solicitadas em runtime
  • React Native: Certifique-se de que mediaPlaybackRequiresUserAction={false} está configurado

WebView não carrega

  • Verifique se o dispositivo tem conexão com a internet
  • Confirme que a URL da chamada está correta
  • No Android, certifique-se de que javaScriptEnabled={true}

Chamada não conecta

  • Verifique se a chamada não expirou (expiresAt)
  • Confirme que o status da chamada é created ou active
  • Teste a URL diretamente no navegador do dispositivo

Erro 401 (Unauthorized)

  • Verifique se a API Key está correta
  • Confirme que a API Key está ativa no painel
  • Certifique-se de usar Bearer {API_KEY} no header

Próximos Passos