

# Introducción al SDK de transmisión para iOS de IVS \$1 Transmisión de baja latencia
<a name="broadcast-ios-getting-started"></a>

En este documento, se explican los pasos para comenzar a usar el SDK de transmisión para iOS para la transmisión de baja latencia de Amazon IVS.

## Instalación de la biblioteca
<a name="broadcast-ios-install"></a>

Recomendamos que integre el SDK de transmisión a través de Swift Package Manager. (También puede agregar el marco a su proyecto de forma manual).

### Recomendación: integre el SDK de transmisión (Swift Package Manager)
<a name="broadcast-ios-install-swift"></a>

1. Descargue el archivo Package.swift desde [https://broadcast.live-video.net/1.40.0/Package.swift](https://broadcast.live-video.net/1.40.0/Package.swift).

1. En su proyecto, cree un nuevo directorio denominado AmazonIVSBroadcast y agréguelo al control de versiones.

1. Coloque el archivo Package.swift descargado en el nuevo directorio.

1. En Xcode, vaya a **Archivo > Agregar dependencias de paquete** y seleccione **Agregar local…**.

1. Navegue hasta el directorio AmazonIVSBroadcast que ha creado, selecciónelo y elija **Agregar paquete**.

1. Cuando se le pida que **elija productos de paquete para AmazonIVSBroadcast**, seleccione **AmazonIVSBroadcast** como su **producto de paquete** mediante la configuración del destino de la aplicación en la sección **Agregar a destino**.

1. Seleccione **Agregar paquete**.

### Método alternativo: instalar el marco de forma manual
<a name="broadcast-ios-install-manual"></a>

1. Descargue la versión más reciente desde [https://broadcast.live-video.net/1.40.0/AmazonIVSBroadcast.xcframework.zip](https://broadcast.live-video.net/1.40.0/AmazonIVSBroadcast.xcframework.zip).

1. Extraiga el contenido del archivo. `AmazonIVSBroadcast.xcframework` contiene el SDK para el dispositivo y el simulador.

1. Integre el `AmazonIVSBroadcast.xcframework` arrastrándolo a la sección **Frameworks, Libraries, and Embedded Content (Marcos, bibliotecas y contenido integrado)** de la pestaña **General** para el destino de la aplicación.  
![\[La sección Marcos, librerías y contenido integrado de la pestaña General para el destino de la aplicación.\]](http://docs.aws.amazon.com/es_es/ivs/latest/LowLatencyUserGuide/images/iOS_Broadcast_SDK_Guide_xcframework.png)

## Implementar IVSBroadcastSession.Delegate
<a name="broadcast-ios-implement-ivsbroadcastsessiondelegate"></a>

Implemente `IVSBroadcastSession.Delegate`, que le permite recibir actualizaciones de estado y notificaciones de cambio de dispositivo:

```
extension ViewController : IVSBroadcastSession.Delegate {
   func broadcastSession(_ session: IVSBroadcastSession,
                         didChange state: IVSBroadcastSession.State) {
      print("IVSBroadcastSession did change state \(state)")
   }

   func broadcastSession(_ session: IVSBroadcastSession,
                         didEmitError error: Error) {
      print("IVSBroadcastSession did emit error \(error)")
   }
}
```

## Solicitar permisos
<a name="broadcast-ios-permissions"></a>

La aplicación debe solicitar permiso para acceder a la cámara y al micrófono del usuario. (Esto no es específico de Amazon IVS; es necesario para cualquier aplicación que necesite acceso a cámaras y micrófonos).

Aquí, verificamos si el usuario ya ha concedido permisos y, de no ser así, preguntamos por ellos:

```
switch AVCaptureDevice.authorizationStatus(for: .video) {
case .authorized: // permission already granted.
case .notDetermined:
   AVCaptureDevice.requestAccess(for: .video) { granted in
       // permission granted based on granted bool.
   }
case .denied, .restricted: // permission denied.
@unknown default: // permissions unknown.
}
```

Es necesario hacer esto para los tipos de medios `.video` y `.audio`, si desea tener acceso a cámaras y micrófonos, respectivamente.

También es necesario agregar entradas para `NSCameraUsageDescription` y `NSMicrophoneUsageDescription` para su `Info.plist`. De lo contrario, la aplicación se bloqueará al intentar solicitar permisos.

## Desactivar el temporizador inactivo de la aplicación
<a name="broadcast-ios-disable-idle-timer"></a>

Esto es opcional, pero recomendable. Evita que el dispositivo se ponga en suspensión mientras utiliza el SDK de transmisión, lo que interrumpiría la transmisión.

```
override func viewDidAppear(_ animated: Bool) {
   super.viewDidAppear(animated)
   UIApplication.shared.isIdleTimerDisabled = true
}
override func viewDidDisappear(_ animated: Bool) {
   super.viewDidDisappear(animated)
   UIApplication.shared.isIdleTimerDisabled = false
}
```

## (Opcional) Configuración de AVAudioSession
<a name="broadcast-ios-setup-avaudiosession"></a>

De forma predeterminada, el SDK de transmisión configurará la de la aplicación `AVAudioSession`. Si desea administrar esto usted mismo, establezca la opción `IVSBroadcastSession.applicationAudioSessionStrategy` en `noAction`. Sin el control de `AVAudioSession`, el SDK de transmisión no puede administrar micrófonos internamente. Para utilizar micrófonos con la opción `noAction`, puede crear un `IVSCustomAudioSource` y proporcionar sus propias muestras a través de un `AVCaptureSession`, `AVAudioEngine` u otra herramienta que proporcione muestras de audio PCM.

Si está configurando de forma manual su `AVAudioSession`, como mínimo, debe configurar la categoría como `.record` o `.playbackAndRecord` y establecerla en `active`. Si desea grabar audio desde dispositivos Bluetooth, debe especificar la opción `.allowBluetooth` también:

```
do {
   try AVAudioSession.sharedInstance().setCategory(.record, options: .allowBluetooth)
   try AVAudioSession.sharedInstance().setActive(true)
} catch {
   print("Error configuring AVAudioSession")
}
```

Recomendamos que deje que el SDK se encargue de esto por usted. De lo contrario, si desea elegir entre diferentes dispositivos de audio, deberá administrar los puertos de forma manual.

## Creación de la sesión de transmisión
<a name="broadcast-ios-create-session"></a>

La interfaz de transmisión es `IVSBroadcastSession`. Inicialícelo como se muestra a continuación:

```
let broadcastSession = try IVSBroadcastSession(
   configuration: IVSPresets.configurations().standardLandscape(),
   descriptors: IVSPresets.devices().frontCamera(),
   delegate: self)
```

Consulte también [Creación de la sesión de transmisión (versión avanzada)](broadcast-ios-use-cases.md#broadcast-ios-create-session-advanced)

## Configurar IVSImagePreviewView para la previsualización
<a name="broadcast-ios-set-imagepreviewview"></a>

Si desea mostrar una previsualización de un dispositivo de cámara activo, agregue la previsualización `IVSImagePreviewView` para el dispositivo a su jerarquía de vista:

```
// If the session was just created, execute the following 
// code in the callback of IVSBroadcastSession.awaitDeviceChanges 
// to ensure all devices have been attached.
if let devicePreview = try broadcastSession.listAttachedDevices()
   .compactMap({ $0 as? IVSImageDevice })
   .first?
   .previewView()
{
   previewView.addSubview(devicePreview)
}
```

## Inicio de una transmisión
<a name="broadcast-ios-start"></a>

El nombre de host que recibe en el campo de respuesta `ingestEndpoint` de la operación `GetChannel` necesita tener `rtmps://` como prefijo y `/app` como sufijo. La URL completa debe tener este formato: `rtmps://{{ ingestEndpoint }}/app`

```
try broadcastSession.start(with: IVS_RTMPS_URL, streamKey: IVS_STREAMKEY)
```

 El SDK de transmisión de iOS solo admite la ingesta de RTMPS (no la ingesta no segura de RTMP). 

## Detención de una transmisión
<a name="broadcast-ios-stop"></a>

```
broadcastSession.stop()
```

## administrar eventos del ciclo de vida
<a name="broadcast-ios-lifecycle-events"></a>

### Interrupciones de audio
<a name="broadcast-ios-audio-interruptions"></a>

Hay varios escenarios en los que el SDK de transmisión no tendrá acceso exclusivo al hardware de entrada de audio. Estos son algunos ejemplos de situaciones que debe abordar:
+ El usuario recibe una llamada telefónica o una llamada por FaceTime
+ El usuario activa Siri

Apple facilita la respuesta a estos eventos al suscribirse a `AVAudioSession.interruptionNotification`:

```
NotificationCenter.default.addObserver(
   self,
   selector: #selector(audioSessionInterrupted(_:)),
   name: AVAudioSession.interruptionNotification,
   object: nil)
```

Luego puede manejar el evento de forma similar a estas situaciones:

```
// This assumes you have a variable `isRunning` which tracks if the broadcast is currently live, and another variable `wasRunningBeforeInterruption` which tracks whether the broadcast was active before this interruption to determine if it should resume after the interruption has ended.

@objc
private func audioSessionInterrupted(_ notification: Notification) {
   guard let userInfo = notification.userInfo,
         let typeValue = userInfo[AVAudioSessionInterruptionTypeKey] as? UInt,
         let type = AVAudioSession.InterruptionType(rawValue: typeValue)
   else {
      return
   }
   switch type {
   case .began:
      wasRunningBeforeInterruption = isRunning
      if isRunning {
         broadcastSession.stop()
      }
   case .ended:
      defer {
         wasRunningBeforeInterruption = false
      }
      guard let optionsValue = userInfo[AVAudioSessionInterruptionOptionKey] as? UInt else { return }
      let options = AVAudioSession.InterruptionOptions(rawValue: optionsValue)
      if options.contains(.shouldResume) && wasRunningBeforeInterruption {
         try broadcastSession.start(
            with: IVS_RTMPS_URL,
            streamKey: IVS_STREAMKEY)
      }
   @unknown default: break
   }
}
```

### La aplicación entra en segundo plano
<a name="broadcast-ios-app-to-background"></a>

Las aplicaciones estándar en iOS no tienen permitido utilizar cámaras en segundo plano. También hay restricciones en la codificación de video en segundo plano: dado que los codificadores de hardware son limitados, solo las aplicaciones en primer plano tienen acceso. Debido a esto, el SDK de transmisión finaliza automáticamente su sesión y establece su propiedad `isReady` en `false`. Cuando la aplicación está a punto de volver a ingresar en primer plano, el SDK de transmisión vuelve a conectar todos los dispositivos a sus entradas `IVSMixerSlotConfiguration` originales.

El SDK de transmisión hace esto al responder a `UIApplication.didEnterBackgroundNotification` y `UIApplication.willEnterForegroundNotification`.

Si proporciona fuentes de imágenes personalizadas, debe estar preparado para gestionar estas notificaciones. Es posible que deba tomar medidas adicionales para abordarlas antes de que se termine la transmisión.

Consulte [Usar video de fondo](broadcast-ios-use-cases.md#broadcast-ios-background-video) para ver una solución alternativa que permite la transmisión mientras la aplicación está en segundo plano.

### Servicios multimedia perdidos
<a name="broadcast-ios-media-services-lost"></a>

En casos muy excepcionales, todo el subsistema multimedia en un dispositivo de iOS se bloqueará. En este escenario, ya no podemos transmitir. Corresponde a su aplicación responder a estas notificaciones de forma adecuada. Como mínimo, suscríbase a estas notificaciones:
+ [mediaServicesWereLostNotification](https://developer.apple.com/documentation/avfaudio/avaudiosession/1616457-mediaserviceswerelostnotificatio): responda al detener la transmisión y eliminar las asignaciones de la `IVSBroadcastSession` por completo. Todos los componentes internos utilizados por la sesión de transmisión serán invalidados.
+ [mediaServicesWereResetNotification](https://developer.apple.com/documentation/avfaudio/avaudiosession/1616540-mediaserviceswereresetnotificati): responda al notificar a los usuarios que pueden transmitir de nuevo. Según su caso de uso, es posible que pueda volver a iniciar la transmisión de forma automática en este momento.