

# 開始使用 IVS iOS 廣播 SDK \| 低延遲串流
<a name="broadcast-ios-getting-started"></a>

本文件將帶您了解開始使用 Amazon IVS 低延遲串流功能 iOS 廣播 SDK 的相關步驟。

## 安裝程式庫
<a name="broadcast-ios-install"></a>

建議您透過 Swift Package Manager 來整合廣播 SDK。(或者，您可以手動將架構新增到您的專案中)。

### 建議：整合廣播 SDK (Swift Package Manager)
<a name="broadcast-ios-install-swift"></a>

1. 從 [https://broadcast.live-video.net/1.41.0/Package.swift](https://broadcast.live-video.net/1.41.0/Package.swift) 下載 Package.swift 檔案。

1. 在您的專案中，建立一個名為 AmazonIVSBroadcast 的新目錄，然後將其新增至版本控制。

1. 將下載的 Package.swift 檔案放在新目錄中。

1. 在 Xcode 中，前往**檔案 > 新增套件相依性**，然後選取**新增本機...**

1. 導覽至建立的 AmazonIVSBroadcast 目錄，將其選取，然後選取**新增套件**。

1. 系統提示您**選擇用於 AmazonIVSBroadcast 的套件產品**時，請在**新增至目標**區段中設定應用程式目標，從而選取 **AmazonIVSBroadcast** 作為**套件產品**。

1. 選取**新增套件**。

### 替代方法：手動安裝架構
<a name="broadcast-ios-install-manual"></a>

1. 從 [https://broadcast.live-video.net/1.41.0/AmazonIVSBroadcast.xcframework.zip](https://broadcast.live-video.net/1.41.0/AmazonIVSBroadcast.xcframework.zip) 中下載最新版本。

1. 解壓縮封存檔的內容。`AmazonIVSBroadcast.xcframework` 包含用於裝置和模擬器的開發套件。

1. 內嵌 `AmazonIVSBroadcast.xcframework`，方法是將其拖曳至您的應用程式目標的**一般**索引標籤的**架構、程式庫和內嵌內容**部分中。  
![您的應用程式目標的一般索引標籤的架構、程式庫和內嵌內容區段。](http://docs.aws.amazon.com/zh_tw/ivs/latest/LowLatencyUserGuide/images/iOS_Broadcast_SDK_Guide_xcframework.png)

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

實作可讓您接收狀態更新和裝置變更通知的 `IVSBroadcastSession.Delegate`：

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

## 請求權限
<a name="broadcast-ios-permissions"></a>

您的應用程式必須請求許可才能存取使用者的攝影機和麥克風。(這不限於 Amazon IVS；任何需要存取攝影機和麥克風的應用程式都必須如此)。

在這裡，我們檢查使用者是否已經授予許可，如果沒有則提出請求：

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

如果您想要存取攝影機和麥克風，必須分別對 `.video` 和 `.audio` 媒體類型執行此動作。

此外，您必須將 `NSCameraUsageDescription` 和 `NSMicrophoneUsageDescription` 的項目新增至您的 `Info.plist`。否則，您的應用程式將在嘗試請求許可時當機。

## 停用應用程式閒置計時器
<a name="broadcast-ios-disable-idle-timer"></a>

此為選用操作，但建議您採用。這可以防止您的裝置在使用廣播開發套件時進入休眠狀態，導致廣播中斷。

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

## (選擇性) 設定 AVAudioSession
<a name="broadcast-ios-setup-avaudiosession"></a>

根據預設，廣播開發套件會設定您應用程式的 `AVAudioSession`。如果您要自行管理，請將 `IVSBroadcastSession.applicationAudioSessionStrategy` 設為 `noAction`。如果沒有控制 `AVAudioSession`，則廣播開發套件無法在內部管理麥克風。若要搭配 `noAction` 選項使用麥克風，您可以建立一個 `IVSCustomAudioSource`，並透過 `AVCaptureSession`、`AVAudioEngine` 或提供 PCM 音訊樣本的其他工具，提供您自己的樣本。

如果您要手動設定 `AVAudioSession`，至少必須將類別設為 `.record` 或 `.playbackAndRecord`，並將其設為 `active`。如果您想要從藍牙裝置錄製音訊，則必須一併指定 `.allowBluetooth` 選項：

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

我們建議您讓開發套件為您處理設定。否則，如果您想要在不同的音訊裝置之間進行選擇，則必須手動管理連接埠。

## 建立廣播工作階段
<a name="broadcast-ios-create-session"></a>

廣播介面是 `IVSBroadcastSession`。如下所示進行初始化：

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

另請參閱[建立廣播工作階段 (進階版)](broadcast-ios-use-cases.md#broadcast-ios-create-session-advanced)

## 設定 IVSImagePreviewView 以供預覽
<a name="broadcast-ios-set-imagepreviewview"></a>

如果您想要顯示作用中攝影機裝置的預覽，請將裝置的預覽 `IVSImagePreviewView` 新增至您的視圖層次結構中：

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

## 開始廣播
<a name="broadcast-ios-start"></a>

您在 `GetChannel` 操作的 `ingestEndpoint` 回應欄位中收到的主機名稱需具有 `rtmps://` 前綴和 `/app` 後綴。完整的 URL 格式如下：`rtmps://{{ ingestEndpoint }}/app`

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

 iOS 廣播 SDK 僅支援 RTMPS 擷取 (非不安全的 RTMP 擷取)。

## 停止廣播
<a name="broadcast-ios-stop"></a>

```
broadcastSession.stop()
```

## 管理生命週期事件
<a name="broadcast-ios-lifecycle-events"></a>

### 音訊中斷
<a name="broadcast-ios-audio-interruptions"></a>

在幾種情境下，廣播開發套件將不具有音訊輸入硬體的專屬存取權。您需要處理的一些範例情境如下：
+ 使用者接聽電話或 FaceTime 通話
+ 使用者啟用 Siri

Apple 可讓您訂閱 `AVAudioSession.interruptionNotification` 來輕鬆回應這些事件：

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

然後，您可以仿照以下作法處理事件：

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

### 應用程式進入背景
<a name="broadcast-ios-app-to-background"></a>

iOS 上的標準應用程式不允許在背景中使用攝影機。背景中的影片編碼也有限制：由於硬體編碼器有限，前景應用程式才有存取權。因此，廣播開發套件會自動終止其工作階段，並將其 `isReady` 屬性設為 `false`。當您的應用程式即將再次進入前景時，廣播開發套件會將所有裝置重新連接到其原始 `IVSMixerSlotConfiguration` 項目。

廣播開發套件的作法是回應 `UIApplication.didEnterBackgroundNotification` 和 `UIApplication.willEnterForegroundNotification`。

如果您提供自訂影像來源，必須準備好處理這些通知。您可能需要採取額外的步驟，才能在串流終止前妥善處理。

請參閱[使用背景影片](broadcast-ios-use-cases.md#broadcast-ios-background-video)以取得在應用程式位於背景時啟用串流的解決方法。

### 媒體服務遺失
<a name="broadcast-ios-media-services-lost"></a>

在極少數情況下，iOS 裝置上的整個媒體子系統將會當機。此時無法再進行廣播。您的應用程式必須適當地回應這些通知。請至少訂閱這些通知：
+ [mediaServicesWereLostNotification](https://developer.apple.com/documentation/avfaudio/avaudiosession/1616457-mediaserviceswerelostnotificatio) — 以停止廣播並完全取消配置 `IVSBroadcastSession` 作為回應。廣播工作階段使用的所有內部元件都會失效。
+ [mediaServicesWereResetNotification](https://developer.apple.com/documentation/avfaudio/avaudiosession/1616540-mediaserviceswereresetnotificati) — 以通知使用者可再次廣播作為回應。依據您的使用案例而定，您可能會在此時再次自動開始廣播。