

# Conceitos básicos do SDK de Transmissão para iOS do IVS \$1 Streaming de baixa latência
<a name="broadcast-ios-getting-started"></a>

Este documento descreve as etapas envolvidas ao começar a usar o SDK de Transmissão para iOS para streaming de baixa latência do Amazon IVS.

## Instalar a biblioteca
<a name="broadcast-ios-install"></a>

Recomendamos integrar o SDK de transmissão usando o Swift Package Manager. (Se preferir, você pode adicionar manualmente a estrutura do framework a seu projeto.)

### Recomendado: integre o SDK de transmissão (Swift Package Manager)
<a name="broadcast-ios-install-swift"></a>

1. Baixe o arquivo Package.swift de [https://broadcast.live-video.net/1.40.0/Package.swift](https://broadcast.live-video.net/1.40.0/Package.swift).

1. Em seu projeto, crie um novo diretório denominado AmazonIVSBroadcast e adicione-o ao controle de versão.

1. Coloque o arquivo Package.swift que foi baixado no novo diretório.

1. No Xcode, vá para **Arquivo > Adicionar dependências de pacote** e selecione **Adicionar local...**.

1. **Navegue e selecione o diretório AmazonIVSBroadcast que você criou e selecione Adicionar pacote**.

1. **Quando receber o prompt **Escolha produtos de pacote para AmazonIVSBroadcast**, selecione **AAmazonIVSBroadcast** como seu **produto de pacote** definindo o destino da aplicação na seção Adicionar ao destino**.

1. Selecione **Adicionar pacote**.

### Abordagem alternativa: instalar o framework manualmente
<a name="broadcast-ios-install-manual"></a>

1. Faça download da versão mais recente de [https://broadcast.live-video.net/1.40.0/AmazonIVSBroadcast.xcframework.zip](https://broadcast.live-video.net/1.40.0/AmazonIVSBroadcast.xcframework.zip).

1. Extraia o conteúdo do arquivo. `AmazonIVSBroadcast.xcframework` contém o SDK para dispositivo e para o simulador.

1. Incorporado o `AmazonIVSBroadcast.xcframework` arrastando-o para a seção **Frameworks, Libraries, and Embedded Content** (Frameworks, bibliotecas e conteúdo incorporado) da guia **General** (Geral) para o destino de sua aplicação.  
![\[A seção Estruturas de trabalho, bibliotecas e conteúdo incorporado da guia Geral para o destino da sua aplicação.\]](http://docs.aws.amazon.com/pt_br/ivs/latest/LowLatencyUserGuide/images/iOS_Broadcast_SDK_Guide_xcframework.png)

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

Implemente o `IVSBroadcastSession.Delegate`, que permite receber atualizações de estado e notificações de alteração 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 permissões
<a name="broadcast-ios-permissions"></a>

Sua aplicação deverá solicitar permissão para acessar a câmera e o microfone do usuário. (Isso não é específico do Amazon IVS; é necessário para qualquer aplicação que precise acessar câmeras e microfones.)

Aqui, verificamos se o usuário já concedeu permissões; caso contrário, nós as solicitamos:

```
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.
}
```

É necessário fazer isso para os tipos de mídia `.video` e `.audio`, se você quiser acesso a câmeras e microfones, respectivamente.

Também é necessário adicionar entradas para `NSCameraUsageDescription` e `NSMicrophoneUsageDescription` no `Info.plist`. Caso contrário, sua aplicação falhará ao tentar solicitar permissões.

## Desativar o temporizador de ociosidade da aplicação
<a name="broadcast-ios-disable-idle-timer"></a>

Isso é opcional, porém é recomendado. Isso impede que seu dispositivo entre em modo de suspensão enquanto usa o SDK de Transmissão, o que interromperia a transmissão.

```
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) Configurar o AvAudioSession
<a name="broadcast-ios-setup-avaudiosession"></a>

Por padrão, o SDK de difusão configurará o de sua aplicação `AVAudioSession`. Se você mesmo quiser gerenciá-lo, defina `IVSBroadcastSession.applicationAudioSessionStrategy` como `noAction`. Sem o controle da `AVAudioSession`, o SDK de Transmissão não pode gerenciar microfones internamente. Para usar microfones com a opção `noAction`, você pode criar um `IVSCustomAudioSource` e fornecer as suas próprias amostras por meio de uma `AVCaptureSession`, `AVAudioEngine` ou outra ferramenta que forneça amostras de áudio de PCM.

Se você estiver configurando manualmente o `AVAudioSession`, é necessário definir no mínimo a categoria como `.record` ou `.playbackAndRecord` e defini-lo como `active`. Caso deseje gravar áudio de dispositivos Bluetooth, será necessário especificar também a opção `.allowBluetooth`:

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

Recomendamos deixar que o SDK solucione isso para você. Caso contrário, se você quiser escolher entre diferentes dispositivos de áudio, será necessário gerenciar as portas manualmente.

## Criar a sessão de transmissão
<a name="broadcast-ios-create-session"></a>

A interface da transmissão é `IVSBroadcastSession`. Inicialize-a como mostrado abaixo:

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

Consulte também [Criar a sessão de transmissão (versão avançada)](broadcast-ios-use-cases.md#broadcast-ios-create-session-advanced)

## Definir o IVSImagePreviewView para pré-visualização
<a name="broadcast-ios-set-imagepreviewview"></a>

Caso queira exibir uma pré-visualização em um dispositivo de câmera ativo, adicione a pré-visualização `IVSImagePreviewView` ao dispositivo para sua hierarquia de exibição:

```
// 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)
}
```

## Iniciar uma transmissão
<a name="broadcast-ios-start"></a>

O nome de host que você recebe no campo de resposta `ingestEndpoint` da operação `GetChannel` precisa ser precedido de `rtmps://` e ter `/app` anexado. O URL completo deve estar no seguinte formato: `rtmps://{{ ingestEndpoint }}/app`

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

 O SDK de Transmissão para iOS oferece suporte somente à ingestão de RTMPS (e não à ingestão insegura de RTMP). 

## Interromper uma transmissão
<a name="broadcast-ios-stop"></a>

```
broadcastSession.stop()
```

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

### Interrupções de áudio
<a name="broadcast-ios-audio-interruptions"></a>

Há vários cenários em que o SDK de difusão não terá acesso exclusivo ao hardware de entrada de áudio. Alguns cenários de exemplo com os quais você precisa lidar são:
+ O usuário recebe uma chamada telefônica ou por FaceTime
+ O usuário ativa a Siri

A Apple facilita a resposta a esses eventos com a inscrição à `AVAudioSession.interruptionNotification`:

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

Então você pode tratar o evento com algo assim:

```
// 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
   }
}
```

### Aplicação entrando em segundo plano
<a name="broadcast-ios-app-to-background"></a>

As aplicações padrão do iOS não podem usar câmeras em segundo plano. Há também restrições na codificação de vídeo em segundo plano: como os codificadores de hardware são limitados, apenas as aplicações de primeiro plano têm acesso. Por causa disso, o SDK de Transmissão encerra automaticamente sua sessão e define a propriedade `isReady` como `false`. Quando sua aplicação está prestes a voltar ao primeiro plano, o SDK de Transmissão reconecta todos os dispositivos às entradas `IVSMixerSlotConfiguration` originais.

O SDK de Transmissão faz isso respondendo a `UIApplication.didEnterBackgroundNotification` e `UIApplication.willEnterForegroundNotification`.

Se você estiver fornecendo fontes de imagem personalizadas, deve se preparar para lidar com essas notificações. Talvez seja necessário tomar medidas adicionais para solucioná-las antes que a transmissão seja encerrada.

Consulte [Como usar vídeo de plano de fundo](broadcast-ios-use-cases.md#broadcast-ios-background-video) para obter uma solução alternativa que habilite uma transmissão enquanto a sua aplicação estiver em segundo plano.

### Serviços de mídia perdidos
<a name="broadcast-ios-media-services-lost"></a>

Em casos raríssimos, todo o subsistema de mídia de um dispositivo iOS apresentará falha. Nesse cenário, não é mais possível transmitir. Cabe à sua aplicação responder a essas notificações da forma adequada. No mínimo, inscreva-se para receber estas notificações:
+ [MediaServiceSwereLostNotification](https://developer.apple.com/documentation/avfaudio/avaudiosession/1616457-mediaserviceswerelostnotificatio): responda interrompendo sua transmissão e desalocando completamente sua `IVSBroadcastSession`. Todos os componentes internos usados pela sessão de difusão serão invalidados.
+ [MediaServiceSwereSetNotification](https://developer.apple.com/documentation/avfaudio/avaudiosession/1616540-mediaserviceswereresetnotificati): responda notificando seus usuários de que eles podem voltar a transmitir. Conforme seu caso de uso, você pode reiniciar a transmissão automaticamente nesse momento.