Re-encode a video to a consistent, reproducible format for analysis. The
format is one video codec and pixel format, and optionally a resolution and
frame rate, with +faststart for smooth playback.
format_for_web uses a fixed recipe for web delivery. Here,
every part of the standard is an argument. So a lab can set its own house
format once and apply it across a dataset. The glossary in
vignette("tidymedia") explains media terms such as codec, pixel format
and frame rate.
Usage
standardize_video(
infile,
outfile,
width = NULL,
height = NULL,
fps = NULL,
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.
- width
The output width in pixels (a positive number), or
NULL(default) to leave the width unconstrained.- height
The output height in pixels (a positive number), or
NULL(default) to leave the height unconstrained.- fps
The output frame rate (a positive number or FFmpeg framerate expression such as
"30000/1001"), orNULL(default) to keep the input frame rate.- 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
The default standard, standardize_video(infile, outfile), re-encodes
to H.264 video (video_codec = "libx264") with
pixel_format = "yuv420p" and -movflags +faststart. It keeps
the source resolution and frame rate. Audio is stream-copied unchanged
(-c:a copy) unless audio_codec names an encoder. The same
input therefore always compiles to a byte-identical command. Loudness
standardization is out of scope. For that, see
normalize_audio.
Resolution follows width and height:
With both, the output has exactly those dimensions.
With only one, the aspect ratio is kept, and the other dimension is rounded to the nearest even number (FFmpeg's
-2).With neither, the source resolution is kept, but odd dimensions are rounded down to the nearest even value.
yuv420pandlibx264require this, and it changes nothing for input that is already even. So the output always encodes.
See also
ffm_scale(), ffm_codec(), and ffm_pixel_format(), among the
pipeline functions it wraps; has_hardware_encoder() for the
hardware toggle;
standardize_video_batch() for the many-file form.
Other task functions:
anonymize_video(),
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_batch(),
strip_metadata(),
strip_metadata_batch()
Other audio selection functions:
anonymize_video(),
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_batch()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
# The documented default standard (H.264 / yuv420p / +faststart)
standardize_video(video, "std.mp4", 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\" -codec:v libx264 -codec:a copy -pix_fmt yuv420p -movflags +faststart -map \"0:v?\" -map \"0:a?\" \"std.mp4\""
# Pin resolution and frame rate too
standardize_video(video, "std.mp4", width = 1280, height = 720, fps = 30,
run = FALSE)
#> [1] "-y -i \"/home/runner/work/_temp/Library/tidymedia/extdata/sample.mp4\" -vf \"scale=w=1280:h=720,fps=30\" -codec:v libx264 -codec:a copy -pix_fmt yuv420p -movflags +faststart -map \"0:v?\" -map \"0:a?\" \"std.mp4\""
# Carry only the second audio track instead of all of them
standardize_video(video, "std.mp4", 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\" -codec:v libx264 -codec:a copy -pix_fmt yuv420p -movflags +faststart -map \"0:v?\" -map \"0:a:1\" \"std.mp4\""