Anonymize a video by covering one or more fixed rectangular regions with
opaque filled boxes. For example, you can redact a face, a name badge, or a
screen that stays in one place for the whole clip. The regions are fixed
(there is no face or object tracking), so this suits footage where the areas
to cover do not move. The glossary in vignette("tidymedia") explains
media terms such as codec, pixel format and stream copy.
Usage
anonymize_video(
infile,
outfile,
regions,
color = "black",
video_codec = "libx264",
audio_codec = "copy",
pixel_format = "yuv420p",
hardware = c("none", "nvenc", "videotoolbox"),
fallback = FALSE,
quality = NULL,
audio_stream = NULL,
run = TRUE
)Arguments
- infile
A string containing the path to a video file.
- outfile
A string containing the path of the video file to write.
- regions
A data frame with one row per box and columns
x,y,width,height(and optionallycolor); see Details.- color
A string naming the default fill color in FFmpeg color syntax, used for any row without its own
color(default"black").- video_codec
A string naming the output video codec (default
"libx264").NULLemits no-codec:vand lets the output container's default encoder decide.NULLis how you opt out of the H.264 default for a container that does not hold it. For a.webmoutput, passvideo_codec = NULLandaudio_codec = NULL, because the defaultaudio_codec = "copy"would otherwise carry a codec WebM cannot hold.- audio_codec
A string naming the output audio codec. The default
"copy"stream-copies the source audio unchanged. Name a real encoder, such as"aac", when the source audio codec cannot be copied into the output container.NULLemits no-codec:aand lets the container's default encoder decide.- pixel_format
A string naming the output pixel format (default
"yuv420p").- hardware
The encoder backend.
"none"(default) uses the softwarevideo_codec."nvenc"uses NVIDIA GPU encoding (H.264, HEVC and AV1), and"videotoolbox"uses Apple GPU encoding (H.264 and HEVC). A backend uses its own encoder for the family ofvideo_codec. For example,"libx264"becomes"h264_nvenc"or"h264_videotoolbox". Seehas_hardware_encoderfor availability and its caveats. This applies to video only.audio_codecis never hardware-accelerated. Resolving a hardware backend asks this FFmpeg build which encoders it has. So the first such call that re-encodes the video runs FFmpeg while the command is built, even underrun = FALSE. The answer is remembered for the rest of the R session. Seerefresh_ffmpeg_capabilitiesto discard it.- fallback
A logical. When a
hardwareother than"none"is requested but its encoder is unavailable,TRUEre-encodes with the softwarevideo_codecand a message.FALSE(default) aborts instead. This keeps output reproducible by never changing the codec silently. Avideo_codecin a family that the backend has no encoder for is a wrong argument, not an absent encoder. So it aborts whateverfallbacksays.- quality
A number, or
NULL(default) to leave the encoder's own default in place. It is the encoder's own rate-control value, passed through unchanged.libx264andlibx265read it as-crf(0 to 51). The nvenc encoders read it as-cq(0 to 51), and the videotoolbox encoders as-q:v(1 to 100). Each scale is its own: the same number means something different on each encoder. A value outside the encoder's range is refused. An encoder outside those seven, such aslibvpx-vp9, is refused withqualityset. So is avideo_codecof"copy", or ofNULLunderhardware = "none". Whenfallback = TRUEfalls back to software, the value is dropped and the message says so, because it belonged to the hardware encoder's scale.- audio_stream
The audio track to carry into the output, as a number that counts from
0among the audio tracks of the input.0is the first audio track and1is the second. Other streams in the file, such as video, do not count.NULL(default) carries every audio track. The every-track family readsNULLthis way:separate_audio_video,standardize_video,anonymize_video,crop_video,segment_videoandformat_for_web, and their_batchforms. The first-track family reads it as the first audio track only:extract_audio,convert_audioandnormalize_audio, and their_batchforms. The function does not carry subtitle or data streams in either case. A track the input does not have gives an FFmpeg error, not an R one. Seeaudio_streamfor how this differs fromaudio_input, the input index oncompare_videosandpicture_in_picture. (default =NULL)- run
A logical: run the command through FFmpeg (
TRUE, default) or return the compiled command without running it (FALSE).
Details
regions is a data frame with one row per box and the columns
x, y, width, and height. Each value is a pixel
number or an FFmpeg expression such as "in_w/2". x and
y give the top-left corner, and width and height give
the size. An optional
color column overrides the color argument for that row. Every
box is a solid fill (FFmpeg's drawbox with t=fill). The
function intentionally does not offer hollow outlines.
Because the function applies a filter, it re-encodes the video. The
video_codec and pixel_format arguments set the encoding, and
default to H.264 and yuv420p. The function floors odd source
dimensions to even, so the output always encodes. yuv420p and
libx264 require even dimensions, and the step changes nothing for
input that is already even. The function stream-copies the audio unchanged
(-c:a copy) unless
audio_codec names an encoder. The same input and regions therefore
always compile to a byte-identical command.
See also
ffm_drawbox(), the pipeline function it wraps;
has_hardware_encoder() for the
hardware argument; anonymize_video_batch()
for the many-file (batch) form.
Other task functions:
anonymize_video_batch(),
compare_videos(),
compare_videos_batch(),
concatenate_videos(),
concatenate_videos_batch(),
convert_audio(),
convert_audio_batch(),
crop_video(),
crop_video_batch(),
extract_audio(),
extract_audio_batch(),
extract_frame(),
extract_frame_batch(),
format_for_web(),
format_for_web_batch(),
normalize_audio(),
normalize_audio_batch(),
picture_in_picture(),
picture_in_picture_batch(),
sample_frames(),
sample_frames_batch(),
segment_video(),
segment_video_batch(),
separate_audio_video(),
separate_audio_video_batch(),
standardize_video(),
standardize_video_batch(),
strip_metadata(),
strip_metadata_batch()
Other audio selection functions:
anonymize_video_batch(),
audio_stream,
compare_videos(),
compare_videos_batch(),
convert_audio(),
convert_audio_batch(),
crop_video(),
crop_video_batch(),
extract_audio(),
extract_audio_batch(),
format_for_web(),
format_for_web_batch(),
normalize_audio(),
normalize_audio_batch(),
picture_in_picture(),
picture_in_picture_batch(),
segment_video(),
segment_video_batch(),
separate_audio_video(),
separate_audio_video_batch(),
standardize_video(),
standardize_video_batch()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
# Cover two fixed regions with black boxes
regions <- data.frame(
x = c(10, 200), y = c(10, 150),
width = c(120, 80), height = c(90, 60)
)
anonymize_video(video, "anon.mp4", regions, run = FALSE)
#> [1] "-y -i \"/home/runner/work/_temp/Library/tidymedia/extdata/sample.mp4\" -vf \"crop=w=floor(in_w/2)*2:h=floor(in_h/2)*2:x=(in_w-out_w)/2:y=(in_h-out_h)/2,drawbox=x=10:y=10:w=120:h=90:c=black:t=fill,drawbox=x=200:y=150:w=80:h=60:c=black:t=fill\" -codec:v libx264 -codec:a copy -pix_fmt yuv420p -map \"0:v?\" -map \"0:a?\" \"anon.mp4\""
# Carry only the second audio track instead of all of them
anonymize_video(video, "anon.mp4", regions, audio_stream = 1, run = FALSE)
#> [1] "-y -i \"/home/runner/work/_temp/Library/tidymedia/extdata/sample.mp4\" -vf \"crop=w=floor(in_w/2)*2:h=floor(in_h/2)*2:x=(in_w-out_w)/2:y=(in_h-out_h)/2,drawbox=x=10:y=10:w=120:h=90:c=black:t=fill,drawbox=x=200:y=150:w=80:h=60:c=black:t=fill\" -codec:v libx264 -codec:a copy -pix_fmt yuv420p -map \"0:v?\" -map \"0:a:1\" \"anon.mp4\""