Search Docs
Loading...
Skip to content

Redact Sensitive Content in Videos

Redact sensitive video content using blur, pixelization, or solid overlays for privacy protection.

12 mins
estimated time
GitHub

The Android Video Editor starter kit is the recommended starting point for UI-based video editing workflows. Use the Engine APIs in this guide when you need to prepare redacted video content programmatically, automate privacy edits, or apply redactions before export.

CE.SDK applies effects to blocks themselves, not as overlays affecting content beneath. This means full-block redaction applies the effect directly to the video block, while partial redaction uses a duplicated video block that is resized and positioned as a bounded patch. Crop values align the duplicate’s source pixels with the original video inside that patch.

This guide covers the built-in Android editor controls for blur and pixelization, then shows how to create full-block, partial, solid, and time-based redactions programmatically with the CreativeEngine.

Understanding Redaction in CE.SDK#

How Effects Work#

Effects in CE.SDK modify the block’s appearance directly rather than creating transparent overlays that affect content beneath. When you blur a video block, the entire block becomes blurred.

Choosing a Redaction Technique#

Select your technique based on privacy requirements and visual impact:

  • Full-block blur: Complete obscuration for backgrounds or placeholder content
  • Partial blur: A duplicated video patch that is resized, positioned, blurred, and crop-aligned over one sensitive region
  • Radial blur: Circular blur patterns that keep a focus region clear while obscuring surrounding content
  • Pixelization: Clearly intentional censoring that is faster to render than heavy blur
  • Solid overlays: Complete blocking for highly sensitive information like documents or credentials

Using the Built-in UI#

Accessing Blur Controls#

In the Android editor, select a video block and open the blur controls from the block options. The editor exposes blur presets such as uniform, radial, linear, and mirrored blur, with adjustment controls for the selected blur type.

Uniform blur applies consistent intensity across the entire block. Higher intensity creates stronger privacy protection but increases rendering work.

Accessing Pixelization Controls#

Select a video block, open the effects controls, and choose the pixelize effect. Adjust the horizontal and vertical pixel sizes to control the mosaic block dimensions.

Larger pixel sizes create stronger obscuration but are more visually disruptive. Values between 15 and 30 pixels work well for standard redaction scenarios.

Creating Partial Redactions#

For face, license-plate, or screen-detail redaction, duplicate the original video block first. Apply blur or pixelization to the duplicate, resize and position its frame over the sensitive region, then adjust crop values so the duplicate shows the same source area as the original underneath.

Programmatic Redaction#

Full-Block Blur#

When the entire video needs obscuring, apply blur directly to the original block without duplication. Check that the block supports blur, create a uniform blur, configure its intensity, attach it to the video block, and enable it.

if (engine.block.supportsBlur(fullBlurVideo)) {
val uniformBlur = engine.block.createBlur(type = BlurType.Uniform)
engine.block.setFloat(
block = uniformBlur,
property = "blur/uniform/intensity",
value = 0.7F,
)
engine.block.setBlur(block = fullBlurVideo, blurBlock = uniformBlur)
engine.block.setBlurEnabled(block = fullBlurVideo, enabled = true)
}

The uniform blur intensity ranges from 0.0 to 1.0. Higher values create stronger blur.

Partial Blur#

When only one region needs obscuring, duplicate the original video block and apply blur to the duplicate. Then resize and position the duplicate as the redaction rectangle, and use crop scale and translation values to keep the source pixels aligned with the original video.

val partialBlurRedaction = engine.block.duplicate(block = partialBlurVideo)
if (
engine.block.supportsBlur(partialBlurRedaction) &&
engine.block.supportsCrop(partialBlurRedaction)
) {
val redactionX = PAGE_WIDTH * 0.22F
val redactionY = PAGE_HEIGHT * 0.18F
val redactionWidth = PAGE_WIDTH * 0.35F
val redactionHeight = PAGE_HEIGHT * 0.28F
val cropBlur = engine.block.createBlur(type = BlurType.Uniform)
engine.block.setFloat(
block = cropBlur,
property = "blur/uniform/intensity",
value = 0.75F,
)
engine.block.setBlur(block = partialBlurRedaction, blurBlock = cropBlur)
engine.block.setBlurEnabled(block = partialBlurRedaction, enabled = true)
engine.block.setWidth(block = partialBlurRedaction, value = redactionWidth)
engine.block.setHeight(block = partialBlurRedaction, value = redactionHeight)
engine.block.setPositionX(block = partialBlurRedaction, value = redactionX)
engine.block.setPositionY(block = partialBlurRedaction, value = redactionY)
// The smaller frame bounds the redaction; crop keeps its source pixels aligned.
engine.block.setCropScaleX(block = partialBlurRedaction, scaleX = PAGE_WIDTH / redactionWidth)
engine.block.setCropScaleY(block = partialBlurRedaction, scaleY = PAGE_HEIGHT / redactionHeight)
engine.block.setCropTranslationX(
block = partialBlurRedaction,
translationX = -redactionX / redactionWidth,
)
engine.block.setCropTranslationY(
block = partialBlurRedaction,
translationY = -redactionY / redactionHeight,
)
partialBlurEnabled = engine.block.isBlurEnabled(partialBlurRedaction)
}

duplicate() keeps the copy on top of the original block. The duplicate’s frame bounds the visible redaction area; crop scale and translation align the duplicated video content inside that smaller frame. The same bounded-duplicate workflow also works with pixelization.

Pixelization#

Pixelization creates a mosaic effect that is clearly intentional. Use the effect system rather than the blur system for pixelization.

if (engine.block.supportsEffects(pixelVideo)) {
val pixelizeEffect = engine.block.createEffect(type = EffectType.Pixelize)
engine.block.setInt(
block = pixelizeEffect,
property = "effect/pixelize/horizontalPixelSize",
value = 24,
)
engine.block.setInt(
block = pixelizeEffect,
property = "effect/pixelize/verticalPixelSize",
value = 24,
)
engine.block.appendEffect(block = pixelVideo, effectBlock = pixelizeEffect)
engine.block.setEffectEnabled(effectBlock = pixelizeEffect, enabled = true)
pixelizationEnabled = engine.block.isEffectEnabled(pixelizeEffect)
}

Check supportsEffects() before creating the pixelize effect. The horizontal and vertical pixel sizes control the mosaic block dimensions.

Solid Overlays#

For complete blocking without any visual hint of the underlying content, create an opaque shape overlay. This approach does not require video block duplication.

val overlay = engine.block.create(DesignBlockType.Graphic)
val rectShape = engine.block.createShape(type = ShapeType.Rect)
engine.block.setShape(block = overlay, shape = rectShape)
val solidFill = engine.block.createFill(fillType = FillType.Color)
engine.block.setColor(
block = solidFill,
property = "fill/color/value",
value = Color.fromRGBA(r = 0.1F, g = 0.1F, b = 0.1F, a = 1.0F),
)
engine.block.setFill(block = overlay, fill = solidFill)
engine.block.setWidth(overlay, value = PAGE_WIDTH * 0.4F)
engine.block.setHeight(overlay, value = PAGE_HEIGHT * 0.3F)
engine.block.setPositionX(overlay, value = PAGE_WIDTH * 0.55F)
engine.block.setPositionY(overlay, value = PAGE_HEIGHT * 0.65F)
engine.block.appendChild(parent = page, child = overlay)

The overlay uses absolute page coordinates for positioning. Set the alpha channel to 1.0 for complete opacity.

Time-Based Redaction#

Redactions can appear only during specific portions of the video. Use a separate redaction layer, then call setTimeOffset() and setDuration() on that layer so the source video timing stays intact.

val timedRedaction = engine.block.create(DesignBlockType.Graphic)
engine.block.setShape(
block = timedRedaction,
shape = engine.block.createShape(type = ShapeType.Rect),
)
val timedFill = engine.block.createFill(fillType = FillType.Color)
engine.block.setColor(
block = timedFill,
property = "fill/color/value",
value = Color.fromRGBA(r = 0.05F, g = 0.05F, b = 0.05F, a = 1.0F),
)
engine.block.setFill(block = timedRedaction, fill = timedFill)
engine.block.setWidth(timedRedaction, value = PAGE_WIDTH * 0.35F)
engine.block.setHeight(timedRedaction, value = PAGE_HEIGHT * 0.22F)
engine.block.setPositionX(timedRedaction, value = PAGE_WIDTH * 0.32F)
engine.block.setPositionY(timedRedaction, value = PAGE_HEIGHT * 0.24F)
engine.block.setTimeOffset(timedRedaction, offset = 4 * SEGMENT_DURATION)
engine.block.setDuration(timedRedaction, duration = SEGMENT_DURATION)
engine.block.appendChild(parent = page, child = timedRedaction)

The time offset specifies when the overlay appears in seconds from the start of its parent timeline, and the duration controls how long it remains visible. If you need blurred or pixelized partial redaction instead of an opaque block, use the same timing pattern on a bounded duplicate video layer.

Radial Blur#

Radial blur keeps the center region unblurred and increases blur outside that focus area. Use it when the content to protect is around the focus region, not when the sensitive subject is centered. To obscure a centered face, license plate, or document area, use pixelization, uniform blur on a duplicate crop, or a solid overlay.

if (engine.block.supportsBlur(radialVideo)) {
val radialBlur = engine.block.createBlur(type = BlurType.Radial)
// Radial blur leaves the radius clear; use it to protect content outside that focus area.
engine.block.setFloat(radialBlur, property = "blur/radial/blurRadius", value = 50F)
engine.block.setFloat(radialBlur, property = "blur/radial/radius", value = 75F)
engine.block.setFloat(radialBlur, property = "blur/radial/gradientRadius", value = 80F)
engine.block.setFloat(radialBlur, property = "blur/radial/x", value = 0.5F)
engine.block.setFloat(radialBlur, property = "blur/radial/y", value = 0.45F)
engine.block.setBlur(block = radialVideo, blurBlock = radialBlur)
engine.block.setBlurEnabled(block = radialVideo, enabled = true)
}

Radial blur properties control the focus center (x, y from 0.0 to 1.0), the unblurred center area (radius from 0.0 to 100.0), the blur transition zone (gradientRadius from 0.0 to 100.0), and the blur strength outside the focus region (blurRadius from 0.0 to 100.0).

Performance Considerations#

Different redaction techniques have different performance impacts:

  • Solid overlays: Minimal impact, and you can create many without significant overhead
  • Pixelization: Faster than blur, with larger pixel sizes adding little extra work
  • Blur effects: Higher intensity and radius values increase rendering time

For complex scenes with multiple redactions, use solid overlays where blur is not necessary, or reduce blur intensity to maintain smooth processing.

Troubleshooting#

Redaction Not Visible#

If your redaction does not appear, verify that:

  • The overlay is attached to the page with appendChild()
  • Blur is enabled with setBlurEnabled() after assigning it with setBlur()
  • Effects are enabled with setEffectEnabled() after appending them with appendEffect()
  • Partial redactions resize and position the duplicate frame before using crop values for source alignment

Performance Issues#

Reduce blur intensity, use pixelization instead of heavy blur, or switch to solid overlays for redactions that do not need the underlying content to remain recognizable.

Best Practices#

  • Preview thoroughly: Scrub the timeline to verify that all sensitive content is covered.
  • Add safety margins: Make redaction regions slightly larger than the sensitive area.
  • Test at export resolution: Higher resolutions may need stronger blur or larger pixel sizes.
  • Archive originals: Exported redactions are permanent and cannot be reversed.

API Reference#

MethodDescription
engine.block.supportsBlur(block=_)Check whether a block supports blur
engine.block.createBlur(type=BlurType.Uniform)Create a blur block
engine.block.setFloat(block=_, property="blur/uniform/intensity", value=_)Set the uniform blur intensity
engine.block.setFloat(block=_, property="blur/radial/blurRadius", value=_)Set the radial blur strength outside the focus region
engine.block.setFloat(block=_, property="blur/radial/radius", value=_)Set the unblurred center radius for radial blur
engine.block.setFloat(block=_, property="blur/radial/gradientRadius", value=_)Set the radial blur transition radius
engine.block.setFloat(block=_, property="blur/radial/x", value=_)Set the radial blur center x coordinate
engine.block.setFloat(block=_, property="blur/radial/y", value=_)Set the radial blur center y coordinate
engine.block.setBlur(block=_, blurBlock=_)Apply a blur block to a design block
engine.block.setBlurEnabled(block=_, enabled=_)Enable or disable a block’s blur
engine.block.duplicate(block=_, attachToParent=_)Duplicate a video block for partial redaction
engine.block.supportsCrop(block=_)Check whether a block supports crop properties
engine.block.setCropScaleX(block=_, scaleX=_)Scale source video content inside the redaction frame
engine.block.setCropScaleY(block=_, scaleY=_)Scale source video content inside the redaction frame
engine.block.setCropTranslationX(block=_, translationX=_)Align the source content horizontally inside the redaction frame
engine.block.setCropTranslationY(block=_, translationY=_)Align the source content vertically inside the redaction frame
engine.block.supportsEffects(block=_)Check whether a block supports effects
engine.block.createEffect(type=EffectType.Pixelize)Create an effect block
engine.block.setInt(block=_, property="effect/pixelize/horizontalPixelSize", value=_)Set the horizontal pixelization block size
engine.block.setInt(block=_, property="effect/pixelize/verticalPixelSize", value=_)Set the vertical pixelization block size
engine.block.appendEffect(block=_, effectBlock=_)Add an effect block to a design block
engine.block.setEffectEnabled(effectBlock=_, enabled=_)Enable or disable an effect
engine.block.setTimeOffset(block=_, offset=_)Set when a block appears on its parent timeline
engine.block.setDuration(block=_, duration=_)Set how long a block remains active
engine.block.getDuration(block=_)Read a block’s active duration
engine.block.create(blockType=DesignBlockType.Graphic)Create a graphic block
engine.block.appendChild(parent=_, child=_)Add a block to a scene, page, or parent block
engine.block.createShape(type=ShapeType.Rect)Create a rectangle shape
engine.block.setShape(block=_, shape=_)Apply a shape to a graphic block
engine.block.createFill(fillType=FillType.Color)Create a fill block
engine.block.setFill(block=_, fill=_)Apply a fill to a block
engine.block.setUri(block=_, property="fill/video/fileURI", value=_)Set a video fill source URI
engine.block.setColor(block=_, property="fill/color/value", value=_)Set a color property
engine.block.setWidth(block=_, value=_)Set a block width
engine.block.setHeight(block=_, value=_)Set a block height
engine.block.setPositionX(block=_, value=_)Set a block’s x position
engine.block.setPositionY(block=_, value=_)Set a block’s y position
engine.block.isBlurEnabled(block=_)Check whether blur is enabled on a block
engine.block.isEffectEnabled(effectBlock=_)Check whether an effect block is enabled
engine.block.getTimeOffset(block=_)Read when a block appears on its parent timeline

Next Steps#

  • Create and Edit Shapes - Create shape blocks for solid redaction overlays
  • Transform - Position and resize video blocks before adding redactions
  • Export - Learn export workflows before baking redactions into final media
  • Control Audio and Video - Control timing, duration, and playback for media blocks