Inicialización de la captura
En este ejemplo, la aplicación utiliza un capturador de vídeo personalizado para publicar píxeles aleatorios (ruido blanco). Esto se hace simplemente para ilustrar los principios básicos de la configuración de un capturador de vídeo personalizado.
En el principal VonageVideoManagerdespués de llamar a session.publish(publisher, error: &error) para iniciar la publicación de un flujo de audio-vídeo, el videoCapture propiedad del OTPublisher se establece en una instancia de BasicVideoCapturer:
publisher.videoCapture = BasicVideoCapturer()
BasicVideoCapturer es una clase personalizada que implementa la función OTVideoCapture (definido en el SDK de Vonage para iOS). Este protocolo te permite definir una capturadora de vídeo personalizada para que la utilice un editor de OpenTok.
El initCapture inicializa la configuración de captura que utilizará el capturador de vídeo personalizado. En la implementación personalizada de OTVideoCapture (OTKBasicVideoCapturer), el initCapture establece las propiedades del método videoFormat propiedad:
func initCapture() {
let format = OTVideoFormat()
format.pixelFormat = .ARGB
format.bytesPerRow = [NSNumber(value: imageWidth * 4)]
format.imageHeight = imageHeight
format.imageWidth = imageWidth
self.videoFormat = format
}
El OTVideoFormat La clase está definida por el SDK de Vonage para iOS. En este código de ejemplo, el formato del capturador de vídeo se configura para utilizar ARGB como formato de píxeles, con un número específico de bytes por fila, altura y anchura.
El videoCaptureConsumer establece una propiedad OTVideoCaptureConsumer objeto que el consumidor de vídeo utiliza para transmitir fotogramas de vídeo a la transmisión del editor. En BasicVideoCaptureresta propiedad se sintetiza a partir del protocolo:
var videoCaptureConsumer: OTVideoCaptureConsumer?
Captura inicial
El start El método se invoca cuando un emisor comienza a grabar vídeo para enviarlo como transmisión a la sesión de Vonage. Esto ocurrirá después de que el Session.publish(_:error:) . En el BasicVideoCapturer, este método activa produceFrame en una cola de fondo:
//
// returns:
// - a negative value for error
// - 0 value when all is OK
//
func start() -> Int32 {
self.captureStarted = true
// Start the frame loop on a background queue
DispatchQueue.global(qos: .background).asyncAfter(deadline: timerInterval) { [weak self] in
self?.produceFrame()
}
return 0
}
Personalización del marco
El produceFrame El método genera un OTVideoFrame objeto que representa un fotograma de vídeo. En este caso, el fotograma contiene píxeles aleatorios que ocupan la altura y la anchura definidas:
private func produceFrame() {
guard let format = self.videoFormat else { return }
let frame = OTVideoFrame(format: format)
// Allocate buffer for image data
let bufferSize = Int(imageWidth * imageHeight * 4)
let buffer = UnsafeMutablePointer<UInt8>.allocate(capacity: bufferSize)
// Generate random pixels
for i in stride(from: 0, to: bufferSize, by: 4) {
buffer[i] = UInt8.random(in: 0...255) // A
buffer[i + 1] = UInt8.random(in: 0...255) // R
buffer[i + 2] = UInt8.random(in: 0...255) // G
buffer[i + 3] = UInt8.random(in: 0...255) // B
}
// Pass pointer to Vonage
var planePointer: UnsafeMutablePointer<UInt8> = buffer
withUnsafeMutablePointer(to: &planePointer) { pointerToPlanePointer in
frame.setPlanesWithPointers(UnsafeMutableRawPointer(pointerToPlanePointer).assumingMemoryBound(to: UnsafeMutablePointer<UInt8>.self), numPlanes: 1)
}
// Send frame to consumer
self.videoCaptureConsumer?.consumeFrame(frame)
buffer.deallocate()
if self.captureStarted {
DispatchQueue.global(qos: .background).asyncAfter(deadline: timerInterval) { [weak self] in
self?.produceFrame()
}
}
}
El método pasa el marco al consumeFrame método del OTVideoCaptureConsumer. Esto hace que el editor envíe el fotograma de datos al flujo de vídeo de la sesión.
Captura de vídeo básica
Descubre cómo configurar un capturador de vídeo básico utilizando el SDK de vídeo de Vonage.