개요
Reincubate의 Camo SDK는 애플리케이션에서 macOS 및 Windows의 Camo Studio로 실시간 시청각 데이터를 보내는 기능을 제공합니다. USB 또는 무선으로 작동합니다. USB는 짧은 대기 시간과 성능에 최적화되어 앱에서 가능한 한 적은 리소스를 사용합니다. 무선은 케이블로부터 자유를 줍니다.
Camo SDK는 상업적 파트너와 협력자가 사용할 수 있습니다. 자세한 내용은 enterprise@reincubate.com 으로 팀에 문의하세요.
현재 SDK는 iOS 12 이상의 물리적 iOS 또는 iPadOS 기기(시뮬레이터 및 Mac Catalyst 제외)에서 실행되는 iOS 애플리케이션만 지원합니다. Camo SDK는 기본적으로 Objective-C와 호환되지 않으므로 앱이 주로 Objective-C인 경우 래퍼를 만들어야 할 수 있습니다.
API 참조
바로 들어가고 싶다면 Camo SDK에서 제공하는 모든 기호를 문서화 하는 전체 API 참조를 볼 수 있습니다. 그렇지 않으면 이 문서에서 SDK와의 샘플 통합을 안내합니다.
Camo SDK 설치
Camo SDK를 받으면 CamoProducerKit.xcframework
라는 파일을 받게 됩니다. 이 독립형 프레임워크에는 외부 종속성 없이 필요한 모든 것이 있으므로 설치가 쉽습니다.
- 프로젝트 네비게이터에서 애플리케이션의 프로젝트를 선택하십시오.
- 프로젝트의 대상 사이드바에서 애플리케이션의 대상을 선택합니다. 사이드바가 표시되지 않으면 페이지 상단의 드롭다운에 있을 수 있습니다.
- '일반' 탭에 있는지 확인하고 '프레임워크, 라이브러리 및 포함된 콘텐츠' 헤더까지 아래로 스크롤합니다.
CamoProducerKit.xcframework
파일을 끌어서 해당 헤더 아래의 파일 목록에 놓습니다.- SDK가 "Embed & Sign"으로 설정되어 있는지 확인하십시오.
완료되면 그림과 같은 프레임워크가 표시되어야 합니다.
앱과 통합
Camo 서비스 제어
CamoProducerKit의 핵심은 앱에 Camo SDK를 제어하기 위한 중앙 집중식 인터페이스를 제공 하는 CamoController 입니다.
앱에서 CamoController 의 인스턴스를 초기화해야 합니다. 앱 시작 시 이 작업을 수행하거나 나중에 저장하도록 선택할 수 있습니다. start()
명시적으로 시작할 때까지 Camo 컨트롤러는 리소스를 거의 사용하지 않습니다. 그러나 초기화 시 오디오 및 비디오 인코딩을 준비합니다.
import CamoProducerKit class MyVideoManager { let controller = CamoController() // ... }
앱에서 Camo 통합을 활성화하고 연결을 용이하게 하기 위해 Camo 서비스 start()
호출할 수 있습니다. stop()
을 호출하여 중지할 수 있습니다.
controller.start() // ... controller.stop()
이 코드는 시작이지만 여전히 Camo Studio에서 새 연결을 수락할 수 없습니다.
새로운 연결에 응답하기
앱이 Camo Studio에서 새 연결을 수락할 수 있으려면 먼저 CamoControllerDelegate 를 구현해야 합니다. 이 두 가지 대리자 메서드를 구현하면 연결 상태 변경에 대한 알림을 받고 연결을 수락할지 거부할지 결정할 수 있습니다.
extension MyVideoManager: CamoControllerDelegate { // Upon receiving a connection request, you can decide whether or not to accept it. func camoControllerShouldAcceptIncomingConnection(_ controller: CamoController) -> Bool { // You could return false if you aren't ready to accept connections, such as during onboarding. return true } // Called whenever the connection state changes, such as if the Camo service starts or stops, or if a new connection is made. func camoController(_ controller: CamoController, stateDidChangeTo state: CamoControllerState?) { // From here, you can update your UI and other state print("New state:", state) } }
완료되면 이제 앱을 열고 USB에 연결하고 Camo Studio에서 장치를 볼 수 있습니다.
무선 연결
무선 연결을 사용하려면 사용자가 로컬 네트워크 액세스 권한을 부여해야 합니다. Bonjour 서비스는 Info.plist에서 NSBonjourServices로 추가되어야 합니다.
_camo._tcp
-
_camopairing._tcp
camoController.start()
를 호출하면 SDK가 Camo Studio와 페어링하고 네트워크 연결을 설정할 준비가 된 것입니다.
편성
사용자가 Camo Studio에서 "+" 버튼을 클릭하면 페어링 프로세스가 시작됩니다. Camo Studio는 앱 측에서 스캔해야 하는 QR 코드를 보여줍니다.
페어링 단계:
- QR 코드를 표시하려면 Camo Studio에서 "+"를 클릭하십시오.
- QR 코드를 스캔하고 데이터를 문자열로 가져옵니다.
-
camoController.pairStudioWithQRCodeData(codeData) { success in }
를 호출하여 해당 데이터를 SDK에 전달합니다. -
pairStudioWithQRCodeData
메서드에는 페어링이 성공했는지 알려주는 콜백이 있습니다. - SDK는 Camo Studio와 페어링을 하고 자동으로 연결됩니다.
페어링을 취소해야 하는 경우(예: 사용자가 QR 스캐너 또는 앱을 닫은 경우) camoController.cancelPairing()
을 호출해야 합니다.
페어링에는 30초의 제한 시간이 있습니다. pairStudioWithQRCodeData 호출 후 30초 동안 페어링이 발생하지 않으면 pairStudioWithQRCodeData
메서드에 대한 콜백이 success
값 false
로 호출 pairStudioWithQRCodeData
.
페어링된 기기
페어링이 완료되면 SDK가 페어링 데이터를 페어링된 장치 목록에 저장합니다. CamoController
에는 해당 목록으로 작업하는 2가지 방법이 있습니다.
pairedDevices
를 사용하여 목록 가져오기(해당 목록을 UI에 표시하려는 경우)- 장치를 잊어 버리려면
removePairedDevice
다음에 Camo Studio에 무선 연결을 설정하려면 Camo Studio에서 "+" 버튼을 클릭하고 연결이 설정될 때까지 기다리면 됩니다. QR 코드를 다시 스캔할 필요가 없습니다.
연결 상태 확인
CamoController 는 위에서 본 것처럼 상태 변경 대리자 메서드 에도 포함된 CamoControllerState 속성을 제공합니다. 이 열거형 은 UI에 표시할 연결된 컴퓨터의 이름과 같이 앱에 유용한 정보를 제공합니다.
다음은 연결 상태를 반영하도록 UI를 업데이트하는 방법의 예입니다.
func camoController(_ controller: CamoController, stateDidChangeTo state: CamoControllerState?) { let statusText = { () -> String in guard case let .running(serviceState) = state else { return "Camo service not running" } switch serviceState { case .active(let connection): return "Connected to \(connection.name)" case .paused(let connection): return "Paused, but connected to \(connection.name)" case .notConnected: return "Camo service running, but no connection" } }() DispatchQueue.main.async { self.statusTextLabel.text = statusText } }
시청각 데이터 발송
클라이언트에게 가능한 한 많은 유연성을 제공하기 위해 Camo SDK는 캡처를 제공하거나 제어하지 않습니다. 대신 CamoController 에 오디오 및 비디오 데이터를 제공할 책임이 있습니다. 이것은 두 개의 간단한 API 호출로 수행할 수 있습니다.
// upon receiving video from the camera or elsewhere camoController.enqueueVideo(sampleBuffer: sampleBuffer) // upon receiving audio from the microphone or elsewhere camoController.enqueuePCMAudio(data: chunk)
동영상 보내기
비디오 파이프라인에서 CMSampleBuffer에 액세스할 수 있는 경우 이 데이터를 Camo SDK에 전달하는 것은 간단합니다.
이 때문에 기본 비디오 AVCaptureSession으로 이것을 설정하는 것은 매우 간단합니다. 다음은 실행 중인 예입니다.
class CaptureController: AVCaptureVideoDataOutputSampleBufferDelegate { // ... func startSession() throws { guard let camera = AVCaptureDevice.default(for: .video) else { fatalError("No camera found") } let input = try AVCaptureDeviceInput(device: camera) captureSession.addInput(input) let output = AVCaptureVideoDataOutput() output.alwaysDiscardsLateVideoFrames = true output.setSampleBufferDelegate(self, queue: videoDataOutputQueue) captureSession.addOutput(output) captureSession.startRunning() } // ... func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) { camoController.enqueueVideo(sampleBuffer: sampleBuffer) } }
비디오 프레임을 보낼 때 다음을 확인하십시오.
- 프레임 지속 시간은 30FPS입니다.
- 픽셀 형식은
kCVPixelFormatType_32BGRA
입니다.
API 참조 에서 자세한 내용을 볼 수 있습니다.
오디오 보내기
오디오 전송은 비디오와 유사하지만 애플리케이션에서 오디오를 수신하는 방식에 따라 몇 가지 단계가 더 필요할 수 있습니다. 샘플 구현은 Camo SDK에 포함된 데모 앱을 참조하십시오.
오디오 데이터를 보낼 때 다음을 확인하십시오.
- 샘플 속도는 48kHz입니다.
- 오디오 코덱은 LPCM입니다.
- 채널 수는 2입니다.
- 비트 깊이는 32입니다.
- 오디오 패킷당 샘플 수는 Studio(macOS 또는 Windows)에 따라 다르며 CamoController.audioSamplesRequired 에서 가져올 수 있습니다.
API 참조 에서 자세한 내용을 볼 수 있습니다.