

# IVS iOS Broadcast SDK 시작하기 \| 저지연 스트리밍
<a name="broadcast-ios-getting-started"></a>

이 문서에서는 Amazon IVS Low-Latency Streaming iOS Broadcast SDK 시작하기와 관련된 단계를 안내합니다.

## 라이브러리 설치
<a name="broadcast-ios-install"></a>

Swift Package Manager를 사용하여 Broadcast SDK를 통합하는 것이 좋습니다. (또는 프레임워크를 프로젝트에 수동으로 추가할 수 있습니다.)

### 권장: Broadcast 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`에는 디바이스와 시뮬레이터 모두에 대한 SDK가 포함되어 있습니다.

1. 애플리케이션 대상에 대해 **일반** 탭의 **프레임워크, 라이브러리 및 포함된 콘텐츠** 섹션으로 끌어 `AmazonIVSBroadcast.xcframework`를 포함합니다.  
![애플리케이션 대상에 대한 일반(General) 탭의 프레임워크, 라이브러리 및 포함된 콘텐츠(Frameworks, Libraries, and Embedded Content) 섹션.](http://docs.aws.amazon.com/ko_kr/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>

이 단계는 선택 사항이지만 권장됩니다. Broadcast SDK를 사용하는 동안 디바이스가 절전 모드로 전환되는 것을 방지함으로써 브로드캐스트가 중단되는 것을 막습니다.

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

기본적으로 Broadcast SDK에서 애플리케이션의 `AVAudioSession`을 설정합니다. 직접 관리하려면 `IVSBroadcastSession.applicationAudioSessionStrategy` 값을 `noAction`으로 설정합니다. `AVAudioSession` 제어 없이 Broadcast SDK가 마이크를 내부적으로 관리할 수 없습니다. `noAction` 옵션으로 마이크를 사용하려면 `IVSCustomAudioSource`를 생성하고 `AVCaptureSession`, `AVAudioEngine` 또는 PCM 오디오 샘플을 제공하는 다른 도구를 통해 사용자의 샘플을 제공할 수 있습니다.

`AVAudioSession`을 수동으로 설정하는 경우 최소한 범주를 `.record` 또는 `.playbackAndRecord`로 설정하고 `active`로 설정해야 합니다. Bluetooth 디바이스에서 오디오를 녹음하려면 `.allowBluetooth` 옵션도 지정해야 합니다.

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

SDK에서 자동으로 처리하도록 하는 것이 좋습니다. 그러지 않으면 다른 오디오 디바이스 중에서 선택하려는 경우 포트를 수동으로 관리해야 합니다.

## 브로드캐스트 세션 생성
<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 Broadcast 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>

Broadcast SDK가 오디오 입력 하드웨어에 단독으로 액세스할 수 없는 여러 경우가 있습니다. 처리해야 하는 몇 가지 예제 시나리오는 다음과 같습니다.
+ 사용자가 전화 통화나 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의 표준 애플리케이션은 백그라운드에서 카메라를 사용할 수 없습니다. 백그라운드에서의 비디오 인코딩에도 제한이 있습니다. 하드웨어 인코더가 제한되므로 포그라운드 애플리케이션만 액세스할 수 있습니다. 이 때문에 Broadcast SDK는 자동으로 세션을 종료하고 세션의 `isReady` 속성을 `false`로 설정합니다. 애플리케이션이 포그라운드로 다시 전환하려고 할 때 Broadcast SDK는 모든 디바이스를 원래 `IVSMixerSlotConfiguration` 항목에 다시 연결합니다.

Broadcast SDK는 `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) - 사용자에게 다시 브로드캐스트할 수 있다고 알려서 응답합니다. 사용 사례에 따라서는 이때 브로드캐스팅을 자동으로 시작할 수 있습니다.