https://d226lax1qjow5r.cloudfront.net/blog/blogposts/vonage-video-media-processor-released-for-ios-android-and-more/video-media-processor.png

¡Lanzamiento del procesador de medios de Video de Vonage para iOS, Android y más!

Publicado el August 28, 2023

Tiempo de lectura: 2 minutos

La Video Media Processor API ya está disponible en todas las plataformas nativas compatibles (iOS, Android, Windows y macOS), lo que permite añadir transformaciones personalizadas a los vídeos publicados.

En el pasado, hemos hablado de cómo podemos utilizar esta funcionalidad en el SDK de JavaScript para crear efectos como desenfoque de fondo y aplicar fondo virtual pero veamos ahora cómo podemos crear un transformador personalizado en Android e iOS para añadir una imagen superpuesta a la señal de vídeo.

Transformadores a medida

Junto con el lanzamiento de esta función, también tenemos una nueva guía para desarrolladores que muestra cómo utilizar el procesador multimedia para crear un efecto de desenfoque de fondo y otras transformaciones personalizadas.. Sin embargo, echemos un vistazo a cómo podemos crear un efecto personalizado en Android e iOS.

Android

Antes de empezar, asegúrese de haber seguido la guía de inicio y de tener configurada una aplicación básica de videochat con un objeto Publisher creado.

Crear una clase que implemente el método PublisherKit.CustomVideoTransformer personalizada. Implemente el método PublisherKit.CustomVideoTransformer.onTransform​(BaseVideoRenderer.Frame frame) método El método PublisherKit.CustomVideoTransformer.onTransform​(BaseVideoRenderer.Frame frame) se activa para cada fotograma de vídeo. En la implementación del método, aplique una transformación al objeto de fotograma pasado al método:

public class MyCustomTransformer implements PublisherKit.CustomVideoTransformer {
    @Override
    public void onTransform(BaseVideoRenderer.Frame frame) {
         // Your custom transformation
    }
}

Si quisiéramos añadir, por ejemplo, una imagen encima del vídeo para que actuara como logotipo o marca de agua, podríamos hacerlo:

public class MyCustomTransformer implements PublisherKit.CustomVideoTransformer {
        public Bitmap resizeImage(Bitmap image, int width, int height) {
            return Bitmap.createScaledBitmap(image, width, height, true);
        }

        @Override
        public void onTransform(BaseVideoRenderer.Frame frame){

            // Obtain the Y plane of the video frame
            ByteBuffer yPlane = frame.getYplane();

            // Get the dimensions of the video frame
            int videoWidth = frame.getWidth();
            int videoHeight = frame.getHeight();

            // Calculate the desired size of the image
            int desiredWidth = videoWidth / 8; // Adjust this value as needed
            int desiredHeight = (int) (image.getHeight() * ((float) desiredWidth / image.getWidth()));

            // Resize the image to the desired size
            image = resizeImage(image, desiredWidth, desiredHeight);

            int logoWidth = image.getWidth();
            int logoHeight = image.getHeight();

            // Location of the image (center of video)
            int logoPositionX = videoWidth * 1/2 - logoWidth; // Adjust this as needed for the desired position
            int logoPositionY = videoHeight * 1/2 - logoHeight; // Adjust this as needed for the desired position

            // Overlay the logo on the video frame
            for (int y = 0; y < logoHeight; y++) {
                for (int x = 0; x < logoWidth; x++) {
                    int frameOffset = (logoPositionY + y) * videoWidth + (logoPositionX + x);

                    // Get the logo pixel color
                    int logoPixel = image.getPixel(x, y);

                    // Extract the color channels (ARGB)
                    int logoAlpha = (logoPixel >> 24) & 0xFF;
                    int logoRed = (logoPixel >> 16) & 0xFF;

                    // Overlay the logo pixel on the video frame
                    int framePixel = yPlane.get(frameOffset) & 0xFF;

                    // Calculate the blended pixel value
                    int blendedPixel = ((logoAlpha * logoRed + (255 - logoAlpha) * framePixel) / 255) & 0xFF;

                    // Set the blended pixel value in the video frame
                    yPlane.put(frameOffset, (byte) blendedPixel);
                }
            }
        }
}

A continuación, pase el objeto que implementa la interfaz PublisherKit.CustomVideoTransformer al método PublisherKit.setVideoTransformers() al método

MyCustomTransformer transformer = new MyCustomTransformer();
ArrayList<PublisherKit.VideoTransformer> videoTransformers = new ArrayList<>();
videoTransformers.add(transformer);
mPublisher.setVideoTransformers(videoTransformers);

Puedes combinar el transformador de la biblioteca Vonage Media (consulta la sección anterior) con transformadores personalizados o aplicar varios transformadores personalizados añadiendo varios objetos PublisherKit.VideoTransformer a la lista ArrayList que se pasa al método PublisherKit.setVideoTransformers() método

A continuación, pase el objeto que implementa la interfaz PublisherKit.CustomAudioRransformer al método PublisherKit.setAudioTransformers() método

MyCustomAudioTransformer transformer = new MyCustomAudioTransformer();
ArrayList<PublisherKit.VideoTransformer> audioTransformers = new ArrayList<>();
audioTransformers.add(transformer);
mPublisher.setAudioTransformers(audioTransformers);

Puede aplicar varios transformadores personalizados añadiendo varios objetos PublisherKit.AudioTransformer a la ArrayList que se pasa al método PublisherKit.setAudioTransformers() método

iOS

Antes de empezar, asegúrese de haber seguido la guía de inicio y tener una aplicación básica de videochat configurada con un objeto OTPublisher creado.

Crear una clase que implemente el método OTCustomVideoTransformer de OTCustomVideoTransformer. Implementa el método [OTCustomVideoTransformer transform:] aplicando una transformación al objeto OTVideoFrame pasado al método. El método [OTCustomVideoTransformer transform:] se activa para cada fotograma de vídeo:

@interface CustomTransformer : NSObject <OTCustomVideoTransformer>
@end
@implementation CustomTransformer
- (void)transform:(nonnull OTVideoFrame *)videoFrame {
    // Your custom transformation
}
@end

Si quisiéramos añadir, por ejemplo, una imagen en la parte superior del Video que actuara como logo o marca de agua podríamos hacerlo:

@interface CustomTransformer : NSObject <OTCustomVideoTransformer>
@end
@implementation CustomTransformer
- (void)transform:(nonnull OTVideoFrame *)videoFrame {
    
    UIImage* image = [UIImage imageNamed:@"Vonage_Logo.png"];

    uint32_t videoWidth = videoFrame.format.imageWidth;
    uint32_t videoHeight = videoFrame.format.imageHeight;

    // Calculate the desired size of the image
    CGFloat desiredWidth = videoWidth / 8;  // Adjust this value as needed
    CGFloat desiredHeight = image.size.height * (desiredWidth / image.size.width);

    // Resize the image to the desired size
    UIImage *resizedImage = [self resizeImage:image toSize:CGSizeMake(desiredWidth, desiredHeight)];

    // Get pointer to the Y plane
    uint8_t* yPlane = [videoFrame getPlaneBinaryData:0];
    
    // Create a CGContext from the Y plane
    CGContextRef context = CGBitmapContextCreate(yPlane, videoWidth, videoHeight, 8, videoWidth, CGColorSpaceCreateDeviceGray(), kCGImageAlphaNone);
    
    // Location of the image (in this case right bottom corner)
    CGFloat x = videoWidth * 4/5;
    CGFloat y = videoHeight * 1/5;
    
    // Draw the resized image on top of the Y plane
    CGRect rect = CGRectMake(x, y, desiredWidth, desiredHeight);
    CGContextDrawImage(context, rect, resizedImage.CGImage);
    
    CGContextRelease(context);
}
@end

A continuación, establezca la propiedad OTPublisherKit.videoTransformers a un array que incluya el objeto que implementa la interfaz OTCustomVideoTransformer:

CustomTransformer* logoTransformer;
logoTransformer = [customTransformer alloc];
OTVideoTransformer *myCustomTransformer = [[OTVideoTransformer alloc] initWithName:@"logo" transformer:logoTransformer];

NSMutableArray * myVideoTransformers = [[NSMutableArray alloc] init];
[myVideoTransformers addObject:myCustomTransformer];

_publisher.videoTransformers = [[NSArray alloc] initWithArray:myVideoTransformers];

Puede combinar el transformador de la biblioteca Vonage Media (consulte la sección anterior) con transformadores personalizados o aplicar varios transformadores personalizados añadiendo varios objetos PublisherKit.VideoTransformer a la ArrayList utilizada para la propiedad OTPublisherKit.videoTransformers propiedad.

Ejemplos de aplicaciones

¿Busca una muestra más completa para probar y experimentar? No se preocupe. Disponemos de ejemplos de aplicaciones que muestran el procesador multimedia para las siguientes plataformas:

Cuéntanos qué estás construyendo con el procesador de medios de video de Vonage. Chatea con nosotros en nuestro Slack de la comunidad de Vonage o envíanos un mensaje en X, antes conocido como Twitter.

Compartir:

https://a.storyblok.com/f/270183/400x400/04765919bb/zachary-powell-1.png
Zachary PowellDesarrollador Android principal