Administración de la grabación de llamadas en el cliente
Importante
La funcionalidad descrita en este artículo se encuentra actualmente en versión preliminar pública. Esta versión preliminar se ofrece sin un Acuerdo de Nivel de Servicio y no se recomienda para cargas de trabajo de producción. Es posible que algunas características no sean compatibles o que tengan sus funcionalidades limitadas. Para más información, consulte Términos de uso complementarios de las Versiones Preliminares de Microsoft Azure.
La grabación de llamadas permite a los usuarios grabar llamadas que realizan con Azure Communication Services. En este artículo, aprenderemos a administrar la grabación en el lado cliente. Antes de empezar, debe configurar la grabación en el lado del servidor.
Requisitos previos
- Una cuenta de Azure con una suscripción activa. Cree una cuenta gratuita.
- Un recurso de Communication Services implementado. Cree un recurso de Communication Services.
- Un token de acceso de usuario para habilitar el cliente de llamada. Para más información, consulte Inicio rápido: Creación y administración de tokens de acceso.
- Opcional: finalizar el inicio rápido para agregar llamadas de voz a la aplicación.
Soporte técnico
En las tablas siguientes se define la compatibilidad con la grabación en Azure Communication Services.
Identidades y tipos de llamadas
En las tablas siguientes se muestra compatibilidad con la grabación para un tipo de llamada y una identidad específicos.
Identidades | Reuniones en Teams | Sala | Llamada 1:1 | Llamada grupal | Llamada de interoperabilidad de Teams individual | Llamada de interoperabilidad de Teams de grupo |
---|---|---|---|---|---|---|
Usuario de Communication Services | ✔️[1] | ✔️[2] | ✔️[2] | ✔️[2] | ✔️[1] | ✔️[1][2] |
Usuario de Microsoft 365 | ✔️[1] | ✔️[2] | ✔️[1] | ✔️[1][2] |
[1] Estos tipos de llamadas admiten la grabación de cumplimiento y la nube de Teams.
[2] Estos tipos de llamadas admiten la grabación de Azure Communication Services.
Operaciones
En las tablas siguientes se muestra la compatibilidad de las API individuales en el SDK de llamadas a tipos de identidad individuales.
Operations | Usuario de Communication Services | Usuario de Microsoft 365 |
---|---|---|
Obtener notificación de que la grabación se inició o detuvo | ✔️ | ✔️ |
Obtención del estado de grabación | ✔️ | ✔️ |
Obtener notificación de que la grabación está disponible | ✔️[1] | ✔️[1] |
Obtenga información sobre si se requiere consentimiento explícito | ✔️[2] | ✔️[2] |
Dar consentimiento explícito para que se registre | ✔️[2] | ✔️[2] |
[1] El usuario no recibe una notificación de que la grabación está disponible. Puede obtener la grabación en la nube de Teams a través de Microsoft Graph API. Puede suscribirse a una notificación en Azure Communication Services cuando la grabación esté disponible.
[2] Esta funcionalidad solo está disponible en reuniones de Teams y llamadas de interoperabilidad de Teams de grupo.
SDK
En las tablas siguientes se muestra compatibilidad con la grabación en SDK individuales de Azure Communication Services.
Platforms | Web | IU Web | iOS | Interfaz de usuario de iOS | Android | UI de Android | Windows |
---|---|---|---|---|---|---|---|
Se admite | ✔️ | ✔️[1] | ✔️[1] | ✔️[1] | ✔️[1] | ✔️[1] | ✔️[1] |
[1] Estos SDK no admiten el consentimiento explícito.
Instalación del SDK
Use el comando npm install
para instalar los SDK comunes y de llamada de Azure Communication Services para JavaScript:
npm install @azure/communication-common --save
npm install @azure/communication-calling --save
Inicialización de los objetos necesarios
Se requiere una instancia de CallClient
para la mayoría de las operaciones de llamada. Al crear una nueva instancia de CallClient
, puede configurarla con opciones personalizadas, como una instancia de Logger
.
Con la instancia de CallClient
, puede crear una instancia de CallAgent
llamando al createCallAgent
. Este método devuelve un objeto de instancia CallAgent
de manera asincrónica.
El método createCallAgent
utiliza CommunicationTokenCredential
como argumento. Acepta un token de acceso de usuario.
Puede usar el método getDeviceManager
en la instancia de CallClient
para acceder a deviceManager
.
const { CallClient } = require('@azure/communication-calling');
const { AzureCommunicationTokenCredential} = require('@azure/communication-common');
const { AzureLogger, setLogLevel } = require("@azure/logger");
// Set the logger's log level
setLogLevel('verbose');
// Redirect log output to console, file, buffer, REST API, or whatever location you want
AzureLogger.log = (...args) => {
console.log(...args); // Redirect log output to console
};
const userToken = '<USER_TOKEN>';
callClient = new CallClient(options);
const tokenCredential = new AzureCommunicationTokenCredential(userToken);
const callAgent = await callClient.createCallAgent(tokenCredential, {displayName: 'optional Azure Communication Services user name'});
const deviceManager = await callClient.getDeviceManager()
Cuál es la mejor forma de administrar la conectividad del SDK en la infraestructura de Microsoft
La instancia de Call Agent
le ayuda a administrar llamadas (para unirse o iniciar llamadas). Para trabajar con el SDK de llamadas, debe conectarse a la infraestructura de Microsoft para obtener notificaciones de llamadas entrantes y coordinar otros detalles de la llamada. Call Agent
tiene dos posibles estados:
Conectado: un valor connectionStatue Call Agent
con estado Connected
significa que el SDK de cliente está conectado y es capaz de recibir notificaciones de la infraestructura de Microsoft.
Desconectado: un valor connectionStatue Call Agent
con estado Disconnected
indica que hay un problema que impide que el SDK se conecte correctamente. Call Agent
se debe volver a crear.
invalidToken
: si un token ha expirado o no es válido, la instancia deCall Agent
se desconecta con este error.connectionIssue
: si hay un problema cuando el cliente se conecta a la infraestructura de Microsoft, después de muchos reintentos,Call Agent
expone el errorconnectionIssue
.
Para comprobar si el Call Agent
local está conectado a la infraestructura de Microsoft, inspeccione el valor actual de la propiedad connectionState
. Durante una llamada activa, puede escuchar el evento connectionStateChanged
para determinar si Call Agent
cambia de Conectado a Desconectado.
const connectionState = callAgentInstance.connectionState;
console.log(connectionState); // it may return either of 'Connected' | 'Disconnected'
const connectionStateCallback = (args) => {
console.log(args); // it will return an object with oldState and newState, each of having a value of either of 'Connected' | 'Disconnected'
// it will also return reason, either of 'invalidToken' | 'connectionIssue'
}
callAgentInstance.on('connectionStateChanged', connectionStateCallback);
Nota:
Esta API se ofrece a los desarrolladores como versión preliminar y puede cambiar en función de los comentarios que recibamos. No use esta API en un entorno de producción. Para usar esta API, use la versión beta del SDK web de llamadas de Azure Communication Services.
Grabación en la nube
La grabación de llamadas es una característica extendida de la llamada a la API principal. En primer lugar, debe importar características de llamada desde el SDK de llamadas:
import { Features} from "@azure/communication-calling";
A continuación, puede obtener el objeto de API de las características de grabación desde la instancia de llamada:
const callRecordingApi = call.feature(Features.Recording);
Para comprobar si se está grabando la llamada, inspeccione la propiedad isRecordingActive
de callRecordingApi
. Devuelve Boolean
.
const isRecordingActive = callRecordingApi.isRecordingActive;
También puede suscribirse a los cambios de grabación:
const isRecordingActiveChangedHandler = () => {
console.log(callRecordingApi.isRecordingActive);
};
callRecordingApi.on('isRecordingActiveChanged', isRecordingActiveChangedHandler);
Puede obtener una lista de grabaciones mediante la propiedad recordings
de callRecordingApi
. Devuelve RecordingInfo[]
, que tiene el estado actual de la grabación en la nube.
const recordings = callRecordingApi.recordings;
recordings.forEach(r => {
console.log("State: ${r.state}");
También puede suscribirse a recordingsUpdated
y obtener una colección de grabaciones actualizadas. Este evento se desencadena siempre que haya una actualización de grabación.
const cloudRecordingsUpdatedHandler = (args: { added: SDK.RecordingInfo[], removed: SDK.RecordingInfo[]}) => {
console.log('Recording started by: ');
args.added?.forEach(a => {
console.log('State: ${a.state}');
});
console.log('Recording stopped by: ');
args.removed?.forEach(r => {
console.log('State: ${r.state}');
});
};
callRecordingApi.on('recordingsUpdated', cloudRecordingsUpdatedHandler );
Consentimiento explícito
Cuando la reunión o llamada de Teams está configurada para requerir consentimiento explícito para la grabación y transcripción, es necesario recopilar el consentimiento de todos los participantes de la llamada para poder grabarlos. Puede proporcionar consentimiento de forma proactiva al unirse a la reunión o reactivamente cuando se inicie la grabación. Hasta que se dé consentimiento explícito, el audio, el vídeo y el uso compartido de pantalla de los participantes se deshabilitarán durante la grabación.
Puede comprobar si la grabación de la reunión requiere consentimiento explícito por propiedad isTeamsConsentRequired
. Si el valor se establece en true
, se requiere consentimiento explícito para el call
.
const isConsentRequired = callRecordingApi.isTeamsConsentRequired;
Si ya ha obtenido el consentimiento del usuario para la grabación, puede llamar al método grantTeamsConsent()
para indicar el consentimiento explícito al servicio. Este consentimiento es válido solo para una sesión de call
y los usuarios deben volver a proporcionar consentimiento si se vuelven a unir a la reunión.
callRecordingApi.grantTeamsConsent();
Se produce un error en los intentos de habilitar el uso compartido de audio, vídeo o pantalla cuando la grabación está activa, se requiere consentimiento explícito, pero aún no se da. Puede reconocer esta situación comprobando la de propiedades reason
de clase ParticipantCapabilities
para funcionalidades turnVideoOn
, unmuteMic
y shareScreen
. Puede encontrar esas funcionalidades en la característica call.feature(Features.Capabilities)
. Esas funcionalidades devolverían el motivo ExplicitConsentRequired
, ya que los usuarios necesitan proporcionar consentimiento explícito.
Instalación del SDK
Busque el archivo build.gradle
de nivel de proyecto y agregue mavenCentral()
a la lista de repositorios en buildscript
y allprojects
:
buildscript {
repositories {
...
mavenCentral()
...
}
}
allprojects {
repositories {
...
mavenCentral()
...
}
}
Luego, en el archivo build.gradle
de nivel de módulo, agregue las siguientes líneas a la sección dependencies
:
dependencies {
...
implementation 'com.azure.android:azure-communication-calling:1.0.0'
...
}
Inicialización de los objetos necesarios
Para crear una instancia de CallAgent
, debe llamar al método createCallAgent
en una instancia de CallClient
. Esta llamada devuelve un objeto de instancia de CallAgent
de manera asincrónica.
El método createCallAgent
toma CommunicationUserCredential
como argumento, que encapsula un token de acceso.
Para acceder a DeviceManager
, primero debe crear una instancia de callAgent
. A continuación, puede usar el método CallClient.getDeviceManager
para obtener DeviceManager
.
String userToken = '<user token>';
CallClient callClient = new CallClient();
CommunicationTokenCredential tokenCredential = new CommunicationTokenCredential(userToken);
android.content.Context appContext = this.getApplicationContext(); // From within an activity, for instance
CallAgent callAgent = callClient.createCallAgent(appContext, tokenCredential).get();
DeviceManager deviceManager = callClient.getDeviceManager(appContext).get();
Para establecer un nombre para mostrar para el autor de la llamada, use este método alternativo:
String userToken = '<user token>';
CallClient callClient = new CallClient();
CommunicationTokenCredential tokenCredential = new CommunicationTokenCredential(userToken);
android.content.Context appContext = this.getApplicationContext(); // From within an activity, for instance
CallAgentOptions callAgentOptions = new CallAgentOptions();
callAgentOptions.setDisplayName("Alice Bob");
DeviceManager deviceManager = callClient.getDeviceManager(appContext).get();
CallAgent callAgent = callClient.createCallAgent(appContext, tokenCredential, callAgentOptions).get();
Registro de llamadas
Nota:
Esta API se ofrece a los desarrolladores como versión preliminar y puede cambiar en función de los comentarios que recibamos. No use esta API en un entorno de producción. Para usar esta API, use la versión beta del Android SDK de llamadas de Azure Communication Services.
La grabación de llamadas es una característica extendida del objeto Call
principal.
Advertencia
Hasta la versión 1.1.0 y la versión beta 1.1.0-beta.1 del Android SDK para llamadas de Azure Communication Services, isRecordingActive
y addOnIsRecordingActiveChangedListener
formaron parte del objeto Call
. En el caso de las nuevas versiones beta, esas API se movieron como una característica extendida de Call
.
Primero debe obtener el objeto de la característica de grabación:
RecordingCallFeature callRecordingFeature = call.feature(Features.RECORDING);
Después, para comprobar si se está grabando la llamada, inspeccione la propiedad isRecordingActive
de callRecordingFeature
. Devuelve boolean
.
boolean isRecordingActive = callRecordingFeature.isRecordingActive();
También puede suscribirse a los cambios de grabación:
private void handleCallOnIsRecordingChanged(PropertyChangedEvent args) {
boolean isRecordingActive = callRecordingFeature.isRecordingActive();
}
callRecordingFeature.addOnIsRecordingActiveChangedListener(handleCallOnIsRecordingChanged);
Si desea iniciar la grabación desde la aplicación, siga primero Introducción a la grabación de llamadas para los pasos para configurar la grabación de llamadas.
Después de configurar la grabación de llamadas en el servidor, desde la aplicación Android, debe obtener el valor de ServerCallId
de la llamada y, a continuación, enviarlo al servidor para iniciar el proceso de grabación. Puede encontrar el valor de ServerCallId
mediante getServerCallId()
de la clase CallInfo
. Puede encontrar la clase CallInfo
en el objeto de clase mediante getInfo()
.
try {
String serverCallId = call.getInfo().getServerCallId().get();
// Send serverCallId to your recording server to start the call recording.
} catch (ExecutionException | InterruptedException e) {
} catch (UnsupportedOperationException unsupportedOperationException) {
}
Al iniciar la grabación desde el servidor, se desencadena el handleCallOnIsRecordingChanged
de eventos y el valor de callRecordingFeature.isRecordingActive()
es true
.
Al igual que iniciar la grabación de llamadas, si desea detener la grabación de llamadas, debe obtener ServerCallId
y enviarlo al servidor de grabación para que pueda detener la grabación:
try {
String serverCallId = call.getInfo().getServerCallId().get();
// Send serverCallId to your recording server to stop the call recording.
} catch (ExecutionException | InterruptedException e) {
} catch (UnsupportedOperationException unsupportedOperationException) {
}
Al detener la grabación desde el servidor, se desencadena el handleCallOnIsRecordingChanged
de eventos y el valor de callRecordingFeature.isRecordingActive()
es false
.
Configuración del sistema
Siga estos pasos para configurar el sistema.
Creación del proyecto de Xcode
En Xcode, cree un nuevo proyecto de iOS y seleccione la plantilla Aplicación de una vista. En este artículo se usa el marco SwiftUI, por lo que debe establecer el Lenguaje en Swift y la Interfaz en SwiftUI.
No va a crear pruebas en este artículo. Puede desactivar la casilla Incluir pruebas.
Instalación del paquete y las dependencias mediante CocoaPods
Cree un Podfile para la aplicación, como en este ejemplo:
platform :ios, '13.0' use_frameworks! target 'AzureCommunicationCallingSample' do pod 'AzureCommunicationCalling', '~> 1.0.0' end
Ejecute
pod install
.Abra
.xcworkspace
mediante Xcode.
Solicitud de acceso al micrófono
Para acceder al micrófono del dispositivo, debe actualizar la lista de propiedades de información de la aplicación mediante NSMicrophoneUsageDescription
. Establezca el valor asociado en una cadena que se incluye en el cuadro de diálogo empleado por el sistema para solicitar acceso al usuario.
Haga clic con el botón derecho en la entrada Info.plist del árbol del proyecto y seleccione Abrir como>Código fuente. Agregue las líneas siguientes a la sección <dict>
de nivel superior y guarde el archivo.
<key>NSMicrophoneUsageDescription</key>
<string>Need microphone access for VOIP calling.</string>
Instalación del marco de la aplicación
Abra el archivo ContentView.swift
del proyecto. Agregue una declaración import
a la parte superior del archivo para importar la biblioteca AzureCommunicationCalling
. Además, importe AVFoundation
. Lo necesitará para las solicitudes de permiso de audio en el código.
import AzureCommunicationCalling
import AVFoundation
Inicialización de CallAgent
Para crear una instancia de CallAgent
a partir de CallClient
, debe usar el método callClient.createCallAgent
, que devuelve de manera asincrónica un objeto CallAgent
después de que se inicializa.
Para crear un cliente de llamada, pase un objeto CommunicationTokenCredential
:
import AzureCommunication
let tokenString = "token_string"
var userCredential: CommunicationTokenCredential?
do {
let options = CommunicationTokenRefreshOptions(initialToken: token, refreshProactively: true, tokenRefresher: self.fetchTokenSync)
userCredential = try CommunicationTokenCredential(withOptions: options)
} catch {
updates("Couldn't created Credential object", false)
initializationDispatchGroup!.leave()
return
}
// tokenProvider needs to be implemented by Contoso, which fetches a new token
public func fetchTokenSync(then onCompletion: TokenRefreshOnCompletion) {
let newToken = self.tokenProvider!.fetchNewToken()
onCompletion(newToken, nil)
}
Pase el objeto CommunicationTokenCredential
que ha creado a CallClient
y establezca el nombre para mostrar:
self.callClient = CallClient()
let callAgentOptions = CallAgentOptions()
options.displayName = " iOS Azure Communication Services User"
self.callClient!.createCallAgent(userCredential: userCredential!,
options: callAgentOptions) { (callAgent, error) in
if error == nil {
print("Create agent succeeded")
self.callAgent = callAgent
} else {
print("Create agent failed")
}
})
Registro de llamadas
Nota:
Esta API se ofrece a los desarrolladores como versión preliminar y puede cambiar en función de los comentarios que recibamos. No use esta API en un entorno de producción. Para usar esta API, use la versión beta del iOS SDK de llamadas de Azure Communication Services.
La grabación de llamadas es una característica extendida del objeto Call
principal.
Advertencia
Hasta la versión 1.1.0 y la versión beta 1.1.0-beta.1 del iOS SDK de Azure Communication Services, isRecordingActive
formaba parte del objeto Call
, y didChangeRecordingState
formaba parte del delegado de CallDelegate
. En el caso de las nuevas versiones beta, esas API se movieron como una característica extendida de Call
.
Primero debe obtener el objeto de la característica de grabación:
let callRecordingFeature = call.feature(Features.recording)
Después, para comprobar si se está grabando la llamada, inspeccione la propiedad isRecordingActive
de callRecordingFeature
. Devuelve Bool
.
let isRecordingActive = callRecordingFeature.isRecordingActive;
También puede suscribirse a los cambios de grabación mediante la implementación del delegado RecordingCallFeatureDelegate
en la clase con el evento didChangeRecordingState
:
callRecordingFeature.delegate = self
// didChangeRecordingState is a member of RecordingCallFeatureDelegate
public func recordingCallFeature(_ recordingCallFeature: RecordingCallFeature, didChangeRecordingState args: PropertyChangedEventArgs) {
let isRecordingActive = recordingFeature.isRecordingActive
}
Si desea iniciar la grabación desde la aplicación, siga primero Introducción a la grabación de llamadas para los pasos para configurar la grabación de llamadas.
Después de configurar la grabación de llamadas en el servidor, desde la aplicación de iOS, debe obtener el valor de ServerCallId
de la llamada y, a continuación, enviarlo al servidor para iniciar el proceso de grabación. Puede encontrar el valor de ServerCallId
mediante getServerCallId()
de la clase CallInfo
. Puede encontrar la clase CallInfo
en el objeto de clase mediante getInfo()
.
// Send serverCallId to your recording server to start the call recording.
let serverCallId = call.info.getServerCallId(){ (serverId, error) in }
Al iniciar la grabación desde el servidor, se desencadena el didChangeRecordingState
de eventos y el valor de recordingFeature.isRecordingActive
es true
.
Al igual que iniciar la grabación de llamadas, si desea detener la grabación de llamadas, debe obtener ServerCallId
y enviarlo al servidor de grabación para que pueda detener la grabación:
// Send serverCallId to your recording server to stop the call recording.
let serverCallId = call.info.getServerCallId(){ (serverId, error) in }
Al detener la grabación desde el servidor, se desencadena el didChangeRecordingState
de eventos y el valor de recordingFeature.isRecordingActive
es false
.
Configuración del sistema
Siga estos pasos para configurar el sistema.
Creación del proyecto de Visual Studio
En el caso de una aplicación para la Plataforma universal de Windows, en Visual Studio 2022, cree un proyecto de Aplicación vacía (Universal Windows). Después de escribir el nombre del proyecto, puede elegir cualquier Windows SDK posterior a 10.0.17763.0.
En el caso de una aplicación WinUI 3, cree un nuevo proyecto con la plantilla Aplicación vacía, empaquetada (WinUI 3 en escritorio) para configurar una aplicación WinUI 3 de una sola página. Se requiere la versión 1.3 o posterior del SDK de aplicaciones de Windows.
Instalación del paquete y las dependencias mediante el Administrador de paquetes NuGet
Las API y bibliotecas de SDK de llamadas están disponibles públicamente a través de un paquete NuGet.
Para buscar, descargar e instalar el paquete NuGet del SDK de llamadas:
- Abra el Administrador de paquetes NuGet desde Herramientas>Administrador de paquetes NuGet>Administrar paquetes NuGet para la solución.
- Seleccione Explorar y, después, escriba Azure.Communication.Calling.WindowsClient en el cuadro de búsqueda.
- Asegúrese de que la casilla Incluir versión preliminar esté activada.
- Seleccione el paquete Azure.Communication.Calling.WindowsClient y, después, Azure.Communication.Calling.WindowsClient 1.4.0-beta.1 o una versión más reciente.
- Seleccione la casilla correspondiente al proyecto de Azure Communication Services en el panel derecho.
- Seleccione Instalar.
Registro de llamadas
La grabación de llamadas es una característica extendida del objeto Call
principal. Primero debe obtener el objeto de la característica de grabación:
RecordingCallFeature recordingFeature = call.Features.Recording;
Después, para comprobar si se está grabando la llamada, inspeccione la propiedad IsRecordingActive
de recordingFeature
. Devuelve boolean
.
boolean isRecordingActive = recordingFeature.IsRecordingActive;
También puede suscribirse a los cambios de grabación:
private async void Call__OnIsRecordingActiveChanged(object sender, PropertyChangedEventArgs args)
boolean isRecordingActive = recordingFeature.IsRecordingActive;
}
recordingFeature.IsRecordingActiveChanged += Call__OnIsRecordingActiveChanged;
Grabación de cumplimiento
La grabación de cumplimiento es la grabación basada en la directiva de Microsoft Teams. Puede habilitarlo mediante este tutorial: Introducción a la grabación basada en directivas de Teams para llamadas.
La grabación basada en directivas se inicia automáticamente cuando un usuario que tiene la directiva se une a una llamada. Para obtener una notificación de Azure Communication Services sobre la grabación, use el siguiente código:
const callRecordingApi = call.feature(Features.Recording);
const isComplianceRecordingActive = callRecordingApi.isRecordingActive;
const isComplianceRecordingActiveChangedHandler = () => {
console.log(callRecordingApi.isRecordingActive);
};
callRecordingApi.on('isRecordingActiveChanged', isComplianceRecordingActiveChangedHandler);
También puede implementar la grabación de cumplimiento mediante un bot de grabación personalizado. Consulte el ejemplo de GitHub.