Skip to content

Implementación

Esta guía utiliza Flutter SDK 0.3.8. Consulte las instrucciones de instalación y actualización.

Crear una instancia de AudioRecognition

Cree un SORIAudioRecognizer con las credenciales de su aplicación SORI. No escriba credenciales reales directamente en código fuente público. Cárguelas mediante la configuración de la versión, un almacenamiento seguro o un proceso de compilación específico del entorno.

El siguiente ejemplo utiliza valores de --dart-define para evitar que el código fuente contenga datos confidenciales:

dart
import 'package:sorisdk_flutter/sorisdk_flutter.dart';

const applicationId = String.fromEnvironment('SORI_APP_ID');
const secretKey = String.fromEnvironment('SORI_SECRET_KEY');

final recognizer = SORIAudioRecognizer(
  applicationId: applicationId,
  secretKey: secretKey,
);

await recognizer.configure();

Ejecute la aplicación con los valores proporcionados por su entorno local o de CI:

bash
flutter run \
  --dart-define=SORI_APP_ID=your-application-id \
  --dart-define=SORI_SECRET_KEY=your-secret-key

WARNING

app_id y secret_key autentican su aplicación ante el servidor de la API de SORI. No incluya valores reales en commits de repositorios, aplicaciones de ejemplo, incidencias, capturas de pantalla ni documentación pública.

Reconocedor Web

Las compilaciones para navegadores no deben contener el secret_key de larga duración de SORI. Después de preparar el bridge Web durante la instalación, cree el reconocedor con un endpoint de clave efímera en el servidor de su aplicación:

dart
final recognizer = SORIAudioRecognizer.web(
  applicationId: applicationId,
  webAuth: SORIWebAuthOptions.ephemeralKeyEndpoint(
    Uri.parse('/api/sori/ephemeral-key'),
    requestCredentials: SORIWebRequestCredentials.sameOrigin,
  ),
);

await recognizer.configure();

Proteja el endpoint con los mismos controles de sesión, origen, CSRF y limitación de frecuencia que utiliza para las demás API de su aplicación. El secret_key de larga duración permanece en el servidor, mientras que applicationId se compila en la aplicación del navegador y no es secreto. El endpoint solo devuelve al navegador la clave efímera de corta duración. Consulte Clave efímera.

Escuchar eventos de reconocimiento

Suscríbase a recognizer.events antes de iniciar el reconocimiento. Según el evento de la plataforma nativa, la información de la campaña estará disponible en event.campaign o en el payload del evento.

dart
import 'dart:async';

import 'package:flutter/foundation.dart' show kIsWeb;

import 'package:sorisdk_flutter/sorisdk_flutter.dart';

late final SORIAudioRecognizer recognizer;
StreamSubscription<SORIRecognitionEvent>? subscription;

subscription = recognizer.events.listen((event) {
  if (event.type == SORIRecognitionEventType.stateChanged) {
    final state = event.payload['state'];
    // Update your UI for STARTING, STARTED, or stopped states.
  }

  final campaign = event.campaign;
  if (campaign != null) {
    // Render campaign.name, campaign.imageUrl, and campaign.actionUrl.
  }

  if (event.type == SORIRecognitionEventType.audioMarkerStateChanged) {
    final state = event.audioMarkerState;
    // Update marker-specific UI or state.
  }

  if (kIsWeb && event.type == SORIRecognitionEventType.audioMarkerFound) {
    final marker = event.audioMarkerIdentity;
    // Render the Console-resolved marker ID and name on Web.
    // Native current-marker UI uses audioMarkerStateChanged above.
  }

  if (event.type == SORIRecognitionEventType.error ||
      event.type == SORIRecognitionEventType.networkError) {
    // Show event.message in your app's error UI.
  }
});

Conciliar el segmento de actividad actual

La guía siguiente corresponde a los callbacks de campaña existentes. Para los nuevos resultados de actividad aceptados por el SDK, use las reglas de actualización por ID exacto de Estado de Audio Marker y resultados de actividad; estos resultados pueden actualizar la actividad histórica correspondiente.

Los eventos de campaña y reconocimiento exponen un event.activityId opcional, mientras que una campaña puede exponer event.campaign?.materialId y event.campaign?.trait?.marker. Muestre inmediatamente el primer evento de campaña y mantenga un segmento actual explícito en el estado de la aplicación.

  • Un evento posterior con el mismo event.activityId no vacío solo puede refinar la fila actual. No busque filas anteriores ni derive la identidad de actividad de los ID de campaña o material.
  • Los servidores anteriores pueden devolver un ID de actividad null. Un fallback mediante material solo es seguro cuando la fila actual tiene el mismo event.campaign?.materialId no vacío.
  • Conserve la hora, la posición y los demás metadatos de UI de la primera observación de la fila actual. Los reporters nativos y Web anclan sus metadatos de transporte a la primera observación; la aplicación no debe sustituirlos por la hora del callback de refinamiento.
  • Conserve el primer marker y los campos de campaña refinados cuando un evento posterior no tenga marker o incluya datos de campaña menos completos.
  • Un evento campaignFound o recognitionResult de otro material, o una parada explícita del reconocimiento, cierra el segmento. Ignore los refinamientos retrasados de una actividad anterior después de ese punto. audioMarkerFound no cierra el segmento.
  • SORIRecognitionEventType.audioMarkerFound notifica el descubrimiento independiente de un marcador. Por sí solo no crea ni refina una fila de actividad. Lea el ID y el nombre resueltos por SORI Console en event.audioMarkerIdentity.

A(activity-1) -> A'(activity-1, marker) -> A(activity-1, marker miss) es una sola fila que conserva el marker. A(activity-1) -> B(activity-2) -> delayed A'(activity-1) mantiene B como actual y no modifica la A histórica.

Cancele la suscripción cuando se descarte el ámbito del widget o de la aplicación:

dart
await subscription?.cancel();

Iniciar y detener el reconocimiento

Llame a startRecognition() después de configurar el reconocedor y cuando la interfaz de usuario esté lista para recibir eventos.

dart
await recognizer.startRecognition(
  notification: const SORIAndroidNotificationOptions(
    title: 'SORI recognition',
    body: 'Listening for SORI audio signals',
  ),
);

La opción notification se utiliza para las notificaciones del servicio en primer plano de Android. En iOS y Web se ignora. En Web, llame a startRecognition() desde una acción del usuario para que el navegador pueda solicitar permiso para usar el micrófono.

Para detener el reconocimiento:

dart
await recognizer.stopRecognition();

También puede consultar el estado actual de la grabadora:

dart
final isRunning = await recognizer.isRecorderRunning();

Activar el reconocimiento de Audio Marker

El reconocimiento de Audio Marker está desactivado de forma predeterminada. Actívelo solo si su configuración de SORI Console utiliza Audio Markers.

dart
await recognizer.configure(
  config: const SORIRecognitionConfig(audiomarker: true),
);

Para mostrar el marcador actual y enriquecer actividades posteriores, use las API de estado y resultados de actividad gestionadas por el SDK. El SDK gestiona la caducidad, los atributos de marcador y las actualizaciones de la misma actividad. Los callbacks de campaña y descubrimiento existentes siguen siendo compatibles.

Flutter Web conserva su comportamiento de reconocimiento y eventos. El nuevo estado actual nativo, la caducidad y la actualización independiente de marcadores tardíos se aplican a Android/iOS. getCurrentAudioMarkerState() devuelve null en Web; no lo interprete como prueba de que no se ha detectado un marcador.

Gestionar las acciones de campaña

Cuando una campaña tenga una URL de acción, decida en su aplicación si debe abrirse. Después de que la aplicación acepte la URL, llame a handleActionUrl() para informar de la interacción y gestionarla mediante el SDK.

dart
final actionUrl = campaign.actionUrl;
if (actionUrl != null && actionUrl.isNotEmpty) {
  await recognizer.handleActionUrl(actionUrl);
}

Actualizar la base de datos de reconocimiento

El SDK puede solicitar al reconocedor nativo que actualice su base de datos de reconocimiento local.

Actualmente, updateDatabase() no es compatible con Web.

dart
final result = await recognizer.updateDatabase();

if (!result.success) {
  // Inspect result.errorMessage and show a retry option if needed.
}