FilterVideoProcessor
The FilterVideoProcessor
is a helper class that simplifies the process of applying visual effects to video streams. It extends the NoDropVideoProcessor
class, providing a convenient way to apply VideoFilter
implementations.
You will need to create a VideoFilter
implementation to use this class and pass an EglBase
instance to the constructor.
We provide two primary VideoFilter
types:
BitmapVideoFilter
, andRawVideoFilter
BitmapVideoFilter
The BitmapVideoFilter
provides a Bitmap of each frame for easy manipulation.
This is less performant than using the RawVideoFilter
because we do YUV to ARGB conversions internally.
Usage Example
This example shows how to create a custom BitmapVideoFilter
that inverts the colors of the video.
class SampleVideoFilter : BitmapVideoFilter() {
override fun applyFilter(bitmap: Bitmap) {
val width = bitmap.width
val height = bitmap.height
for (y in 0 until height) {
for (x in 0 until width) {
val pixel = bitmap[x, y]
val r = 255 - Color.red(pixel)
val g = 255 - Color.green(pixel)
val b = 255 - Color.blue(pixel)
bitmap[x, y] = Color.rgb(r, g, b)
}
}
}
}
RawVideoFilter
The RawVideoFilter
is quite similar to creating a custom VideoProcessor
. It allows you to get frames directly from WebRTC and modify them.
Usage Example
Here's how to implement a RawVideoFilter
that dims the brightness of the video.
class CustomFilter : RawVideoFilter() {
override fun applyFilter(
videoFrame: VideoFrame,
surfaceTextureHelper: SurfaceTextureHelper,
): VideoFrame {
val buffer = videoFrame.buffer
val i420 = buffer.toI420()
if (i420 == null) return videoFrame
val width = i420.width
val height = i420.height
val yPlane = i420.dataY
val yStride = i420.strideY
// Dim brightness: halve all Y (luma) values
for (y in 0 until height) {
for (x in 0 until width) {
val index = y * yStride + x
yPlane.put(index, (yPlane.get(index).toInt() / 2).toByte())
}
}
return VideoFrame(i420, videoFrame.rotation, videoFrame.timestampNs)
}
}
Using the Filter
After creating a VideoFilter
, you can create an instance of FilterVideoProcessor
and pass it down to the RealtimeKitMeetingBuilder
object.
val eglBase = EglBase.create()
// Create the filter which will be used to process the video frames.
val bgFilter = CustomFilter()
// Create the processor that will execute the filter.
val filterProcessor = FilterVideoProcessor(eglBase = eglBase, filter = bgFilter)
val meeting = RealtimeKitMeetingBuilder()
.setVideoProcessor(filterProcessor)
.build(activity)