Skip to content

[ReplayKit] Another APP

In Ye, Kim edited this page Dec 3, 2024 · 4 revisions

해당 글은 노션에서도 확인 가능합니다.


개요

ReplayKit을 사용하면 In-App 레코딩과 캡처가 가능할 뿐만 아니라 앱이 제 3자 방송 서비스로 콘텐츠를 스트리밍할 수 있게 됩니다.

In-App 레코딩과 캡처에 대한 내용은 이전 페이지에서 다뤘으니 이번에는 제 3자 방송 서비스로 콘텐츠를 스트리밍하는 방법에 대해서 알아보겠습니다.


ReplayKit을 사용하여 제 3자 방송서비스로 콘텐츠 스트리밍 하기

1. 방송 시작 전

(예시에서 사용할 방송 서비스는 Mobcrush입니다.)

예를 들어 어떤 유저가 특정 게임을 방송서비스에 방송하고 싶어 할 경우 ReplayKit을 사용할 수 있습니다.

조금 더 자세히 살펴보겠습니다.

먼저, Client App은 ReplayKit API와 통신(communicates)하여 방송을 시작하도록 요청합니다.

이 시점에서 ReplayKit은 사용자가 방송 서비스를 선택할 수 있는 UI를 표시합니다.

1-1. 구현하기

지금까지 내용을 구현해 보겠습니다.

가장 먼저 방송을 시작할 수 있도록 UI를 표시해야합니다.

이를 위해서는 RPBroadcastActivityViewController에 대해 이해해야 합니다.

RPBroadcastActivityViewController는 클래스로 사용자가 방송 서비스를 선택하는 UI를 표시하는 뷰컨트롤러입니다.

RPBroadcastActivityViewController를 사용해 보겠습니다.

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 버튼을 추가하는 코드 (생략)
    }
    
    // 버튼이 눌리면 실행되는 코드
    @objc func didPressBroadcastButton() {
        RPBroadcastActivityViewController.load { broadcastAVC, error in
            if let broadcastAVC {
                broadcastAVC.delegate = self
                self.present(broadcastAVC, animated: true)
            }
        }
    }
}

extension ViewController: RPBroadcastActivityViewControllerDelegate {
    func broadcastActivityViewController(_ broadcastActivityViewController: RPBroadcastActivityViewController, didFinishWith broadcastController: RPBroadcastController?, error: (any Error)?) {
        broadcastActivityViewController.dismiss(animated: true) {
            broadcastController?.startBroadcast{ error in
                print("broadcast started!")
            }
            
        }
    }
}

load 메소드를 통해 RPBroadcastActivityViewController가 load되고, 그 결과가 클로저로 전달됩니다.

즉, broadcastAVC라고 작성한 파라미터가 불러온 RPBroadcastActivityViewController가 됩니다.

실제로 버튼을 눌러보면 다음과 같이 뜨는 것을 확인할 수 있습니다.

현재 제 폰에는 Mobcrush과 같은 스트리밍 앱이 없으므로 앱을 찾으라고 뜨지만, 만약 앱이 깔려 있다면 다음과 같이 팝업이 나타납니다.

그리고 RPBroadcastActivityViewControllerDelegate 에 있는 broadcastActivityViewController(_:didFinishWith:error:) 메소드를 통해 선택이 완료된 시점을 알 수 있습니다. 이 시점에 RPBroadcastActivityViewController를 닫아줍니다.

그리고 RPBroadcastController를 통해서 방송을 시작합니다.

extension ViewController: RPBroadcastActivityViewControllerDelegate {
    func broadcastActivityViewController(_ broadcastActivityViewController: RPBroadcastActivityViewController, didFinishWith broadcastController: RPBroadcastController?, error: (any Error)?) {
        broadcastActivityViewController.dismiss(animated: true) { // 닫기
            broadcastController?.startBroadcast{ error in //방송 시작
                print("broadcast started!")
            }
        }
    }
}

RPBroadcastController 역시 클래스이며 방송을 시작하고 제어하기 위한 메서드를 포함하고 있습니다.

또한 RPBroadcastControllerDelegate를 통해서 오류와 등을 처리할 수 있습니다.

2. 방송 시작 후

이제 실제로 방송이 시작되면, ReplayKit은 Mobcrush의 Extension에 오디오와 비디오 Sample을 전달합니다.

Broadcast Upload Extension은 ReplayKit이 전달한 미디어 샘플을 받아서 인코딩하고, 비디오 스트림을 생성하여 온라인 서비스로 업로드합니다.

Broadcast Upload Extension은 XCode 템플릿으로 쉽게 추가할 수 있으며, 추가하고 나면 sampleHandler 클래스가 생성됩니다. 아래 코드는 기본으로 생성된 코드입니다.

import ReplayKit

class SampleHandler: RPBroadcastSampleHandler {
    override func broadcastStarted(withSetupInfo setupInfo: [String : NSObject]?) {
    }
    
    override func broadcastPaused() {
    }
    
    override func broadcastResumed() {
    }
    
    override func broadcastFinished() {
    }
    
    override func processSampleBuffer(_ sampleBuffer: CMSampleBuffer, with sampleBufferType: RPSampleBufferType) {
        switch sampleBufferType {
        case RPSampleBufferType.video:
            break
        case RPSampleBufferType.audioApp:
            break
        case RPSampleBufferType.audioMic:
            break
        @unknown default:
            fatalError("Unknown type of sample buffer")
        }
    }
}

여기서 방송 시작, 중지, 일시 정지 등의 이벤트를 처리하는 함수를 override할 수 있습니다.

override func broadcastStarted(withSetupInfo setupInfo: [String : NSObject]?) {
}

setupInfo에는 다양한 정보가 담겨옵니다. 예를 들어 방송이 앱에서 시작된 건지 Control Center에서 시작된 건지 알 수 있습니다.

ReplayKit은 Broadcast Upload Extension의 processSampleBuffer로 다음 3개를 제공합니다.

  1. 화면에서 캡처한 비디오 샘플
  2. 앱에서 캡처한 오디오 샘플
  3. 마이크에서 캡처한 오디오 샘플

이렇게 들어온 콘텐츠를 인코딩하는데 다양한 기술을 활용할 수 있지만, 실용적인 측면에서 VideoToolbox라는 하위 수준 API를 제공합니다.

왜 실용적인 측면에 VideoToolbox라는 하위 수준 API를 사용하는 것일까요?

App Extension은 일반 앱에 비해서 훨씬 낮은 메모리 한도를 가지고 있습니다.
그렇기 때문에 하드웨어 가속인코딩에 접근할 수 있는 것이 매우 중요해집니다. 따라서 실용적인 측면에서 VideoToolbox를 사용합니다.

3. Broadcast Setup UI Extension (방송 시작 전)

다시 방송 시작전으로 돌아가 보겠습니다.

사실 Broadcast Upload Extension말고도 Extension이 1개 더 있었습니다.

바로 Broadcast Setup UI Extension 입니다.

이름 그래도 사용자로부터 어떠한 정보를 입력받는 UI를 제공합니다. 예를 들어 방송 이름이나 로그인 정보 같은 세부 정보를 입력받게 할 수 있습니다.

Broadcast Upload Extension 마찬가지로 XCode에서 템플릿으로 손쉽게 추가해서 사용이 가능합니다.

Clone this wiki locally