Renderização personalizada de vídeo (iOS)

Visão geral

Este tutorial explica as etapas necessárias para fazer pequenas modificações no renderizador de vídeo utilizado por um objeto OTPublisher. Você também pode usar as mesmas técnicas para modificar o renderizador de vídeo utilizado por um objeto OTSubscriber (embora este exemplo ilustre apenas um renderizador personalizado para um publisher).

Configurando seu projeto

O código desta seção está no Renderizador Básico de Vídeo projeto do repositório opentok-ios-sdk-samples, portanto, se ainda não tiver feito isso, você precisará clonar o repositório em um diretório local — isso pode ser feito usando a linha de comando:

git clone https://github.com/opentok/opentok-ios-sdk-samples.git

Mude para o diretório do projeto Basic Video Renderer:

cd opentok-ios-sdk-samples/Basic-Video-Renderer

Em seguida, instale a dependência do OpenTok:

pod install

Abra o projeto no Xcode para acompanhar o passo a passo.

Explorando o código

Neste exemplo, o aplicativo usa um renderizador de vídeo personalizado para exibir uma versão em preto e branco do vídeo do objeto OTPublisher.

No ViewController principal, após inicializar o objeto OTPublisher, o videoRender A propriedade do objeto OTPublisher está definida como uma instância de OTKBasicVideoRender:

_publisher = [[OTPublisher alloc] initWithDelegate:self settings:settings];
_renderer = [[OTKBasicVideoRender alloc] init];
_publisher.videoRender = _renderer;

OTKBasicVideoRender é uma classe personalizada que implementa o protocolo OTVideoRender (definido no SDK do OpenTok para iOS). Esse protocolo permite definir um renderizador de vídeo personalizado a ser utilizado por um emissor ou assinante do OpenTok.

O [OTKBasicVideoRender init:] O método define um _renderView propriedade a um objeto UIView. Esse é o objeto UIView que conterá a visualização a ser renderizada (pelo editor ou pelo assinante). Neste exemplo, o objeto UIView é definido pela classe personalizada OTKCustomRenderView, que estende UIView:

- (id)init
{
    self = [super init];
    if (self) {
        _renderView = [[OTKCustomRenderView alloc] initWithFrame:CGRectZero];
    }
    return self;
}

A classe OTKCustomRenderView inclui métodos (que serão abordados mais adiante) que convertem um quadro de vídeo em uma representação em preto e branco.

O método [OTVideoRender renderVideoFrame:] é chamado quando o editor (ou assinante) renderiza um quadro de vídeo para o renderizador de vídeo. O quadro é um objeto OTVideoFrame (definido pelo SDK do OpenTok para iOS). Na implementação desse método pelo OTKCustomRenderView, ele simplesmente recebe o quadro e o repassa para o [renderVideoFrame] método do objeto OTKCustomRenderView:

- (void)renderVideoFrame:(OTVideoFrame*) frame
{
    [(OTKCustomRenderView*)self.renderView renderVideoFrame:frame];
}

O [OTKCustomRenderView renderVideoFrame] O método percorre os pixels do plano, ajusta cada pixel para um valor em preto e branco e adiciona esse valor a um buffer. Em seguida, ele grava o buffer em um CGImageRef que representa a imagem da vista e chama [self setNeedsDisplay] para renderizar a visualização da imagem:

- (void)renderVideoFrame:(OTVideoFrame *)frame
{
    __block OTVideoFrame *frameToRender = frame;
    dispatch_sync(self.renderQueue, ^{
        if (_img != NULL) {
            CGImageRelease(_img);
            _img = NULL;
        }

        size_t bufferSize = frameToRender.format.imageHeight
          * frameToRender.format.imageWidth * 3;
        uint8_t *buffer = malloc(bufferSize);

        uint8_t *yplane = [frameToRender.planes pointerAtIndex:0];

        for (int i = 0; i < frameToRender.format.imageHeight; i++) {
            for (int j = 0; j < frameToRender.format.imageWidth; j++) {
                int starting = (i * frameToRender.format.imageWidth * 3) + (j * 3);
                uint8_t yvalue = yplane[(i * frameToRender.format.imageWidth) + j];
                // If in a RGB image we copy the same Y value for R, G and B
                // we will obtain a Black & White image
                buffer[starting] = yvalue;
                buffer[starting+1] = yvalue;
                buffer[starting+2] = yvalue;
            }
        }

        CGDataProviderRef imgProvider = CGDataProviderCreateWithData(NULL,
                                                                     buffer,
                                                                     bufferSize,
                                                                     release_frame);

        _img = CGImageCreate(frameToRender.format.imageWidth,
                             frameToRender.format.imageHeight,
                             8,
                             24,
                             3 * frameToRender.format.imageWidth,
                             CGColorSpaceCreateDeviceRGB(),
                             kCGBitmapByteOrder32Big | kCGImageAlphaNone,
                             imgProvider,
                             NULL,
                             false,
                             kCGRenderingIntentDefault);


        CGDataProviderRelease(imgProvider);
        dispatch_async(dispatch_get_main_queue(), ^{
            [self setNeedsDisplay];
        });
    });
}

Parabéns! Você concluiu o tutorial sobre renderização personalizada de vídeo para iOS.
Você pode continuar experimentando e ajustando o código que desenvolveu aqui, ou conferir o Próximos passos abaixo.

Próximos passos

Quando terminar esta seção, continue desenvolvendo e aprimorando seu aplicativo OpenTok com estes recursos úteis: