El Camo SDK de Reincubate ofrece la posibilidad de enviar datos audiovisuales en tiempo real desde tu aplicación a Camo Studio en macOS y Windows. Funciona por USB o de forma inalámbrica. El USB está optimizado para baja latencia y rendimiento, consumiendo el mínimo de recursos posible en tu aplicación. El modo inalámbrico te libera de los cables.
El Camo SDK está disponible para su uso por parte de socios comerciales y colaboradores. Para más información, ponte en contacto con nuestro equipo en enterprise@reincubate.com.
Actualmente, el SDK solo admite aplicaciones de iOS que se ejecuten en un dispositivo físico con iOS o iPadOS (excluyendo simuladores y Mac Catalyst) con iOS 12 o superior. El Camo SDK no tiene compatibilidad con Objective-C de fábrica, así que si tu aplicación es principalmente Objective-C, es posible que necesites crear un wrapper.
Referencia de la API
Si quieres empezar directamente, puedes consultar la referencia completa de la API, que documenta todos los símbolos que proporciona el Camo SDK. De lo contrario, este documento te guiará a través de un ejemplo de integración con el SDK.
Instalar el Camo SDK
Cuando recibas el Camo SDK, habrás recibido un archivo llamado CamoProducerKit.xcframework. Este framework autocontenido tiene todo lo que necesitas sin dependencias externas, por lo que la instalación es sencilla.
- Selecciona el proyecto de tu aplicación en el Navegador de proyectos.
- Elige el target de tu aplicación en la barra lateral de targets del proyecto. Si no ves una barra lateral, puede que esté en un menú desplegable en la parte superior de la página.
- Asegúrate de estar en la pestaña «General» y desplázate hacia abajo hasta el encabezado «Frameworks, Libraries, and Embedded Content».
- Arrastra el archivo
CamoProducerKit.xcframeworky suéltalo en la lista de archivos debajo de ese encabezado. - Asegúrate de que el SDK esté configurado como «Embed & Sign».
Cuando termines, deberías ver el framework como se muestra en la imagen:

Camo SDK incorporado en una aplicación de ejemplo
Integración con tu aplicación
Camo SDK en acción
Con el Camo SDK se incluye una aplicación de demostración que muestra cómo transmitir datos desde la cámara y los micrófonos del dispositivo, así como desde un archivo de vídeo incluido.
Controlar el servicio de Camo
En el núcleo de CamoProducerKit se encuentra CamoController, que ofrece a tu aplicación una interfaz centralizada para controlar el Camo SDK.
En tu aplicación, debes inicializar una instancia de CamoController. Puedes hacerlo al iniciar la aplicación o dejarlo para más adelante. Hasta que se inicie explícitamente con start(), el controlador de Camo usará muy pocos recursos. Sin embargo, se preparará para la codificación de audio y vídeo al inicializarse.
import CamoProducerKit
class MyVideoManager {
let controller = CamoController()
// ...
}
Cuando quieras activar la integración de Camo en tu aplicación, iniciando el servicio de Camo para facilitar las conexiones, puedes llamar a start(). Cuando hayas terminado, puedes detenerlo llamando a stop().
controller.start()
// ...
controller.stop()
¿Cuándo debo iniciar y detener el servicio de Camo?
Hemos diseñado CamoProducerKit para que use el mínimo de recursos posible en todo momento. Sin embargo, mantener el servicio en ejecución para facilitar las conexiones con Camo Studio seguirá consumiendo algunos recursos.
Para ofrecer la mejor experiencia de usuario, recomendamos mantener el servicio de Camo activado en todo momento. Como alternativa, durante el onboarding puedes informar a los usuarios sobre tu integración con Camo y darles la opción de elegir por sí mismos.
Si necesitas liberar estos recursos, detener el servicio de Camo puede ayudar. No recomendamos hacerlo sin notificar al usuario.
Este código es un comienzo, pero todavía no puede aceptar nuevas conexiones de Camo Studio.
Responder a nuevas conexiones
Antes de que tu aplicación pueda aceptar nuevas conexiones de Camo Studio, deberás implementar CamoControllerDelegate. Al implementar estos dos métodos delegados, puedes recibir notificaciones sobre los cambios en el estado de la conexión y decidir si aceptas o rechazas una conexión.
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)
}
}
Con esto hecho, ya deberías poder abrir tu aplicación, conectarte por USB y ver tu dispositivo en Camo Studio.
Conexiones inalámbricas
Para usar conexiones inalámbricas, los usuarios deberán conceder acceso a la red local. Los servicios Bonjour deben añadirse como NSBonjourServices en Info.plist:
_camo._tcp_camopairing._tcp
Cuando llamas a camoController.start(), el SDK está listo para el emparejamiento y para establecer conexiones de red con Camo Studio.
Emparejamiento
Cuando un usuario hace clic en el botón «+» en Camo Studio, comienza el proceso de emparejamiento. Camo Studio muestra un código QR que debe escanearse desde la aplicación.
Pasos para el emparejamiento:
- Haz clic en «+» en Camo Studio para mostrar el código QR
- Escanea el código QR y obtén sus datos como una cadena de texto
- Pasa esos datos al SDK llamando a
camoController.pairStudioWithQRCodeData(codeData) { success in } - El método
pairStudioWithQRCodeDatatiene un callback que te indicará si el emparejamiento se realizó correctamente - El SDK realizará el emparejamiento con Camo Studio y la conexión se establecerá automáticamente.
Si necesitas cancelar el emparejamiento (por ejemplo, si el usuario cerró el escáner de QR o la aplicación), debes llamar a camoController.cancelPairing()
El emparejamiento tiene un tiempo de espera de 30 segundos. El callback del método pairStudioWithQRCodeData se llamará con el valor success false si el emparejamiento no se produce en los 30 segundos posteriores a llamar a pairStudioWithQRCodeData.
Dispositivos emparejados
Una vez completado el emparejamiento, el SDK guardará los datos del emparejamiento en la lista de dispositivos emparejados. CamoController tiene 2 métodos para trabajar con esa lista:
pairedDevicespara obtener la lista (si quieres mostrarla en la interfaz de usuario)removePairedDevicepara olvidar el dispositivo
Para establecer la conexión inalámbrica con Camo Studio la próxima vez, haz clic en el botón «+» en Camo Studio y espera hasta que se establezca la conexión; no es necesario volver a escanear el código QR.
Determinar el estado de la conexión
CamoController proporciona una propiedad CamoControllerState, que también se incluye en el método delegado de cambio de estado como se ha visto anteriormente. Este enum proporciona información útil para tu aplicación, como el nombre del equipo conectado para mostrarlo en la interfaz de usuario.
Aquí tienes un ejemplo de cómo podrías actualizar tu interfaz de usuario para reflejar el estado de la conexión:
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
}
}
Enviar datos audiovisuales
Para ofrecer a los clientes la máxima flexibilidad posible, el Camo SDK no proporciona ni controla ninguna captura. En su lugar, tú eres responsable de proporcionar a CamoController los datos de audio y vídeo. Esto se puede hacer con dos sencillas llamadas a la 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)
Evitar el procesamiento innecesario
Antes de procesar cualquier dato audiovisual para proporcionarlo al Camo SDK, debes asegurarte de que hay una conexión activa y no pausada, para evitar un consumo innecesario de recursos. Puedes hacerlo comprobando state en el CamoController.
Enviar vídeo
Si tienes acceso a un CMSampleBuffer en tu pipeline de vídeo, es trivial pasar estos datos al Camo SDK.
Por eso, configurar esto con un AVCaptureSession de vídeo básico es extremadamente sencillo. Aquí tienes un ejemplo de cómo funciona.
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)
}
}
Al enviar fotogramas de vídeo, asegúrate de que:
- La duración del fotograma es de 30 FPS.
- El formato de píxel es
kCVPixelFormatType_32BGRA.
Puedes consultar más detalles en la referencia de la API.
Enviar audio
Enviar audio es similar a enviar vídeo, pero puede requerir algunos pasos más según cómo lo reciba tu aplicación. Para ver una implementación de ejemplo, consulta la aplicación de demostración incluida con el Camo SDK.
Al enviar datos de audio, asegúrate de que:
- Tu frecuencia de muestreo es de 48 kHz.
- El códec de audio es LPCM.
- El número de canales es 2.
- La profundidad de bits es de 32.
- El número de muestras por paquete de audio depende de Studio (macOS o Windows); puedes obtenerlo de CamoController.audioSamplesRequired.
Puedes consultar más detalles en la referencia de la API.