Renderización de vídeo personalizada (iOS)

Visión general

Este tutorial explica paso a paso los pasos necesarios para realizar modificaciones menores en el renderizador de vídeo que utiliza un objeto OTPublisher. También puedes utilizar las mismas técnicas para modificar el renderizador de vídeo que utiliza un objeto OTSubscriber (aunque este ejemplo solo ilustra un renderizador personalizado para un editor).

Configuración de tu proyecto

El código de esta sección se encuentra en el Renderizador de vídeo básico proyecto de la Repositorio «opentok-ios-sdk-samples»por lo que, si aún no lo ha hecho, deberá clonar el repositorio en un directorio local. esto se puede hacer utilizando la línea de comandos:

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

Cambia el directorio al proyecto Basic Video Renderer:

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

A continuación, instala la dependencia de OpenTok:

pod install

Abre el proyecto en Xcode para seguir los pasos.

Explorar el código

En este ejemplo, la aplicación utiliza un renderizador de vídeo personalizado para mostrar una versión en blanco y negro del vídeo del objeto OTPublisher.

En el ViewController principal, después de inicializar el objeto OTPublisher, la función videoRender del objeto OTPublisher es una instancia de OTKBasicVideoRender:

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

OTKBasicVideoRender es una clase personalizada que implementa el protocolo OTVideoRender (definido en el SDK de OpenTok para iOS). Este protocolo permite definir un renderizador de vídeo personalizado para que lo utilicen los emisores o suscriptores de OpenTok.

El [OTKBasicVideoRender init:] El método establece un _renderView propiedad a un objeto UIView. Se trata del objeto UIView que contendrá la vista que se va a renderizar (por parte del editor o del suscriptor). En este ejemplo, el objeto UIView viene definido por la clase personalizada OTKCustomRenderView, que hereda de UIView:

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

La clase OTKCustomRenderView incluye métodos (que se explicarán más adelante) que convierten un fotograma de vídeo en una representación en blanco y negro.

El método [OTVideoRender renderVideoFrame:] se invoca cuando el editor (o el suscriptor) representa un fotograma de vídeo en el renderizador de vídeo. El fotograma es un objeto OTVideoFrame (definido por el SDK de OpenTok para iOS). En la implementación de este método por parte de OTKCustomRenderView, simplemente se toma el fotograma y se le pasa al [renderVideoFrame] del objeto OTKCustomRenderView:

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

El [OTKCustomRenderView renderVideoFrame] El método recorre los píxeles del plano, ajusta cada píxel a un valor en blanco y negro y añade dicho valor a un búfer. A continuación, escribe el búfer en un CGImageRef que representa la imagen de la vista y llama a [self setNeedsDisplay] para renderizar la vista de la imagen:

- (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];
        });
    });
}

¡Enhorabuena! Has completado el tutorial sobre renderización de vídeo personalizada para iOS.
Puedes seguir probando y modificando el código que has creado aquí, o echar un vistazo a la Próximos pasos abajo.

Próximos pasos

Cuando hayas terminado aquí, sigue desarrollando y mejorando tu aplicación de OpenTok con estos útiles recursos: