Skip to contents

Crop a video to a rectangular region. The glossary in vignette("tidymedia") explains media terms such as codec, container and stream copy.

Usage

crop_video(
  infile,
  outfile,
  width,
  height,
  x = "(in_w-out_w)/2",
  y = "(in_h-out_h)/2",
  video_codec = NULL,
  audio_codec = "copy",
  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.

width

The width of the output video, in pixels.

height

The height of the output video, in pixels.

x

The horizontal offset, in pixels, of the left edge of the crop. (default = centered)

y

The vertical offset, in pixels, of the top edge of the crop. (default = centered)

video_codec

A string naming the output video codec, or NULL (default) to leave it unset. Then the output container's default encoder is used, and the compiled command is the same as one that never named a codec.

audio_codec

A string naming the output audio codec. "copy" (default) stream-copies the audio through untouched. Name an encoder, such as "aac", to transcode it. NULL leaves the codec unset, so the output container's default encoder is used. Stream-copying fails if the output container cannot hold the source audio codec, for example FLAC in .mp4. In that case, name an encoder.

hardware

The encoder backend. "none" (default) uses the software video_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 of video_codec. For example, "libx264" becomes "h264_nvenc" or "h264_videotoolbox". With the default video_codec = NULL, the H.264 family is assumed. So a non-H.264 container, such as .webm, needs an explicit HEVC- or AV1-family video_codec (AV1 only under "nvenc"). See has_hardware_encoder for availability and its caveats. 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 under run = FALSE. The answer is remembered for the rest of the R session. See refresh_ffmpeg_capabilities to discard it.

fallback

A logical. When a hardware other than "none" is requested but its encoder is unavailable, TRUE encodes in software with a message. FALSE (default) aborts instead. With video_codec = NULL, the fallback leaves the codec unset rather than picking one, so the codec never changes silently. A video_codec in a family that the backend has no encoder for is a wrong argument, not an absent encoder. So it aborts whatever fallback says.

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. libx264 and libx265 read 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 as libvpx-vp9, is refused with quality set. So is a video_codec of "copy", or of NULL under hardware = "none". When fallback = TRUE falls 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 0 among the audio tracks of the input. 0 is the first audio track and 1 is the second. Other streams in the file, such as video, do not count. NULL (default) carries every audio track. The every-track family reads NULL this way: separate_audio_video, standardize_video, anonymize_video, crop_video, segment_video and format_for_web, and their _batch forms. The first-track family reads it as the first audio track only: extract_audio, convert_audio and normalize_audio, and their _batch forms. 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. See audio_stream for how this differs from audio_input, the input index on compare_videos and picture_in_picture. (default = NULL)

run

A logical: run the command through FFmpeg (TRUE, default) or return the compiled command without running it (FALSE).

Value

The compiled FFmpeg command (invisibly when run = TRUE).

Examples

video <- system.file("extdata", "sample.mp4", package = "tidymedia")
crop_video(video, "cropped.mp4", width = 160, height = 120, run = FALSE)
#> [1] "-y -i \"/home/runner/work/_temp/Library/tidymedia/extdata/sample.mp4\" -vf \"crop=w=160:h=120:x=(in_w-out_w)/2:y=(in_h-out_h)/2\" -codec:a copy -map \"0:v?\" -map \"0:a?\" \"cropped.mp4\""