visão global
Reincubate's Camo SDK provides the ability to send real-time audiovisual data from your application to Camo Studio on macOS and Windows. It functions over USB or wirelessly. USB is optimised for low-latency and performance, consuming as few resources in your app as possible. Wireless gives freedom from cables.
O Camo SDK está disponível para uso por parceiros comerciais e colaboradores. Para mais informações, entre em contato com sua equipe em enterprise@reincubate.com .
Atualmente, o SDK só oferece suporte a aplicativos iOS executados em um dispositivo iOS ou iPadOS físico (excluindo simuladores e Mac Catalyst) no iOS 12 ou superior. O Camo SDK não tem compatibilidade com Objective-C pronto para uso, portanto, se seu aplicativo for principalmente Objective-C, talvez você precise criar um wrapper.
Referência API
Se quiser começar, você pode ver a referência completa da API , que documenta todos os símbolos fornecidos pelo Camo SDK. Caso contrário, este documento o guiará por um exemplo de integração com o SDK.
Instalando o Camo SDK
Ao receber o Camo SDK, você receberá um arquivo chamado CamoProducerKit.xcframework . Esta estrutura independente tem tudo que você precisa sem dependências externas, então a instalação é fácil.
- Selecione o projeto do seu aplicativo no Project Navigator.
- Escolha o destino do seu aplicativo na barra lateral de destino do projeto. Se você não vir uma barra lateral, ela pode estar em uma lista suspensa na parte superior da página.
- Certifique-se de estar na guia 'Geral' e role para baixo até o cabeçalho "Estruturas, bibliotecas e conteúdo incorporado".
- Arraste o
CamoProducerKit.xcframeworke solte-o na lista de arquivos abaixo desse cabeçalho. - Certifique-se de que o SDK está definido como "Embed & Sign".
Quando terminar, você deve ver a estrutura conforme ilustrada:

Integração com seu aplicativo
Controlando o serviço Camo
No núcleo do CamoProducerKit está o CamoController , que fornece ao seu aplicativo uma interface centralizada para controlar o Camo SDK.
Em seu aplicativo, você deve inicializar uma instância do CamoController . Você pode optar por fazer isso no lançamento do aplicativo ou salvá-lo para mais tarde. Até que seja explicitamente iniciado com start() , o controlador Camo usará poucos recursos. No entanto, ele se preparará para a codificação de áudio e vídeo na inicialização.
import CamoProducerKit
class MyVideoManager {
let controller = CamoController()
// ...
}
Quando quiser ativar a integração Camo em seu aplicativo, iniciando o serviço Camo para facilitar as conexões, pode-se chamar start() . Quando terminar, você pode pará-lo chamando stop() .
controller.start()
// ...
controller.stop()
Este código é um começo, mas ainda não aceita novas conexões do Camo Studio.
Respondendo a novas conexões
Antes que seu aplicativo seja capaz de aceitar novas conexões do Camo Studio, você precisará implementar o CamoControllerDelegate . Ao implementar esses dois métodos de delegação, você pode ser notificado sobre as alterações no estado da conexão e decidir se aceita ou rejeita uma conexão.
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)
}
}
Feito isso, agora você deve ser capaz de abrir seu aplicativo, conectar-se ao USB e visualizar seu dispositivo no Camo Studio.
Conexões sem fio
Para usar conexões sem fio, os usuários terão que conceder acesso à rede local. Os serviços Bonjour devem ser adicionados como NSBonjourServices no Info.plist:
_camo._tcp-
_camopairing._tcp
Quando você chama camoController.start() , o SDK está pronto para emparelhamento e para estabelecer conexões de rede com o Camo Studio.
Emparelhamento
Quando um usuário clica no botão “+” no Camo Studio, o processo de emparelhamento é iniciado. O Camo Studio mostra o código QR que deve ser escaneado no lado do aplicativo.
Passos para o emparelhamento:
- Clique em “+” no Camo Studio para mostrar o código QR
- Digitalize o código QR e obtenha seus dados como uma string
- Passe esses dados para o SDK chamando
camoController.pairStudioWithQRCodeData(codeData) { success in } - O método
pairStudioWithQRCodeDatatem um retorno de chamada que informará se o emparelhamento foi bem-sucedido - O SDK fará o emparelhamento com o Camo Studio e a conexão será estabelecida automaticamente.
Se você precisar cancelar o emparelhamento (por exemplo, se o usuário fechou o QR Scanner ou o aplicativo), chame camoController.cancelPairing()
O emparelhamento tem um tempo limite de 30 segundos. O retorno de chamada para o método pairStudioWithQRCodeData será chamado com o valor de success false se o emparelhamento não ocorrer durante 30 segundos após a chamada pairStudioWithQRCodeData .
Dispositivos pareados
Após o emparelhamento, o SDK salvará os dados de emparelhamento na lista de dispositivos emparelhados. CamoController tem 2 métodos para trabalhar com essa lista:
pairedDevicespara obter a lista (se você quiser mostrar essa lista na interface do usuário)-
removePairedDevicepara esquecer o dispositivo
Para estabelecer a conexão sem fio com o Camo Studio da próxima vez, basta clicar no botão “+” no Camo Studio e aguardar até que a conexão seja estabelecida, não há necessidade de digitalizar o código QR novamente.
Determinando o estado da conexão
O CamoController fornece uma propriedade CamoControllerState , que também está incluída no método de delegação de mudança de estado, conforme visto acima. Este enum fornece informações úteis para seu aplicativo, como o nome do computador conectado para exibição na IU.
Aqui está um exemplo de como você pode atualizar sua IU para refletir o estado da conexão:
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
}
}
Envio de dados audiovisuais
Para permitir aos clientes o máximo de flexibilidade possível, o Camo SDK não fornece nem controla nenhuma captura. Em vez disso, você é responsável por fornecer ao CamoController os dados de áudio e vídeo. Isso pode ser feito com duas chamadas de API simples:
// upon receiving video from the camera or elsewhere
camoController.enqueueVideo(sampleBuffer: sampleBuffer)
// upon receiving audio from the microphone or elsewhere
camoController.enqueuePCMAudio(data: chunk)
Enviando vídeo
Se você tiver acesso a um CMSampleBuffer em seu pipeline de vídeo, é trivial passar esses dados para o Camo SDK.
Por causa disso, configurar isso com um vídeo básico AVCaptureSession é extremamente simples. Aqui está um exemplo disso em ação.
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)
}
}
Ao enviar quadros de vídeo, certifique-se de que:
- A duração do quadro é de 30 FPS.
- O formato do pixel é
kCVPixelFormatType_32BGRA.
Você pode ver mais detalhes na referência da API.
Enviando áudio
O envio de áudio é semelhante ao vídeo, mas pode exigir mais algumas etapas, dependendo de como seu aplicativo o recebe. Para obter um exemplo de implementação, consulte o aplicativo de demonstração incluído no Camo SDK.
Ao enviar dados de áudio, certifique-se de que:
- Sua taxa de amostragem é 48 kHz.
- O codec de áudio é LPCM.
- O número de canais é 2.
- A profundidade de bits é de 32.
- O número de amostras por pacote de áudio depende do Studio (macOS ou Windows), você pode obtê-lo em CamoController.audioSamplesRequired .
Você pode ver mais detalhes na referência da API.