{"id":2250,"date":"2023-09-18T08:10:47","date_gmt":"2023-09-18T08:10:47","guid":{"rendered":"https:\/\/blogs.encamina.com\/piensa-en-software-desarrolla-en-colores\/?p=2250"},"modified":"2023-09-18T08:57:10","modified_gmt":"2023-09-18T08:57:10","slug":"primeros-pasos-con-azure-communication-service-en-flutter-para-hacer-video-llamadas","status":"publish","type":"post","link":"https:\/\/blogs.encamina.com\/piensa-en-software-desarrolla-en-colores\/primeros-pasos-con-azure-communication-service-en-flutter-para-hacer-video-llamadas\/","title":{"rendered":"Primeros pasos con Azure Communication Service en Flutter para hacer videollamadas"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2253\" src=\"http:\/\/blogs.encamina.com\/piensa-en-software-desarrolla-en-colores\/wp-content\/uploads\/sites\/21\/2023\/09\/videollamadas-y-Flutter.jpg\" alt=\"\" width=\"647\" height=\"455\" srcset=\"https:\/\/encaminablogs.wpenginepowered.com\/piensa-en-software-desarrolla-en-colores\/wp-content\/uploads\/sites\/21\/2023\/09\/videollamadas-y-Flutter.jpg 647w, https:\/\/encaminablogs.wpenginepowered.com\/piensa-en-software-desarrolla-en-colores\/wp-content\/uploads\/sites\/21\/2023\/09\/videollamadas-y-Flutter-300x211.jpg 300w, https:\/\/encaminablogs.wpenginepowered.com\/piensa-en-software-desarrolla-en-colores\/wp-content\/uploads\/sites\/21\/2023\/09\/videollamadas-y-Flutter-610x429.jpg 610w\" sizes=\"auto, (max-width: 647px) 100vw, 647px\" \/> En este post vamos a ver c\u00f3mo comenzar a integrar <strong>Azure Communication Service<\/strong> en nuestras aplicaciones. Crearemos el servicio en Azure y lo utilizaremos desde una aplicaci\u00f3n Android\/iOS creada con <strong>flutter<\/strong>.<\/p>\n<p><!-- \/wp:post-content --><\/p>\n<p><!-- wp:paragraph --><\/p>\n<p>\u00a1\u00a1\u00a1Comenzamos!!! <!--more--><\/p>\n<p><!-- \/wp:paragraph --><\/p>\n<p><!-- wp:heading --><\/p>\n<h2 class=\"wp-block-heading\">\u00bfQu\u00e9 vamos a crear?<\/h2>\n<p><!-- \/wp:heading --><\/p>\n<p><!-- wp:paragraph --><\/p>\n<p>Para poneos en contexto, aqu\u00ed vemos el resultado final de la app que vamos a crear.<\/p>\n<p><!-- \/wp:paragraph --><\/p>\n<p><!-- wp:image {\"align\":\"center\",\"id\":3321,\"linkDestination\":\"custom\"} --><\/p>\n<figure class=\"wp-block-image aligncenter\"><a href=\"http:\/\/blogs.encamina.com\/por-una-nube-sostenible\/wp-content\/uploads\/sites\/19\/2023\/05\/demo-calling-android.gif\"><img decoding=\"async\" class=\"wp-image-3321 aligncenter\" src=\"http:\/\/blogs.encamina.com\/por-una-nube-sostenible\/wp-content\/uploads\/sites\/19\/2023\/05\/demo-calling-android.gif\" alt=\"Aplicaci\u00f3n de v\u00eddeo llamada en Android que se va a construir en este post\" \/><\/a><\/figure>\n<p><!-- \/wp:image --><\/p>\n<p><!-- wp:paragraph --><\/p>\n<p>N\u00f3tese que las opciones que nos ofrece <em>Communication Service<\/em> son tan amplias que es imposible abordarlas todas en un art\u00edculo, por lo que, como he indicado en el t\u00edtulo, aqu\u00ed vamos a dar nuestros primeros pasos. Nos permite el env\u00edo de email, SMS, llamadas de voz, chat y videollamadas. Concretamente, vamos a tratar la llamada grupal, aunque utilizando este servicio tambi\u00e9n se podr\u00eda implementar llamadas punto a punto.<\/p>\n<p><!-- \/wp:paragraph --><\/p>\n<p><!-- wp:heading --><\/p>\n<h2 class=\"wp-block-heading\">Creando el servicio en Azure<\/h2>\n<p><!-- \/wp:heading --><\/p>\n<p><!-- wp:paragraph --><\/p>\n<p>Crear este servicio es bastante sencillo. Lo primero que tenemos que hacer es ir a nuestro portal de <strong>Azure<\/strong> y crear un <strong>nuevo recurso<\/strong>.<\/p>\n<p><!-- \/wp:paragraph --><\/p>\n<p><!-- wp:image {\"align\":\"center\",\"id\":3312,\"linkDestination\":\"custom\"} --><\/p>\n<figure class=\"wp-block-image aligncenter\"><a href=\"http:\/\/blogs.encamina.com\/por-una-nube-sostenible\/wp-content\/uploads\/sites\/19\/2023\/05\/azure_communication_service_1.png\"><img decoding=\"async\" class=\"wp-image-3312 aligncenter\" src=\"http:\/\/blogs.encamina.com\/por-una-nube-sostenible\/wp-content\/uploads\/sites\/19\/2023\/05\/azure_communication_service_1.png\" alt=\"Portal de azure en el que se selecciona la opci\u00f3n para crear un nuevo recurso\" \/><\/a><\/figure>\n<p><!-- \/wp:image --><\/p>\n<p><!-- wp:paragraph --><\/p>\n<p>El recurso que nos interesa es <em>Communication Service. <\/em>Una vez localizado, lo creamos e informamos toda la informaci\u00f3n que se nos solicita.<\/p>\n<p><!-- \/wp:paragraph --><\/p>\n<p><!-- wp:image {\"align\":\"center\",\"id\":3315,\"linkDestination\":\"custom\"} --><\/p>\n<figure class=\"wp-block-image aligncenter\"><a href=\"http:\/\/blogs.encamina.com\/por-una-nube-sostenible\/wp-content\/uploads\/sites\/19\/2023\/05\/azure_communication_service_2.png\"><img decoding=\"async\" class=\"wp-image-3315 aligncenter\" src=\"http:\/\/blogs.encamina.com\/por-una-nube-sostenible\/wp-content\/uploads\/sites\/19\/2023\/05\/azure_communication_service_2.png\" alt=\"Creaci\u00f3n de servicio de comunicaci\u00f3n en Azure\" \/><\/a><\/figure>\n<p><!-- \/wp:image --><\/p>\n<p><!-- wp:image {\"align\":\"center\",\"id\":3316,\"linkDestination\":\"custom\"} --><\/p>\n<figure class=\"wp-block-image aligncenter\"><a href=\"http:\/\/blogs.encamina.com\/por-una-nube-sostenible\/wp-content\/uploads\/sites\/19\/2023\/05\/azure_communication_service_3.png\"><img decoding=\"async\" class=\"wp-image-3316 aligncenter\" src=\"http:\/\/blogs.encamina.com\/por-una-nube-sostenible\/wp-content\/uploads\/sites\/19\/2023\/05\/azure_communication_service_3.png\" alt=\"Datos necesarios para crear el servicio de comunicaci\u00f3n en Azure\" \/><\/a><\/figure>\n<p><!-- \/wp:image --><\/p>\n<p><!-- wp:paragraph --><\/p>\n<p>Una vez creado el servicio, lo que vamos a necesitar para empezar a utilizarlo es la <strong>cadena de conexi\u00f3n<\/strong>, que podemos encontrarla dentro de la secci\u00f3n <em>Keys, <\/em>que la utilizaremos para obtener los <em>tokens<\/em> utilizados por las aplicaciones cliente que utilizan el servicio.<\/p>\n<p><!-- \/wp:paragraph --><\/p>\n<p><!-- wp:heading --><\/p>\n<h2 class=\"wp-block-heading\">Precios del servicio<\/h2>\n<p><!-- \/wp:heading --><\/p>\n<p><!-- wp:paragraph --><\/p>\n<p>Antes de continuar, creo que es importante conocer el <em>pricing<\/em> de este servicio, por lo que aqu\u00ed dejo una tabla con los datos para el oeste de Europa.<\/p>\n<p><!-- \/wp:paragraph --><\/p>\n<p><!-- wp:image {\"align\":\"center\",\"id\":3317,\"linkDestination\":\"custom\"} --><\/p>\n<figure class=\"wp-block-image aligncenter\"><a href=\"http:\/\/blogs.encamina.com\/por-una-nube-sostenible\/wp-content\/uploads\/sites\/19\/2023\/05\/azure_communication_service_pricing.png\"><img decoding=\"async\" class=\"wp-image-3317 aligncenter\" src=\"http:\/\/blogs.encamina.com\/por-una-nube-sostenible\/wp-content\/uploads\/sites\/19\/2023\/05\/azure_communication_service_pricing.png\" alt=\"\" \/><\/a><\/figure>\n<p><!-- \/wp:image --><\/p>\n<p><!-- wp:paragraph --><\/p>\n<p>Asimismo, aqu\u00ed os dejo el link con todos los detalles:<a href=\"https:\/\/azure.microsoft.com\/es-es\/pricing\/details\/communication-services\/\"> https:\/\/azure.microsoft.com\/es-es\/pricing\/details\/communication-services\/<\/a><\/p>\n<p><!-- \/wp:paragraph --><\/p>\n<p><!-- wp:heading --><\/p>\n<h2 class=\"wp-block-heading\">Obteniendo token de acceso<\/h2>\n<p><!-- \/wp:heading --><\/p>\n<p><!-- wp:paragraph --><\/p>\n<p>Dado que el objetivo de este post es hacer una introducci\u00f3n a <em>Azure Communication Service<\/em> y empezar a usarlo en <em>flutter<\/em>, no nos hemos preocupado por la implementaci\u00f3n de la seguridad. Por ello, hemos creado un <strong>Azure Function<\/strong> que, utilizando la cadena de conexi\u00f3n del servicio, siempre devuelve un token nuevo, sin hacer ninguna comprobaci\u00f3n de seguridad.<\/p>\n<p><!-- \/wp:paragraph --><\/p>\n<p><!-- wp:code --><\/p>\n<pre class=\"wp-block-code\"><code>using Azure;\r\nusing Azure.Communication;\r\nusing Azure.Communication.Identity;\r\nusing Azure.Core;\r\nusing Microsoft.Azure.Functions.Worker;\r\nusing System.Text.Json;\r\n\r\nnamespace AuthFunction\r\n{\r\n    public class AuthFunction\r\n    {\r\n\r\n        [Function(\"function\")]\r\n        public static async Task&lt;object&gt; Run([HttpTrigger(AuthorizationLevel.Anonymous, \"get\", Route = null)] HttpRequestMessage req)\r\n        {\r\n            string connectionString = \"{YOUR_CONNECTION_STRING}}\";\r\n            CommunicationIdentityClient identityClient = new CommunicationIdentityClient(connectionString);\r\n            Response&lt;CommunicationUserIdentifier&gt; user = await identityClient.CreateUserAsync();\r\n            Response&lt;AccessToken&gt; userToken = await identityClient.GetTokenAsync(user, new[] { CommunicationTokenScope.VoIP });\r\n\r\n            JsonSerializerOptions options = new JsonSerializerOptions\r\n            {\r\n                PropertyNamingPolicy = JsonNamingPolicy.CamelCase,\r\n                WriteIndented = true\r\n            };\r\n            return JsonSerializer.Serialize(userToken.Value, options);\r\n        }\r\n    }\r\n}\r\n<\/code><\/pre>\n<p><!-- \/wp:code --><\/p>\n<p><!-- wp:paragraph --><\/p>\n<p>Por otro lado, si no quer\u00e9is implementar est\u00e1 funci\u00f3n, tambi\u00e9n se puede obtener un <em>token<\/em> para hacer pruebas desde el propio servicio en el portal de <em>Azure<\/em>, en el apartado <em>Identities &amp; User Access Tokens<\/em><\/p>\n<p><!-- \/wp:paragraph --><\/p>\n<p><!-- wp:image {\"align\":\"center\",\"id\":3318,\"linkDestination\":\"custom\"} --><\/p>\n<figure class=\"wp-block-image aligncenter\"><a href=\"http:\/\/blogs.encamina.com\/por-una-nube-sostenible\/wp-content\/uploads\/sites\/19\/2023\/05\/azure_communication_service_token.png\"><img decoding=\"async\" class=\"wp-image-3318 aligncenter\" src=\"http:\/\/blogs.encamina.com\/por-una-nube-sostenible\/wp-content\/uploads\/sites\/19\/2023\/05\/azure_communication_service_token.png\" alt=\"Generando un token de VOIP para Azure communication service en el portal de Azure\" \/><\/a><\/figure>\n<p><!-- \/wp:image --><\/p>\n<p><!-- wp:heading --><\/p>\n<h2 class=\"wp-block-heading\">Creando la aplicaci\u00f3n m\u00f3vil con Flutter<\/h2>\n<p><!-- \/wp:heading --><\/p>\n<p><!-- wp:paragraph --><\/p>\n<p>Una vez que tenemos el servicio y la funci\u00f3n de <em>Azure<\/em> para servirnos <em>tokens<\/em>, es el momento de crear los diferentes clientes que se conectar\u00e1n a este servicio.<\/p>\n<p><!-- \/wp:paragraph --><\/p>\n<p><!-- wp:paragraph --><\/p>\n<p>Dado que, en el momento de escribir este post, no hay ning\u00fan paquete que nos permita operar con<em> Communication Service <\/em>directamente en<em> flutter<\/em>, vamos a utilizar el SDK nativo. Por lo que vamos a dividir esta secci\u00f3n en tres puntos. En el primero de ellos, veremos todo el c\u00f3digo escrito en <strong>Dart<\/strong>, en la parte propia de <em>flutter<\/em>, la cual ser\u00e1 <strong>com\u00fan a la aplicaci\u00f3n Android y iOS<\/strong>. Y en las otras dos escribiremos todo lo relacionado con la parte de <strong>iOS y Android<\/strong> (escrito en <strong>swift y<\/strong> <strong>kotlin<\/strong>, respectivamente).<\/p>\n<p><!-- \/wp:paragraph --><\/p>\n<p><!-- wp:heading {\"level\":3} --><\/p>\n<h3 class=\"wp-block-heading\">Desarrollando parte com\u00fan en Dart<\/h3>\n<p><!-- \/wp:heading --><\/p>\n<p><!-- wp:paragraph --><\/p>\n<p>El primer paso que vamos a dar es el de a\u00f1adir los <strong>paquetes necesarios<\/strong> para hacer la app:<\/p>\n<p><!-- \/wp:paragraph --><\/p>\n<p><!-- wp:list --><\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul><!-- wp:list-item --><\/p>\n<li><strong>uuid<\/strong>: Nos servir\u00e1 para generar un UUID de manera sencilla. Lo vamos a utilizar para crear el identificador de una reuni\u00f3n.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><!-- \/wp:list-item --><\/p>\n<p><!-- wp:list-item --><\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li><strong>jwt_decoder<\/strong>: Con este paquete decodificaremos nuestro token y obtendremos el identificador \u00fanico. Aunque no es el objetivo de este post, este identificador es el que se utilizar\u00eda para hacer llamadas punto a punto.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><!-- \/wp:list-item --><\/p>\n<p><!-- wp:list-item --><\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li><strong>http<\/strong>: Lo utilizaremos para hacer la llamada a la funci\u00f3n de Azure que nos proporciona el token de acceso a communication service.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><!-- \/wp:list-item --><!-- \/wp:list --><\/p>\n<p><!-- wp:paragraph --><\/p>\n<p>Una vez que tenemos los paquetes instalados, procedemos a la creaci\u00f3n del <em>widget<\/em> que ser\u00e1 la pantalla inicial de nuestra app y desde la que se lanzar\u00e1 la funcionalidad de v\u00eddeo llamadas, encapsulada en el SDK.<\/p>\n<p><!-- \/wp:paragraph --><\/p>\n<p><!-- wp:image {\"align\":\"center\",\"id\":3322,\"linkDestination\":\"custom\"} --><\/p>\n<figure class=\"wp-block-image aligncenter\"><a href=\"http:\/\/blogs.encamina.com\/por-una-nube-sostenible\/wp-content\/uploads\/sites\/19\/2023\/05\/main_widget.png\"><img decoding=\"async\" class=\"wp-image-3322 aligncenter\" src=\"http:\/\/blogs.encamina.com\/por-una-nube-sostenible\/wp-content\/uploads\/sites\/19\/2023\/05\/main_widget.png\" alt=\"Pantalla de inicio de la aplicaci\u00f3n\" \/><\/a><\/figure>\n<p><!-- \/wp:image --><\/p>\n<p><!-- wp:paragraph --><\/p>\n<p>Comenzaremos escribiendo la parte de dise\u00f1o, que al ser una app de demo, es bastante sencilla.<\/p>\n<p><!-- \/wp:paragraph --><\/p>\n<p><!-- wp:code --><\/p>\n<pre class=\"wp-block-code\"><code>class MyHomePage extends StatefulWidget {\r\n  const MyHomePage({super.key, required this.title});\r\n  final String title;\r\n\r\n  @override\r\n  State&lt;MyHomePage&gt; createState() =&gt; _MyHomePageState();\r\n}\r\n\r\nclass _MyHomePageState extends State&lt;MyHomePage&gt; {\r\n  late TextEditingController _groupCallIdController;\r\n  late TextEditingController _userIdController;\r\n  late TextEditingController _userNameController;\r\n\r\n  @override\r\n  void initState() {\r\n    super.initState();\r\n    _groupCallIdController = TextEditingController();\r\n    _userIdController = TextEditingController();\r\n    _userNameController = TextEditingController();\r\n  }\r\n\r\n  @override\r\n  void dispose() {\r\n    _groupCallIdController.dispose();\r\n    _userIdController.dispose();\r\n    _userNameController.dispose();\r\n    super.dispose();\r\n  }\r\n\r\n  @override\r\n  Widget build(BuildContext context) {\r\n    return Scaffold(\r\n      appBar: AppBar(\r\n        title: Text(widget.title),\r\n      ),\r\n      body: Padding(\r\n        padding: const EdgeInsets.all(8.0),\r\n        child: Center(\r\n          child: Column(\r\n            mainAxisAlignment: MainAxisAlignment.center,\r\n            children: &lt;Widget&gt;[\r\n              const SizedBox(height: 10),\r\n              TextButton(onPressed: _getToken, child: const Text('Get token')),\r\n              const SizedBox(height: 10),\r\n              TextField(\r\n                controller: _userIdController,\r\n                decoration: const InputDecoration(labelText: 'User ID'),\r\n                readOnly: true,\r\n              ),\r\n              const SizedBox(height: 10),\r\n              TextField(\r\n                controller: _userNameController,\r\n                decoration: const InputDecoration(labelText: 'User name'),\r\n              ),\r\n              Row(\r\n                children: [\r\n                  Expanded(\r\n                    child: TextField(\r\n                      controller: _groupCallIdController,\r\n                      decoration: const InputDecoration(labelText: 'Group call ID'),\r\n                    ),\r\n                  ),\r\n                  const SizedBox(width: 5),\r\n                  IconButton(\r\n                    icon: const Icon(Icons.refresh_rounded),\r\n                    onPressed: () {\r\n                      var uuid = const Uuid();\r\n                      setState(() {\r\n                        _groupCallIdController.text = uuid.v1();\r\n                      });\r\n                    },\r\n                  ),\r\n                ],\r\n              ),\r\n              const SizedBox(height: 10),\r\n              TextButton(onPressed: _joinGroup, child: const Text('Join group call')),\r\n            ],\r\n          ),\r\n        ),\r\n      ),\r\n    );\r\n  }\r\n}<\/code><\/pre>\n<p><!-- \/wp:code --><\/p>\n<p><!-- wp:paragraph --><\/p>\n<p>La parte importante est\u00e1 en los m\u00e9todos utilizados para la obtenci\u00f3n del <em>token<\/em> realizando una llamada a la funci\u00f3n de Azure creada anteriormente:<\/p>\n<p><!-- \/wp:paragraph --><\/p>\n<p><!-- wp:code --><\/p>\n<pre class=\"wp-block-code\"><code>  late String _userToken;\r\n\r\n  void _getToken() async {\r\n    var response = await http.get(Uri.parse('{YOUR AZURE FUNCTION ENDPOINT}'));\r\n    if (response.statusCode != 200) {\r\n      return;\r\n    }\r\n\r\n    var jsonResponse = convert.jsonDecode(response.body) as Map&lt;String, dynamic&gt;;\r\n    var token = jsonResponse['token'];\r\n\r\n    _userToken = token;\r\n    Map&lt;String, dynamic&gt; decodedToken = JwtDecoder.decode(token);\r\n    _userIdController.text = decodedToken[\"skypeid\"];\r\n  }<\/code><\/pre>\n<p><!-- \/wp:code --><\/p>\n<p><!-- wp:paragraph --><\/p>\n<p>Y en el m\u00e9todo para unirnos a una llamada. Dado que el SDK que utilizamos es nativo, tenemos que<strong> utilizar un channel para ejecutar el m\u00e9todo de la parte nativa<\/strong>, pas\u00e1ndole todos los par\u00e1metros que necesita. Estos son el <em>token, el identificador del grupo y el nombre de usuario.<\/em><\/p>\n<p><!-- \/wp:paragraph --><\/p>\n<p><!-- wp:code --><\/p>\n<pre class=\"wp-block-code\"><code>static const platform = MethodChannel('com.example.flutter_azure_calling_ui\/calling');\r\n\r\nvoid _joinGroup() async {\r\n    final bool result = await platform.invokeMethod('startCall', {\"groupCallId\": _groupCallIdController.text, \"displayName\": _userNameController.text, \"userToken\": _userToken});\r\n    if (kDebugMode) {\r\n      print(\"The call result is $result\");\r\n    }\r\n  }<\/code><\/pre>\n<p><!-- \/wp:code --><\/p>\n<p><!-- wp:paragraph --><\/p>\n<p>Cabe destacar que, si estamos creando la reuni\u00f3n, podemos utilizar el bot\u00f3n a la derecha de <em>Group call ID <\/em>para generar un identificador de grupo nuevo. Sin embargo, si queremos conectarnos a una reuni\u00f3n ya creada, escribiremos el ID del grupo. Obviamente, en una aplicaci\u00f3n real esta gesti\u00f3n debe quedar encapsulada en el backend y ser totalmente transparente para la app cliente.<\/p>\n<p><!-- \/wp:paragraph --><\/p>\n<p><!-- wp:heading {\"level\":3} --><\/p>\n<h3 class=\"wp-block-heading\">Desarrollando parte nativa en Android<\/h3>\n<p><!-- \/wp:heading --><\/p>\n<p><!-- wp:paragraph --><\/p>\n<p>Tal y como hemos dicho, tenemos que irnos a la <strong>parte nativa para interactuar con el SDK de Communication Service<\/strong>. Por lo que, para conseguir que nuestra app funcione en <em>Android<\/em>, abriremos el proyecto de <em>Android<\/em> en <em>Android Studio<\/em> y seguiremos los siguientes pasos:<\/p>\n<p><!-- \/wp:paragraph --><\/p>\n<p><!-- wp:list --><\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul><!-- wp:list-item --><\/p>\n<li>Asegurarnos de que <strong>mavenCentral<\/strong> se utiliza como repositorio en <em>buildscript<\/em> y <em>allporjects <\/em>de nuestro .<em>gradle<\/em> a nivel de proyecto.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><!-- \/wp:list-item --><!-- \/wp:list --><\/p>\n<p><!-- wp:code --><\/p>\n<pre class=\"wp-block-code\"><code>buildscript { \r\n    repositories { \r\n        ... \r\n        mavenCentral() \r\n        ...\r\n    }\r\n} \r\n... \r\nallprojects { \r\n    repositories { \r\n        ... \r\n        mavenCentral() \r\n        ...\r\n    }\r\n}<\/code><\/pre>\n<p><!-- \/wp:code --><\/p>\n<p><!-- wp:list --><\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul><!-- wp:list-item --><\/p>\n<li>En el .<em>gradle<\/em>, a nivel de m\u00f3dulo, a\u00f1adir la siguiente dependencia y opciones de compilaci\u00f3n.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><!-- \/wp:list-item --><!-- \/wp:list --><\/p>\n<p><!-- wp:code --><\/p>\n<pre class=\"wp-block-code\"><code>android {\r\n    ...\r\n    compileOptions {\r\n        sourceCompatibility JavaVersion.VERSION_1_8\r\n        targetCompatibility JavaVersion.VERSION_1_8\r\n    }\r\n    ..\r\n}\r\n...\r\ndependencies {\r\n    ...\r\n    implementation 'com.azure.android:azure-communication-ui-calling:+'\r\n    ...\r\n}<\/code><\/pre>\n<p><!-- \/wp:code --><\/p>\n<p><!-- wp:list --><\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul><!-- wp:list-item --><\/p>\n<li>A\u00f1adir los permisos necesarios en el <em>AndroidManifest.xml.<\/em><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><!-- \/wp:list-item --><!-- \/wp:list --><\/p>\n<p><!-- wp:code --><\/p>\n<pre class=\"wp-block-code\"><code>&lt;manifest ...&gt;\r\n    &lt;uses-permission android:name=\"android.permission.INTERNET\" \/&gt;\r\n    &lt;uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\" \/&gt;\r\n    &lt;uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\" \/&gt;\r\n    &lt;uses-permission android:name=\"android.permission.RECORD_AUDIO\" \/&gt;\r\n    &lt;uses-permission android:name=\"android.permission.CAMERA\" \/&gt;\r\n    &lt;uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\" \/&gt;\r\n    &lt;uses-permission android:name=\"android.permission.READ_PHONE_STATE\" \/&gt;\r\n&lt;\/manifest&gt;<\/code><\/pre>\n<p><!-- \/wp:code --><\/p>\n<p><!-- wp:list --><\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul><!-- wp:list-item --><\/p>\n<li>A\u00f1adir un replace en el <em>label<\/em> de application, para evitar problemas al ejecutar la aplicaci\u00f3n.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><!-- \/wp:list-item --><!-- \/wp:list --><\/p>\n<p><!-- wp:code --><\/p>\n<pre class=\"wp-block-code\"><code>&lt;manifest \r\n    ...\r\n    xmlns:tools=\"http:\/\/schemas.android.com\/tools\"&gt;\r\n   &lt;application\r\n        ...\r\n        tools:replace=\"android:label\"&gt;\r\n        ...\r\n    &lt;\/application&gt;\r\n&lt;\/manifest&gt;<\/code><\/pre>\n<p><!-- \/wp:code --><\/p>\n<p><!-- wp:list --><\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul><!-- wp:list-item --><\/p>\n<li>Crear canal de comunicaci\u00f3n con <em>flutter<\/em>. Este canal tiene que tener el mismo nombre que el utilizado en <em>Dart <\/em>para que la comunicaci\u00f3n se materialice correctamente. Adem\u00e1s, se a\u00f1ade el m\u00e9todo al que se va a llamar para inicia la llamada.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><!-- \/wp:list-item --><!-- \/wp:list --><\/p>\n<p><!-- wp:code --><\/p>\n<pre class=\"wp-block-code\"><code>class MainActivity: FlutterActivity() {\r\n    private val CHANNEL = \"com.example.flutter_azure_calling_ui\/calling\"\r\n    private lateinit var methodChannel: MethodChannel\r\n\r\n    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {\r\n        super.configureFlutterEngine(flutterEngine)\r\n        methodChannel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL)\r\n        methodChannel.setMethodCallHandler { call: MethodCall, result: MethodChannel.Result -&gt;\r\n            if (call.method.equals(\"startCall\")) {\r\n                val groupCallId = call.argument&lt;String&gt;(\"groupCallId\")\r\n                val displayName = call.argument&lt;String&gt;(\"displayName\")\r\n                val userToken = call.argument&lt;String&gt;(\"userToken\")\r\n                startCallComposite(groupCallId!!, displayName!!, userToken!!)\r\n                result.success(true)\r\n            } else {\r\n                result.notImplemented()\r\n            }\r\n        }\r\n    }\r\n\r\n    private fun startCallComposite(groupCallId: String, displayName: String, userToken: String) {\r\n        val communicationTokenCredential =\r\n            CommunicationTokenCredential(userToken)\r\n        val locator: CallCompositeJoinLocator =\r\n            CallCompositeGroupCallLocator(UUID.fromString(groupCallId))\r\n        val remoteOptions =\r\n            CallCompositeRemoteOptions(locator, communicationTokenCredential, displayName)\r\n        val callComposite = CallCompositeBuilder().build()\r\n\r\n        callComposite.addOnErrorEventHandler { event: CallCompositeErrorEvent -&gt;\r\n            \/\/ Process error event\r\n            println(event.cause)\r\n            println(event.errorCode)\r\n        }\r\n        callComposite.launch(this, remoteOptions)\r\n    }\r\n}<\/code><\/pre>\n<p><!-- \/wp:code --><\/p>\n<p><!-- wp:paragraph --><\/p>\n<p>Con todo lo anterior, nuestra aplicaci\u00f3n estar\u00eda lista para ejecutarse y poder hacer video llamadas en varios dispositivos <em>Android<\/em>.<\/p>\n<p><!-- \/wp:paragraph --><\/p>\n<p><!-- wp:heading {\"level\":3} --><\/p>\n<h3 class=\"wp-block-heading\">Desarrollando parte nativa en iOS<\/h3>\n<p><!-- \/wp:heading --><\/p>\n<p><!-- wp:paragraph --><\/p>\n<p>Como te podr\u00e1s imaginas, la implementaci\u00f3n en iOS es totalmente an\u00e1loga a la de Android. Al igual que en \u00e9sta, tenemos que a\u00f1adir el SDK de <em>Communication Service<\/em> (lo haremos v\u00eda <em>pod<\/em>) e implementar el canal para poder llamar desde <em>flutter<\/em> a las funcionalidades que nos ofrece el SDK.<\/p>\n<p><!-- \/wp:paragraph --><\/p>\n<p><!-- wp:paragraph --><\/p>\n<p>A continuaci\u00f3n, se detallan todos los puntos a seguir para completar la implementaci\u00f3n:<\/p>\n<p><!-- \/wp:paragraph --><\/p>\n<p><!-- wp:list --><\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul><!-- wp:list-item --><\/p>\n<li>El primer paso es hacer un <em>pod init <\/em>desde el terminal, ya que la instalaci\u00f3n del SDK se hace v\u00eda pod.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><!-- \/wp:list-item --><\/p>\n<p><!-- wp:list-item --><\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li>Una vez iniciados los pod, abrimos el archivo <em>Podfile<\/em> y lo modificamos para dejarlo de la siguiente manera.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><!-- \/wp:list-item --><!-- \/wp:list --><\/p>\n<p><!-- wp:code --><\/p>\n<pre class=\"wp-block-code\"><code>platform :ios, '14.0'\r\n\r\ntarget 'Runner' do\r\n  use_frameworks!\r\n\r\n  pod 'AzureCommunicationUICalling', '1.3.0'\r\nend\r\n\r\npost_install do |installer|\r\n  installer.pods_project.targets.each do |target|\r\n    target.build_configurations.each do |config|\r\n      if config.build_settings['WRAPPER_EXTENSION'] == 'bundle'\r\n        config.build_settings['DEVELOPMENT_TEAM'] = 'com.example.flutterAzureCallingUi'\r\n      end\r\n    end\r\n  end\r\nend<\/code><\/pre>\n<p><!-- \/wp:code --><\/p>\n<p><!-- wp:paragraph --><\/p>\n<p>Dependiendo del momento en el que est\u00e9s leyendo este post, es posible que tengas que modificar el target o la versi\u00f3n del SDK. Asimismo, ten en cuenta que en lugar de usar <em>com.example.flutterAzureCallingUI<\/em>, debes usar el nombre de paquete de tu app.<\/p>\n<p><!-- \/wp:paragraph --><\/p>\n<p><!-- wp:list --><\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul><!-- wp:list-item --><\/p>\n<li>Ejecutar la instrucci\u00f3n <em>pod install. <\/em>\u00c9sta generar\u00e1 un<em> .xcworkspace, <\/em>que ser\u00e1 el proyecto que tenemos que abrir en<em> XCode.<\/em><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><!-- \/wp:list-item --><\/p>\n<p><!-- wp:list-item --><\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li>A\u00f1adir las siguientes l\u00edneas en el <em>info.plist<\/em> que existe en la ruta <em>ios\/Runner<\/em><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><!-- \/wp:list-item --><!-- \/wp:list --><\/p>\n<p><!-- wp:code --><\/p>\n<pre class=\"wp-block-code\"><code>&lt;key&gt;NSCameraUsageDescription&lt;\/key&gt;\r\n&lt;string&gt;Need camera access for video calling&lt;\/string&gt;\r\n&lt;key&gt;NSMicrophoneUsageDescription&lt;\/key&gt;\r\n&lt;string&gt;Need microphone access for video calling&lt;\/string&gt;<\/code><\/pre>\n<p><!-- \/wp:code --><\/p>\n<p><!-- wp:list --><\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul><!-- wp:list-item --><\/p>\n<li>Crear canal de comunicaci\u00f3n con <em>flutter<\/em>. Al igual que para Android, este canal tiene que tener el mismo nombre que el utilizado en <em>Dart <\/em>para que la comunicaci\u00f3n se materialice correctamente. Adem\u00e1s, se a\u00f1ade el m\u00e9todo al que se va a llamar para inicia la llamada.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><!-- \/wp:list-item --><!-- \/wp:list --><\/p>\n<p><!-- wp:code --><\/p>\n<pre class=\"wp-block-code\"><code>@UIApplicationMain\r\n@objc class AppDelegate: FlutterAppDelegate {\r\n    \r\n    private var callComposite: CallComposite?\r\n    \r\n    override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -&gt; Bool {\r\n        let controller : FlutterViewController = window?.rootViewController as! FlutterViewController\r\n        let methodChannel = FlutterMethodChannel(name: \"com.example.flutter_azure_calling_ui\/calling\",\r\n                                                  binaryMessenger: controller.binaryMessenger)\r\n        methodChannel.setMethodCallHandler({\r\n          (call: FlutterMethodCall, result: @escaping FlutterResult) -&gt; Void in\r\n            switch call.method {\r\n            case \"startCall\":\r\n                guard let args = call.arguments as? [String: String] else {return}\r\n                let groupCallId = args[\"groupCallId\"]!\r\n                let displayName = args[\"displayName\"]!\r\n                let token = args[\"userToken\"]!\r\n                self.startCallComposite(groupCallId: groupCallId, displayName: displayName, userToken: token)\r\n                result(true)\r\n            default:\r\n                result(FlutterMethodNotImplemented)\r\n            }\r\n        })\r\n    \r\n        GeneratedPluginRegistrant.register(with: self)\r\n        return super.application(application, didFinishLaunchingWithOptions: launchOptions)\r\n    }\r\n    \r\n    private func startCallComposite(groupCallId: String, displayName: String, userToken: String) {\r\n        let callCompositeOptions = CallCompositeOptions();\r\n        callComposite = CallComposite(withOptions: callCompositeOptions);\r\n        let communicationTokenCredential = try! CommunicationTokenCredential(token: userToken);\r\n        let remoteOptions = RemoteOptions(for: .groupCall(groupId: UUID(uuidString: groupCallId)!),\r\n        credential: communicationTokenCredential,\r\n        displayName: displayName)\r\n\r\n        callComposite?.launch(remoteOptions: remoteOptions)\r\n    }\r\n}<\/code><\/pre>\n<p><!-- \/wp:code --><\/p>\n<p><!-- wp:paragraph --><\/p>\n<p>Con todo lo anterior, ahora podemos ejecutar la app tambi\u00e9n en iOS y hacer v\u00eddeo llamadas a trav\u00e9s del m\u00f3vil, independientemente de la plataforma.<\/p>\n<p><!-- \/wp:paragraph --><\/p>\n<p><!-- wp:paragraph --><\/p>\n<p>Aqu\u00ed dejo el enlace al repo, para que pod\u00e1is revisar todo el c\u00f3digo de este ejemplo: <a href=\"https:\/\/github.com\/Encamina\/Blogs\/tree\/master\/Por%20una%20nube%20sostenible\/CommunicationService\">https:\/\/github.com\/Encamina\/Blogs\/tree\/master\/Por%20una%20nube%20sostenible\/CommunicationService<\/a><\/p>\n<!-- AddThis Advanced Settings generic via filter on the_content --><!-- AddThis Share Buttons generic via filter on the_content --><span class=\"et_bloom_bottom_trigger\"><\/span>","protected":false},"excerpt":{"rendered":"<p>En este post vamos a ver c\u00f3mo comenzar a integrar Azure Communication Service en nuestras aplicaciones. Crearemos el servicio en Azure y lo utilizaremos desde una aplicaci\u00f3n Android\/iOS creada con flutter. \u00a1\u00a1\u00a1Comenzamos!!!<!-- AddThis Advanced Settings generic via filter on get_the_excerpt --><!-- AddThis Share Buttons generic via filter on get_the_excerpt --><\/p>\n","protected":false},"author":212,"featured_media":2253,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[144],"tags":[],"class_list":["post-2250","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-azure"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v18.2.1 (Yoast SEO v27.3) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Primeros pasos con Azure Communication Service en Flutter para hacer videollamadas | ENCAMINA<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blogs.encamina.com\/piensa-en-software-desarrolla-en-colores\/primeros-pasos-con-azure-communication-service-en-flutter-para-hacer-video-llamadas\/\" \/>\n<meta property=\"og:locale\" content=\"es_ES\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Primeros pasos con Azure Communication Service en Flutter para hacer videollamadas\" \/>\n<meta property=\"og:description\" content=\"En este post vamos a ver c\u00f3mo comenzar a integrar Azure Communication Service en nuestras aplicaciones. Crearemos el servicio en Azure y lo utilizaremos desde una aplicaci\u00f3n Android\/iOS creada con flutter. \u00a1\u00a1\u00a1Comenzamos!!!\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blogs.encamina.com\/piensa-en-software-desarrolla-en-colores\/primeros-pasos-con-azure-communication-service-en-flutter-para-hacer-video-llamadas\/\" \/>\n<meta property=\"og:site_name\" content=\"Piensa en software, desarrolla en colores\" \/>\n<meta property=\"article:published_time\" content=\"2023-09-18T08:10:47+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-09-18T08:57:10+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/blogs.encamina.com\/piensa-en-software-desarrolla-en-colores\/wp-content\/uploads\/sites\/21\/2023\/09\/videollamadas-y-Flutter.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"647\" \/>\n\t<meta property=\"og:image:height\" content=\"455\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Jorge Diego\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Escrito por\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jorge Diego\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tiempo de lectura\" \/>\n\t<meta name=\"twitter:data2\" content=\"11 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/blogs.encamina.com\\\/piensa-en-software-desarrolla-en-colores\\\/primeros-pasos-con-azure-communication-service-en-flutter-para-hacer-video-llamadas\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/blogs.encamina.com\\\/piensa-en-software-desarrolla-en-colores\\\/primeros-pasos-con-azure-communication-service-en-flutter-para-hacer-video-llamadas\\\/\"},\"author\":{\"name\":\"Jorge Diego\",\"@id\":\"https:\\\/\\\/blogs.encamina.com\\\/piensa-en-software-desarrolla-en-colores\\\/#\\\/schema\\\/person\\\/db467d392da36cf2deba504fbb9eeb3e\"},\"headline\":\"Primeros pasos con Azure Communication Service en Flutter para hacer videollamadas\",\"datePublished\":\"2023-09-18T08:10:47+00:00\",\"dateModified\":\"2023-09-18T08:57:10+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/blogs.encamina.com\\\/piensa-en-software-desarrolla-en-colores\\\/primeros-pasos-con-azure-communication-service-en-flutter-para-hacer-video-llamadas\\\/\"},\"wordCount\":1314,\"commentCount\":1,\"image\":{\"@id\":\"https:\\\/\\\/blogs.encamina.com\\\/piensa-en-software-desarrolla-en-colores\\\/primeros-pasos-con-azure-communication-service-en-flutter-para-hacer-video-llamadas\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/blogs.encamina.com\\\/piensa-en-software-desarrolla-en-colores\\\/wp-content\\\/uploads\\\/sites\\\/21\\\/2023\\\/09\\\/videollamadas-y-Flutter.jpg\",\"articleSection\":[\"AZure\"],\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/blogs.encamina.com\\\/piensa-en-software-desarrolla-en-colores\\\/primeros-pasos-con-azure-communication-service-en-flutter-para-hacer-video-llamadas\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/blogs.encamina.com\\\/piensa-en-software-desarrolla-en-colores\\\/primeros-pasos-con-azure-communication-service-en-flutter-para-hacer-video-llamadas\\\/\",\"url\":\"https:\\\/\\\/blogs.encamina.com\\\/piensa-en-software-desarrolla-en-colores\\\/primeros-pasos-con-azure-communication-service-en-flutter-para-hacer-video-llamadas\\\/\",\"name\":\"Primeros pasos con Azure Communication Service en Flutter para hacer videollamadas | ENCAMINA\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/blogs.encamina.com\\\/piensa-en-software-desarrolla-en-colores\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/blogs.encamina.com\\\/piensa-en-software-desarrolla-en-colores\\\/primeros-pasos-con-azure-communication-service-en-flutter-para-hacer-video-llamadas\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/blogs.encamina.com\\\/piensa-en-software-desarrolla-en-colores\\\/primeros-pasos-con-azure-communication-service-en-flutter-para-hacer-video-llamadas\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/blogs.encamina.com\\\/piensa-en-software-desarrolla-en-colores\\\/wp-content\\\/uploads\\\/sites\\\/21\\\/2023\\\/09\\\/videollamadas-y-Flutter.jpg\",\"datePublished\":\"2023-09-18T08:10:47+00:00\",\"dateModified\":\"2023-09-18T08:57:10+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/blogs.encamina.com\\\/piensa-en-software-desarrolla-en-colores\\\/#\\\/schema\\\/person\\\/db467d392da36cf2deba504fbb9eeb3e\"},\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/blogs.encamina.com\\\/piensa-en-software-desarrolla-en-colores\\\/primeros-pasos-con-azure-communication-service-en-flutter-para-hacer-video-llamadas\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\\\/\\\/blogs.encamina.com\\\/piensa-en-software-desarrolla-en-colores\\\/primeros-pasos-con-azure-communication-service-en-flutter-para-hacer-video-llamadas\\\/#primaryimage\",\"url\":\"https:\\\/\\\/blogs.encamina.com\\\/piensa-en-software-desarrolla-en-colores\\\/wp-content\\\/uploads\\\/sites\\\/21\\\/2023\\\/09\\\/videollamadas-y-Flutter.jpg\",\"contentUrl\":\"https:\\\/\\\/blogs.encamina.com\\\/piensa-en-software-desarrolla-en-colores\\\/wp-content\\\/uploads\\\/sites\\\/21\\\/2023\\\/09\\\/videollamadas-y-Flutter.jpg\",\"width\":647,\"height\":455},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/blogs.encamina.com\\\/piensa-en-software-desarrolla-en-colores\\\/#website\",\"url\":\"https:\\\/\\\/blogs.encamina.com\\\/piensa-en-software-desarrolla-en-colores\\\/\",\"name\":\"Piensa en software, desarrolla en colores\",\"description\":\"Las ventajas que te ofrece Microsoft Azure y el mundo.NET\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/blogs.encamina.com\\\/piensa-en-software-desarrolla-en-colores\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"es\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/blogs.encamina.com\\\/piensa-en-software-desarrolla-en-colores\\\/#\\\/schema\\\/person\\\/db467d392da36cf2deba504fbb9eeb3e\",\"name\":\"Jorge Diego\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/4dc904b19ec9f1309fdccfd8a3c7520f3f89fe1efba301130bbc6ca84e3f6d85?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/4dc904b19ec9f1309fdccfd8a3c7520f3f89fe1efba301130bbc6ca84e3f6d85?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/4dc904b19ec9f1309fdccfd8a3c7520f3f89fe1efba301130bbc6ca84e3f6d85?s=96&d=mm&r=g\",\"caption\":\"Jorge Diego\"},\"description\":\"Soy un apasionado del desarrollo de software. Me encanta mi trabajo y mantenerme al d\u00eda haciendo cursos, investigando, realizando proyectos personales, etc. Principalmente trabajo con tecnolog\u00eda .NET. Asimismo, me interesa much\u00edsimo el mundo de la productividad personal. Adem\u00e1s del desarrollo tengo otras muchas aficiones: viajar, deporte, gastronom\u00eda, fotograf\u00eda\u2026y sobre todo, pasar tiempo con mi familia.\",\"url\":\"https:\\\/\\\/blogs.encamina.com\\\/piensa-en-software-desarrolla-en-colores\\\/author\\\/jdiego\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Primeros pasos con Azure Communication Service en Flutter para hacer videollamadas | ENCAMINA","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blogs.encamina.com\/piensa-en-software-desarrolla-en-colores\/primeros-pasos-con-azure-communication-service-en-flutter-para-hacer-video-llamadas\/","og_locale":"es_ES","og_type":"article","og_title":"Primeros pasos con Azure Communication Service en Flutter para hacer videollamadas","og_description":"En este post vamos a ver c\u00f3mo comenzar a integrar Azure Communication Service en nuestras aplicaciones. Crearemos el servicio en Azure y lo utilizaremos desde una aplicaci\u00f3n Android\/iOS creada con flutter. \u00a1\u00a1\u00a1Comenzamos!!!","og_url":"https:\/\/blogs.encamina.com\/piensa-en-software-desarrolla-en-colores\/primeros-pasos-con-azure-communication-service-en-flutter-para-hacer-video-llamadas\/","og_site_name":"Piensa en software, desarrolla en colores","article_published_time":"2023-09-18T08:10:47+00:00","article_modified_time":"2023-09-18T08:57:10+00:00","og_image":[{"width":647,"height":455,"url":"http:\/\/blogs.encamina.com\/piensa-en-software-desarrolla-en-colores\/wp-content\/uploads\/sites\/21\/2023\/09\/videollamadas-y-Flutter.jpg","type":"image\/jpeg"}],"author":"Jorge Diego","twitter_card":"summary_large_image","twitter_misc":{"Escrito por":"Jorge Diego","Tiempo de lectura":"11 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/blogs.encamina.com\/piensa-en-software-desarrolla-en-colores\/primeros-pasos-con-azure-communication-service-en-flutter-para-hacer-video-llamadas\/#article","isPartOf":{"@id":"https:\/\/blogs.encamina.com\/piensa-en-software-desarrolla-en-colores\/primeros-pasos-con-azure-communication-service-en-flutter-para-hacer-video-llamadas\/"},"author":{"name":"Jorge Diego","@id":"https:\/\/blogs.encamina.com\/piensa-en-software-desarrolla-en-colores\/#\/schema\/person\/db467d392da36cf2deba504fbb9eeb3e"},"headline":"Primeros pasos con Azure Communication Service en Flutter para hacer videollamadas","datePublished":"2023-09-18T08:10:47+00:00","dateModified":"2023-09-18T08:57:10+00:00","mainEntityOfPage":{"@id":"https:\/\/blogs.encamina.com\/piensa-en-software-desarrolla-en-colores\/primeros-pasos-con-azure-communication-service-en-flutter-para-hacer-video-llamadas\/"},"wordCount":1314,"commentCount":1,"image":{"@id":"https:\/\/blogs.encamina.com\/piensa-en-software-desarrolla-en-colores\/primeros-pasos-con-azure-communication-service-en-flutter-para-hacer-video-llamadas\/#primaryimage"},"thumbnailUrl":"https:\/\/blogs.encamina.com\/piensa-en-software-desarrolla-en-colores\/wp-content\/uploads\/sites\/21\/2023\/09\/videollamadas-y-Flutter.jpg","articleSection":["AZure"],"inLanguage":"es","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/blogs.encamina.com\/piensa-en-software-desarrolla-en-colores\/primeros-pasos-con-azure-communication-service-en-flutter-para-hacer-video-llamadas\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/blogs.encamina.com\/piensa-en-software-desarrolla-en-colores\/primeros-pasos-con-azure-communication-service-en-flutter-para-hacer-video-llamadas\/","url":"https:\/\/blogs.encamina.com\/piensa-en-software-desarrolla-en-colores\/primeros-pasos-con-azure-communication-service-en-flutter-para-hacer-video-llamadas\/","name":"Primeros pasos con Azure Communication Service en Flutter para hacer videollamadas | ENCAMINA","isPartOf":{"@id":"https:\/\/blogs.encamina.com\/piensa-en-software-desarrolla-en-colores\/#website"},"primaryImageOfPage":{"@id":"https:\/\/blogs.encamina.com\/piensa-en-software-desarrolla-en-colores\/primeros-pasos-con-azure-communication-service-en-flutter-para-hacer-video-llamadas\/#primaryimage"},"image":{"@id":"https:\/\/blogs.encamina.com\/piensa-en-software-desarrolla-en-colores\/primeros-pasos-con-azure-communication-service-en-flutter-para-hacer-video-llamadas\/#primaryimage"},"thumbnailUrl":"https:\/\/blogs.encamina.com\/piensa-en-software-desarrolla-en-colores\/wp-content\/uploads\/sites\/21\/2023\/09\/videollamadas-y-Flutter.jpg","datePublished":"2023-09-18T08:10:47+00:00","dateModified":"2023-09-18T08:57:10+00:00","author":{"@id":"https:\/\/blogs.encamina.com\/piensa-en-software-desarrolla-en-colores\/#\/schema\/person\/db467d392da36cf2deba504fbb9eeb3e"},"inLanguage":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blogs.encamina.com\/piensa-en-software-desarrolla-en-colores\/primeros-pasos-con-azure-communication-service-en-flutter-para-hacer-video-llamadas\/"]}]},{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/blogs.encamina.com\/piensa-en-software-desarrolla-en-colores\/primeros-pasos-con-azure-communication-service-en-flutter-para-hacer-video-llamadas\/#primaryimage","url":"https:\/\/blogs.encamina.com\/piensa-en-software-desarrolla-en-colores\/wp-content\/uploads\/sites\/21\/2023\/09\/videollamadas-y-Flutter.jpg","contentUrl":"https:\/\/blogs.encamina.com\/piensa-en-software-desarrolla-en-colores\/wp-content\/uploads\/sites\/21\/2023\/09\/videollamadas-y-Flutter.jpg","width":647,"height":455},{"@type":"WebSite","@id":"https:\/\/blogs.encamina.com\/piensa-en-software-desarrolla-en-colores\/#website","url":"https:\/\/blogs.encamina.com\/piensa-en-software-desarrolla-en-colores\/","name":"Piensa en software, desarrolla en colores","description":"Las ventajas que te ofrece Microsoft Azure y el mundo.NET","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blogs.encamina.com\/piensa-en-software-desarrolla-en-colores\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"es"},{"@type":"Person","@id":"https:\/\/blogs.encamina.com\/piensa-en-software-desarrolla-en-colores\/#\/schema\/person\/db467d392da36cf2deba504fbb9eeb3e","name":"Jorge Diego","image":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/secure.gravatar.com\/avatar\/4dc904b19ec9f1309fdccfd8a3c7520f3f89fe1efba301130bbc6ca84e3f6d85?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/4dc904b19ec9f1309fdccfd8a3c7520f3f89fe1efba301130bbc6ca84e3f6d85?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/4dc904b19ec9f1309fdccfd8a3c7520f3f89fe1efba301130bbc6ca84e3f6d85?s=96&d=mm&r=g","caption":"Jorge Diego"},"description":"Soy un apasionado del desarrollo de software. Me encanta mi trabajo y mantenerme al d\u00eda haciendo cursos, investigando, realizando proyectos personales, etc. Principalmente trabajo con tecnolog\u00eda .NET. Asimismo, me interesa much\u00edsimo el mundo de la productividad personal. Adem\u00e1s del desarrollo tengo otras muchas aficiones: viajar, deporte, gastronom\u00eda, fotograf\u00eda\u2026y sobre todo, pasar tiempo con mi familia.","url":"https:\/\/blogs.encamina.com\/piensa-en-software-desarrolla-en-colores\/author\/jdiego\/"}]}},"_links":{"self":[{"href":"https:\/\/blogs.encamina.com\/piensa-en-software-desarrolla-en-colores\/wp-json\/wp\/v2\/posts\/2250","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.encamina.com\/piensa-en-software-desarrolla-en-colores\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.encamina.com\/piensa-en-software-desarrolla-en-colores\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.encamina.com\/piensa-en-software-desarrolla-en-colores\/wp-json\/wp\/v2\/users\/212"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.encamina.com\/piensa-en-software-desarrolla-en-colores\/wp-json\/wp\/v2\/comments?post=2250"}],"version-history":[{"count":0,"href":"https:\/\/blogs.encamina.com\/piensa-en-software-desarrolla-en-colores\/wp-json\/wp\/v2\/posts\/2250\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blogs.encamina.com\/piensa-en-software-desarrolla-en-colores\/wp-json\/wp\/v2\/media\/2253"}],"wp:attachment":[{"href":"https:\/\/blogs.encamina.com\/piensa-en-software-desarrolla-en-colores\/wp-json\/wp\/v2\/media?parent=2250"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.encamina.com\/piensa-en-software-desarrolla-en-colores\/wp-json\/wp\/v2\/categories?post=2250"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.encamina.com\/piensa-en-software-desarrolla-en-colores\/wp-json\/wp\/v2\/tags?post=2250"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}