Inicializando a captura
Neste exemplo, o aplicativo utiliza um capturador de vídeo personalizado para exibir pixels aleatórios (ruído branco). Isso é feito simplesmente para ilustrar os princípios básicos da configuração de um capturador de vídeo personalizado.
Em geral VonageVideoManager, depois de ligar para session.publish(publisher, error: &error) para iniciar a transmissão de um fluxo de áudio e vídeo, o videoCapture propriedade do OTPublisher o objeto é definido como uma instância de BasicVideoCapturer:
publisher.videoCapture = BasicVideoCapturer()
BasicVideoCapturer é uma classe personalizada que implementa a OTVideoCapture protocolo (definido no SDK da Vonage para iOS). Esse protocolo permite definir um capturador de vídeo personalizado para ser usado por um editor do OpenTok.
O initCapture O método inicializa as configurações de captura a serem utilizadas pelo capturador de vídeo personalizado. Na implementação personalizada deste exemplo de OTVideoCapture (OTKBasicVideoCapturer), o initCapture O método define as propriedades do videoFormat propriedade:
func initCapture() {
let format = OTVideoFormat()
format.pixelFormat = .ARGB
format.bytesPerRow = [NSNumber(value: imageWidth * 4)]
format.imageHeight = imageHeight
format.imageWidth = imageWidth
self.videoFormat = format
}
O OTVideoFormat A classe é definida pelo SDK da Vonage para iOS. Neste código de exemplo, o formato do capturador de vídeo está configurado para usar ARGB como formato de pixel, com um número específico de bytes por linha, altura e largura.
O videoCaptureConsumer A propriedade define um OTVideoCaptureConsumer objeto que o consumidor de vídeo utiliza para transmitir quadros de vídeo para o fluxo do editor. Em BasicVideoCapturer, essa propriedade é sintetizada a partir do protocolo:
var videoCaptureConsumer: OTVideoCaptureConsumer?
Iniciando a captura
O start O método é chamado quando um emissor começa a capturar vídeo para enviá-lo como um stream para a sessão da Vonage. Isso ocorrerá após o Session.publish(_:error:) método é chamado. No BasicVideoCapturer, esse método aciona produceFrame em uma fila de segundo plano:
//
// 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
}
Personalização da moldura
O produceFrame O método gera um OTVideoFrame objeto que representa um quadro de vídeo. Nesse caso, o quadro contém pixels aleatórios que preenchem a altura e a largura 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()
}
}
}
O método passa o quadro para o consumeFrame método do OTVideoCaptureConsumer. Isso faz com que o editor envie o quadro de dados para o fluxo de vídeo na sessão.
Captura básica de vídeo
Saiba como configurar um capturador de vídeo básico usando o SDK de vídeo da Vonage.