| Title: | Media File Preprocessing and Metadata for the 'tidyverse' |
| Version: | 0.2.1 |
| Description: | Batch preprocessing and metadata extraction for audio, video and image files, built on the command-line programs 'FFmpeg' (https://ffmpeg.org/) and 'MediaInfo' (https://mediaarea.net/en/MediaInfo). Trim, crop, scale, convert and standardize files one at a time or across a whole directory, and read container and stream metadata back as tibbles for use with the 'tidyverse'. |
| License: | GPL-3 |
| URL: | https://github.com/jmgirard/tidymedia, https://jmgirard.github.io/tidymedia/ |
| BugReports: | https://github.com/jmgirard/tidymedia/issues |
| Depends: | R (≥ 4.1.0) |
| Imports: | archive (≥ 1.1.1), cli (≥ 3.4.0), digest (≥ 0.6.37), dplyr (≥ 1.1.0), glue (≥ 1.6.2), purrr (≥ 1.0.0), rappdirs (≥ 0.3.3), rlang (≥ 1.2.0), tibble (≥ 3.1.4), tools, utils, withr (≥ 2.5.0) |
| Suggests: | furrr (≥ 0.3.0), future (≥ 1.30.0), knitr (≥ 1.40), rmarkdown (≥ 2.16), roxygen2 (≥ 7.2.0), spelling (≥ 2.2), testthat (≥ 3.0.0) |
| SystemRequirements: | FFmpeg (https://ffmpeg.org/), MediaInfo (https://mediaarea.net/en/MediaInfo) |
| VignetteBuilder: | knitr |
| Encoding: | UTF-8 |
| Language: | en-US |
| Config/testthat/edition: | 3 |
| Config/roxygen2/version: | 8.1.0 |
| Config/Needs/website: | pkgdown |
| NeedsCompilation: | no |
| Packaged: | 2026-09-29 16:06:56 UTC; jmgirard |
| Author: | Jeffrey Girard |
| Maintainer: | Jeffrey Girard <me@jmgirard.com> |
| Repository: | CRAN |
| Date/Publication: | 2026-10-10 10:30:02 UTC |
tidymedia: Media File Preprocessing and Metadata for the 'tidyverse'
Description
tidymedia prepares audio and video files for research. It trims, crops,
converts and standardizes files, and reads file details back as tibbles. It
runs the programs FFmpeg and MediaInfo. Start with vignette("tidymedia").
Details
Task functions, such as extract_audio(), do one common job in one call.
Pipeline functions, such as ffm_files(), build an FFmpeg command one step
at a time. Direct commands, ffmpeg(), ffprobe() and mediainfo(), pass
your own arguments to the programs. probe_all() and get_duration() read
file details.
See vignette("tidymedia") for the guided tour and a glossary of media
terms. The other vignettes are "batch", "metadata", "verification" and
"workflow".
Session options
A new option value takes effect at the next call. The workers of a
parallel = TRUE run use your session's values.
-
options(tidymedia.timeout = 600)sets a limit, in whole seconds, on each program the package starts. The default,0, means no limit. Seewith_timeout(). -
options(tidymedia.check_tracks = FALSE)turns off the dropped-track warning ofextract_audio(),convert_audio(),normalize_audio()and their_batchforms. The default isTRUE. The check runs one FFprobe call for each different input, whenrun = TRUEand the call or job row names noaudio_stream. Turning it off skips those calls. A value other thanTRUEorFALSEgives an error that names the option, when the check would run. -
options(tidymedia.hardware_encoders = "h264_nvenc")names the hardware video encoders of this computer, so the package does not ask FFmpeg.character(0)means none.
Errors when FFmpeg fails
-
tidymedia_ffmpeg_exit: FFmpeg exited non-zero inffm_run(), or in theloudnormanalysis pass ofnormalize_audio(two_pass = TRUE). The task functions that run their command withffm_run(), such asextract_audio()andseparate_audio_video(), give it too. Thetm_statusfield holds the exit status. -
tidymedia_loudnorm_no_measurement: the two-pass analysis gave no measurement. In the_batchform,tm_rowsholds the rows, andtm_row_statusholds each exit status orNA. -
tidymedia_multitrack_separation:separate_audio_video()could not write several audio tracks into one audio file. The_batchform gives a warning.
Author(s)
Maintainer: Jeffrey Girard me@jmgirard.com (ORCID)
Authors:
Jeffrey Girard me@jmgirard.com (ORCID)
See Also
Useful links:
Report bugs at https://github.com/jmgirard/tidymedia/issues
Cover fixed regions of a video with opaque boxes
Description
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 |
color |
A string naming the default fill color in FFmpeg color syntax,
used for any row without its own |
video_codec |
A string naming the output video codec (default
|
audio_codec |
A string naming the output audio codec. The default
|
pixel_format |
A string naming the output pixel format (default
|
hardware |
The encoder backend. |
fallback |
A logical. When a |
quality |
A number, or |
audio_stream |
The audio track to carry into the output, as a number that counts from |
run |
A logical: run the command through FFmpeg ( |
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.
Value
The compiled FFmpeg command (invisibly when run = TRUE).
References
https://ffmpeg.org/ffmpeg-filters.html#drawbox
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)
# Carry only the second audio track instead of all of them
anonymize_video(video, "anon.mp4", regions, audio_stream = 1, run = FALSE)
Anonymize Many Videos From a Jobs Table
Description
Cover fixed rectangular regions of many input videos with opaque filled boxes
from a single jobs tibble. This is the batch (table-driven) form of
anonymize_video(), for when you have more than one video to
redact. Each row is one input with its own regions. The required columns name
the source (input) and the boxes to cover (regions). This is a
thin wrapper over ffm_batch. It compiles one reproducible
command per input. It shares the same box-fill pipeline (and per-region
validation) as anonymize_video(). The glossary in
vignette("tidymedia") explains media terms such as codec, pixel format
and stream copy.
Usage
anonymize_video_batch(
jobs,
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,
parallel = FALSE,
...
)
Arguments
jobs |
A data frame with one row per input and (at least) an
|
color |
A string naming the default fill color (FFmpeg color syntax)
applied to every row. A |
video_codec |
A string naming the output video codec applied to every
row, unless |
audio_codec |
A string naming the output audio codec applied to every
row, unless |
pixel_format |
A string naming the output pixel format applied to every
row, unless |
hardware |
The encoder backend applied to every row. |
fallback |
A logical applied to every row. When a |
quality |
A number, or |
audio_stream |
The audio track to carry into each output, as a number that counts from |
run |
A logical: run each input's command through FFmpeg ( |
parallel |
A logical passed to |
... |
Additional arguments forwarded to |
Value
The tibble returned by ffm_batch: jobs with an added command column. When output was derived, it also has the resolved output column. When run = TRUE, it has a success column, plus any columns the forwarded arguments add, such as verified.
See Also
anonymize_video() for the single-input form.
has_hardware_encoder() for the hardware argument. ffm_batch()
for the batch runner and the arguments forwarded through ....
standardize_video_batch() and segment_video_batch() for the other
table-driven functions.
Other task functions:
anonymize_video(),
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(),
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")
jobs <- tibble::tibble(
input = c(video, video),
output = c("a.mp4", "b.mp4"),
regions = list(
data.frame(x = 10, y = 10, width = 120, height = 90),
data.frame(x = 200, y = 150, width = 80, height = 60)
)
)
# run = FALSE compiles one command per input without calling FFmpeg
anonymize_video_batch(jobs, run = FALSE)
Audio track and audio input indices
Description
Two audio arguments in this package count different things: audio_stream
and audio_input. Both count from 0, so 0 means the first one. This page
explains which is which.
The glossary in vignette("tidymedia") explains media terms such as stream,
container and codec.
Value
This page documents no function and returns no value. It explains two arguments the functions listed under See Also take. Each of those pages says what its own function returns.
The two indices
audio_stream counts the audio tracks of one input file. On
extract_audio(), audio_stream = 1 is the second audio track of the file.
Where that track sits among all the streams of the file does not matter. So
audio_stream is not the index column of probe_audio(), which counts
every stream, audio or not.
audio_input counts the input files of a function. The functions
compare_videos() and picture_in_picture() combine several files into one
output, so they must choose whose sound to keep. On these functions,
audio_input = 1 is the second file. It says nothing about which
track of that file is used.
You cannot work out one index from the other. So the package keeps two names, rather than one argument whose meaning depends on how many inputs a function takes.
What NULL means
audio_stream = NULL still selects audio. It does not mean "no audio". How
much audio it selects depends on the function.
The first-track family reads
NULLas the first audio track only:extract_audio,convert_audioandnormalize_audio, and their_batchforms. The every-track family reads it as every audio track:separate_audio_video,standardize_video,anonymize_video,crop_video,segment_videoandformat_for_web, and their_batchforms.The two readings have a reason. A function that writes one audio stream must pick one track when you name none. A function that carries audio through can keep all the tracks its container holds.
On the functions that pass video through, an input with no audio gives an output with no audio, not an error. On
separate_audio_video()andnormalize_audio(), whose output is audio, that input gives an FFmpeg error.
audio_input = NULL is different: it selects no audio at all, so the output
has no audio. A silent output is the default for compare_videos()
and picture_in_picture(). With several inputs, no choice of which one to
hear is better than another.
The two arguments also fail in different ways when a number is too large.
An audio_input that names an input you did not pass gives an R error,
before FFmpeg runs. An audio_stream that names a track the input does not
have gives an FFmpeg error. The reason is that the number of tracks is a fact
about the file, not about the call.
In a _batch jobs table
On a _batch function, both arguments follow one rule. The argument you
pass is the default, and a jobs column with the same name overrides it row
by row.
This rule is about these two arguments only. The arguments hardware,
parallel and two_pass apply to the whole batch, and the function reads
no column for them.
If the column is absent, the argument applies to every row. If the column is
present, each row uses its own cell. An NA cell means NULL for that row.
It does not fall back to the argument. So audio_stream = 2 with an NA
cell in an audio_stream column gives that row the NULL reading of its
family, not track 2.
The name audio alone is not an index
The pipeline functions use audio for two things that are not counts:
an audio codec name on
ffm_codec(), whereaudio = "aac"names an encoder;a logical on
ffm_copy(), whereaudio = TRUEcopies the audio stream without re-encoding it.
The input index is called audio_input, so that its name says what it
counts, as audio_stream does.
See Also
extract_audio, convert_audio and normalize_audio read NULL as the
first audio track. separate_audio_video, standardize_video, anonymize_video, crop_video, segment_video and format_for_web read it
as every audio track. compare_videos() and picture_in_picture() take
the input index. probe_audio() shows which audio tracks a file has.
Other audio selection functions:
anonymize_video(),
anonymize_video_batch(),
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()
Build a side-by-side comparison video
Description
Stack two or more videos into a single comparison video. The videos go
side-by-side (direction = "horizontal") or one above the other
(direction = "vertical"). This is a common need when reviewing
annotations or before/after processing. Built on the stacking pipeline
functions (ffm_hstack / ffm_vstack). The glossary
in vignette("tidymedia") explains media terms such as codec, encoder
and stream copy.
Usage
compare_videos(
infiles,
outfile,
direction = c("horizontal", "vertical"),
resize = TRUE,
audio_input = NULL,
video_codec = NULL,
audio_codec = "copy",
hardware = c("none", "nvenc", "videotoolbox"),
fallback = FALSE,
quality = NULL,
run = TRUE
)
Arguments
infiles |
A character vector of two or more video file paths. This function checks every path itself. A path that cannot be found or read aborts naming this function, and the error lists every such path. It is not reported against the internal builder that the path would otherwise reach. |
outfile |
A string giving the path to write the comparison video to. |
direction |
Either |
resize |
A logical indicating whether to resize the inputs to share an
edge. Only supported for exactly two inputs. (default = |
audio_input |
The input file whose audio to keep, as a number that counts from |
video_codec |
A string naming the output video codec, or |
audio_codec |
A string naming the codec for the carried audio track.
|
hardware |
The encoder backend. |
fallback |
A logical. When a |
quality |
A number, or |
run |
A logical: run the command through FFmpeg ( |
Details
By default the two inputs are resized to share an edge (equal heights for a
horizontal stack, equal widths for a vertical one). Resizing currently
supports exactly two inputs, so pass resize = FALSE to compare more.
Audio is dropped unless audio_input names an input to carry; a carried
track is stream-copied unless audio_codec names an encoder.
Value
The compiled FFmpeg command (invisibly when run = TRUE).
See Also
ffm_hstack() and ffm_vstack(), the pipeline functions it wraps;
has_hardware_encoder() for the hardware argument;
picture_in_picture() for insetting instead of stacking.
Other task functions:
anonymize_video(),
anonymize_video_batch(),
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(),
anonymize_video_batch(),
audio_stream,
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")
compare_videos(c(video, video), "compare.mp4", run = FALSE)
Build Many Comparison Videos From a Jobs Table
Description
Stack videos side by side for many outputs from a single jobs tibble. This is
the batch (table-driven) form of compare_videos(), for when you have
more than one comparison to produce. Each row carries an inputs
list-column (each cell two or more video paths) plus an output column.
This is a thin wrapper over ffm_batch: one reproducible stacking
command per row, sharing the pipeline with compare_videos(). The glossary
in vignette("tidymedia") explains media terms such as codec, encoder
and stream copy.
Usage
compare_videos_batch(
jobs,
direction = c("horizontal", "vertical"),
resize = TRUE,
audio_input = NULL,
video_codec = NULL,
audio_codec = "copy",
hardware = c("none", "nvenc", "videotoolbox"),
fallback = FALSE,
quality = NULL,
run = TRUE,
parallel = FALSE,
...
)
Arguments
jobs |
A data frame with one row per output and (at least) an
|
direction, resize |
Defaults applied to every row lacking the
corresponding column. |
audio_input |
The input file whose audio to keep, as a number that counts from |
video_codec |
A string naming the output video codec, applied to every
row lacking a |
audio_codec |
A string naming the codec for the carried audio track,
applied to every row lacking an |
hardware, fallback |
The encoder backend and its fallback behavior, applied to the whole batch. They are a property of the machine, not of a row, so neither is read as a |
quality |
A number, or |
run |
A logical: run each command through FFmpeg ( |
parallel |
A logical: process the jobs in parallel with furrr
( |
... |
Additional arguments forwarded to |
Value
The jobs tibble with an added command column. When run = TRUE, it also has a success column, plus verified or a provenance manifest, each when requested through .... See ffm_batch.
See Also
compare_videos(), the one-output function it wraps; ffm_batch(),
the batch runner; has_hardware_encoder() for the hardware
argument. concatenate_videos_batch() and picture_in_picture_batch(),
the other batch functions that take several inputs per row.
Other task functions:
anonymize_video(),
anonymize_video_batch(),
compare_videos(),
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(),
anonymize_video_batch(),
audio_stream,
compare_videos(),
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")
jobs <- tibble::tibble(inputs = list(c(video, video)), output = "compare.mp4")
compare_videos_batch(jobs, run = FALSE)
Combine video files using the concat demuxer
Description
Combine multiple video files one after another without needing to re-encode
them by using the concat demuxer. This will be much
faster than re-encoding but requires that the files have the same parameters
(width, height, etc.) and formats/codecs. To concatenate videos using
re-encoding, see the concat video filter. The glossary in
vignette("tidymedia") explains media terms such as codec and
re-encode.
Usage
concatenate_videos(infiles, outfile, run = TRUE)
Arguments
infiles |
A character vector containing the file paths to video files. This function checks every path itself. A path that cannot be found or read aborts naming this function, and the error lists every such path. It is not reported against the internal builder that the path would otherwise reach. |
outfile |
A string containing the desired file path to write the new, concatenated video file to. |
run |
A logical: run the command through FFmpeg ( |
Value
The compiled FFmpeg command (invisibly when run = TRUE).
See Also
ffm_concat(), the pipeline function it wraps.
Other task functions:
anonymize_video(),
anonymize_video_batch(),
compare_videos(),
compare_videos_batch(),
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()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
concatenate_videos(c(video, video), "joined.mp4", run = FALSE)
Concatenate Many Videos From a Jobs Table
Description
Join clips end to end for many outputs from a single jobs tibble. This is the
batch (table-driven) form of concatenate_videos(), for when you have
more than one concatenation to produce. Unlike the single-input batch
functions, each row's inputs are many. So jobs carries an
inputs list-column (each cell a character vector of source paths)
plus an output column. This is a thin wrapper over
ffm_batch: one reproducible concat-demuxer command per row,
sharing the copy + map-0 pipeline with concatenate_videos().
Usage
concatenate_videos_batch(jobs, run = TRUE, parallel = FALSE, ...)
Arguments
jobs |
A data frame with one row per output and (at least) an
|
run |
A logical: run each command through FFmpeg ( |
parallel |
A logical: process the jobs in parallel with furrr
( |
... |
Additional arguments forwarded to |
Value
The jobs tibble with an added command column. When run = TRUE, it also has a success column, plus verified or a provenance manifest, each when requested through .... See ffm_batch.
See Also
concatenate_videos(), the one-output function it wraps; ffm_batch(),
the batch runner; compare_videos_batch() and
picture_in_picture_batch(), the other batch functions that take several
inputs per row.
Other task functions:
anonymize_video(),
anonymize_video_batch(),
compare_videos(),
compare_videos_batch(),
concatenate_videos(),
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()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
jobs <- tibble::tibble(inputs = list(c(video, video)), output = "joined.mp4")
concatenate_videos_batch(jobs, run = FALSE)
Extract or convert a media file's audio track
Description
Write the audio stream of infile into outfile. By default
(audio_codec = NULL), the output format follows the outfile
file extension, at the highest VBR quality (-q:a 0). For example, an
.mp3 extension gives an MP3. Pass audio_codec to set the output
audio codec yourself, whatever the extension is. The glossary in
vignette("tidymedia") explains media terms such as codec and stream.
Usage
convert_audio(
infile,
outfile,
audio_codec = NULL,
audio_stream = NULL,
run = TRUE
)
Arguments
infile |
A string containing the path to a media file. |
outfile |
A string containing the path of the audio file to write. |
audio_codec |
An optional string naming the output audio codec (e.g.
|
audio_stream |
The audio track to take, as a number that counts from |
run |
A logical: run the command through FFmpeg ( |
Details
When infile has more than one audio track, audio_stream names
which one to take. With no audio_stream, the function takes the
first one.
When no audio_stream is named and the input has tracks that the output will not carry, the function warns. The check costs one FFprobe call per distinct input, which is one call here, because this function takes a single infile. The warning is given when FFprobe is available and the input can be probed. Otherwise the check is skipped silently. It never runs under run = FALSE, and never changes the compiled command. Suppress it by naming a track with audio_stream, or by class with suppressWarnings(classes = "tidymedia_dropped_audio").
To switch the check off and skip its FFprobe call, use options(tidymedia.check_tracks = FALSE) for the session. Use withr::local_options(tidymedia.check_tracks = FALSE) for the rest of one function.
Value
The compiled FFmpeg command (invisibly when run = TRUE).
See Also
ffm_codec() and ffm_map(), the pipeline functions it wraps.
extract_audio() to copy audio without re-encoding.
convert_audio_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_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(),
anonymize_video_batch(),
audio_stream,
compare_videos(),
compare_videos_batch(),
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")
convert_audio(video, "audio.mp3", run = FALSE)
convert_audio(video, "audio.m4a", audio_codec = "aac", run = FALSE)
# Convert the second audio track instead of the first
convert_audio(video, "audio.mp3", audio_stream = 1, run = FALSE)
Convert the Audio of Many Files From a Jobs Table
Description
Extract or re-encode the audio track of many input files, using one jobs
table. This is the batch form of convert_audio(), for when you have
more than one file. Each row is one input. The input and
output columns are required. The function is a thin wrapper over
ffm_batch. It builds one reproducible command for each input.
Each command uses the same audio steps as convert_audio(), and the
function checks each audio_codec value in the same way. The glossary
in vignette("tidymedia") explains media terms such as codec and
stream.
Usage
convert_audio_batch(
jobs,
audio_codec = NULL,
audio_stream = NULL,
run = TRUE,
parallel = FALSE,
...
)
Arguments
jobs |
A data frame with one row per input. It needs at least an
|
audio_codec |
The output audio codec applied to every row, unless
|
audio_stream |
The audio track to take, as a number that counts from |
run |
A logical: run each command through FFmpeg ( |
parallel |
A logical: process the jobs in parallel with furrr
( |
... |
Additional arguments forwarded to |
Details
When a row names no audio_stream and its input has tracks that the output will not carry, the function warns once for the whole batch. The warning names every affected row. The check costs one FFprobe call per distinct input it has to probe. A repeated input is probed once, and a row that names a track is not probed at all. The warning is given when FFprobe is available and the input can be probed. Otherwise the check is skipped silently. Those probes run one at a time, before any row starts, so parallel does not reach them. A sweep long enough to look like a hang reports its progress. The check never runs under run = FALSE, never changes any compiled command, and is skipped entirely when every row names a track. Suppress it by class with suppressWarnings(classes = "tidymedia_dropped_audio").
To switch the check off and skip the whole sweep, use options(tidymedia.check_tracks = FALSE) for the session. Use withr::local_options(tidymedia.check_tracks = FALSE) for the rest of one function.
Value
The jobs tibble with an added command column. When run = TRUE, it also has a success column, plus verified or a provenance manifest, each when requested through .... See ffm_batch.
See Also
convert_audio(), the single-input form it wraps. ffm_batch(),
the batch runner. extract_audio_batch() to stream-copy audio in batch.
Other task functions:
anonymize_video(),
anonymize_video_batch(),
compare_videos(),
compare_videos_batch(),
concatenate_videos(),
concatenate_videos_batch(),
convert_audio(),
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(),
anonymize_video_batch(),
audio_stream,
compare_videos(),
compare_videos_batch(),
convert_audio(),
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")
jobs <- tibble::tibble(input = c(video, video), output = c("a.mp3", "b.mp3"))
convert_audio_batch(jobs, run = FALSE)
Crop a video to a rectangular region
Description
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 |
audio_codec |
A string naming the output audio codec.
|
hardware |
The encoder backend. |
fallback |
A logical. When a |
quality |
A number, or |
audio_stream |
The audio track to carry into the output, as a number that counts from |
run |
A logical: run the command through FFmpeg ( |
Value
The compiled FFmpeg command (invisibly when run = TRUE).
See Also
ffm_crop(), the pipeline function it wraps;
has_hardware_encoder() for the hardware toggle;
crop_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_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(),
anonymize_video_batch(),
audio_stream,
compare_videos(),
compare_videos_batch(),
convert_audio(),
convert_audio_batch(),
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")
crop_video(video, "cropped.mp4", width = 160, height = 120, run = FALSE)
Crop Many Videos From a Jobs Table
Description
Crop many videos to a rectangular region, using one jobs table. This is the
batch form of crop_video(), for when you have more than one file. Each
row is one input. The function is a thin wrapper over
ffm_batch. It builds one reproducible command for each input,
with the same crop steps as crop_video(). This function checks each
row's crop size and position before any command runs. So a bad cell is
refused with an error that names this function. The glossary in
vignette("tidymedia") explains media terms such as codec, container
and stream copy.
Usage
crop_video_batch(
jobs,
width = NULL,
height = NULL,
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,
parallel = FALSE,
...
)
Arguments
jobs |
A data frame with one row per input. It needs at least an
|
width, height |
The output crop size in pixels, for every row unless
|
x, y |
The offset in pixels of the crop's left and top edge, for every
row unless |
video_codec |
A string naming the output video codec, applied to every
row lacking a |
audio_codec |
A string naming the output audio codec, for every row
when |
hardware, fallback |
The encoder backend and its fallback behavior, applied to the whole batch. They are a property of the machine, not of a row, so neither is read as a |
quality |
A number, or |
audio_stream |
The audio track to carry into each output, as a number that counts from |
run |
A logical: run each command through FFmpeg ( |
parallel |
A logical: process the jobs in parallel with furrr
( |
... |
Additional arguments forwarded to |
Value
The jobs tibble with an added command column. When run = TRUE, it also has a success column, plus verified or a provenance manifest, each when requested through .... See ffm_batch.
See Also
crop_video(), the single-input form it wraps; ffm_batch(),
the batch runner; has_hardware_encoder() for the hardware toggle;
standardize_video_batch() to re-encode in batch.
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(),
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(),
anonymize_video_batch(),
audio_stream,
compare_videos(),
compare_videos_batch(),
convert_audio(),
convert_audio_batch(),
crop_video(),
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")
jobs <- tibble::tibble(input = c(video, video), output = c("a.mp4", "b.mp4"),
width = c(160, 80), height = c(120, 60))
crop_video_batch(jobs, run = FALSE)
Extract the audio stream from a media file
Description
Take one audio track out of infile, and drop the video. When the
input has more than one audio track, audio_stream names which one to
take. With no audio_stream, the function takes the first
audio track. The glossary in vignette("tidymedia") explains media
terms such as codec, container and stream copy.
Usage
extract_audio(
infile,
outfile,
audio_codec = "copy",
audio_stream = NULL,
run = TRUE
)
Arguments
infile |
A string containing the path to a media file. |
outfile |
A string containing the path of the audio file to write. |
audio_codec |
A string naming the audio codec for the output stream.
The default |
audio_stream |
The audio track to take, as a number that counts from |
run |
A logical: run the command through FFmpeg ( |
Details
When no audio_stream is named and the input has tracks that the output will not carry, the function warns. The check costs one FFprobe call per distinct input, which is one call here, because this function takes a single infile. The warning is given when FFprobe is available and the input can be probed. Otherwise the check is skipped silently. It never runs under run = FALSE, and never changes the compiled command. Suppress it by naming a track with audio_stream, or by class with suppressWarnings(classes = "tidymedia_dropped_audio").
To switch the check off and skip its FFprobe call, use options(tidymedia.check_tracks = FALSE) for the session. Use withr::local_options(tidymedia.check_tracks = FALSE) for the rest of one function.
Value
The compiled FFmpeg command (invisibly when run = TRUE).
See Also
ffm_drop() and ffm_codec(), the pipeline functions it wraps.
convert_audio() to re-encode the extracted audio.
extract_audio_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_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(),
anonymize_video_batch(),
audio_stream,
compare_videos(),
compare_videos_batch(),
convert_audio(),
convert_audio_batch(),
crop_video(),
crop_video_batch(),
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")
extract_audio(video, "audio.aac", run = FALSE)
# Take the second audio track instead of the first
extract_audio(video, "audio.aac", audio_stream = 1, run = FALSE)
Extract Audio From Many Files From a Jobs Table
Description
Take the audio track out of many input files, using one jobs table. This is
the batch form of extract_audio(), for when you have more than one
file. Each row is one input. The input and output columns are
required. The function is a thin wrapper over ffm_batch. It
builds one reproducible command for each input, with the same steps as
extract_audio(): select the audio track and drop the video. The
glossary in vignette("tidymedia") explains media terms such as codec,
container and stream copy.
Usage
extract_audio_batch(
jobs,
audio_codec = "copy",
audio_stream = NULL,
run = TRUE,
parallel = FALSE,
...
)
Arguments
jobs |
A data frame with one row per input. It needs at least an
|
audio_codec |
The audio codec applied to every row, unless |
audio_stream |
The audio track to take, as a number that counts from |
run |
A logical: run each command through FFmpeg ( |
parallel |
A logical: process the jobs in parallel with furrr
( |
... |
Additional arguments forwarded to |
Details
When a row names no audio_stream and its input has tracks that the output will not carry, the function warns once for the whole batch. The warning names every affected row. The check costs one FFprobe call per distinct input it has to probe. A repeated input is probed once, and a row that names a track is not probed at all. The warning is given when FFprobe is available and the input can be probed. Otherwise the check is skipped silently. Those probes run one at a time, before any row starts, so parallel does not reach them. A sweep long enough to look like a hang reports its progress. The check never runs under run = FALSE, never changes any compiled command, and is skipped entirely when every row names a track. Suppress it by class with suppressWarnings(classes = "tidymedia_dropped_audio").
To switch the check off and skip the whole sweep, use options(tidymedia.check_tracks = FALSE) for the session. Use withr::local_options(tidymedia.check_tracks = FALSE) for the rest of one function.
Value
The jobs tibble with an added command column. When run = TRUE, it also has a success column, plus verified or a provenance manifest, each when requested through .... See ffm_batch.
See Also
extract_audio(), the single-input form it wraps. ffm_batch(),
the batch runner. convert_audio_batch() to re-encode audio in batch.
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_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(),
anonymize_video_batch(),
audio_stream,
compare_videos(),
compare_videos_batch(),
convert_audio(),
convert_audio_batch(),
crop_video(),
crop_video_batch(),
extract_audio(),
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")
jobs <- tibble::tibble(input = c(video, video), output = c("a.aac", "b.aac"))
extract_audio_batch(jobs, run = FALSE)
Extract a single frame from a video
Description
Save one frame of a video to an image file, selected either by timestamp or
by frame number. Provide exactly one of timestamp or frame.
Usage
extract_frame(infile, outfile, timestamp = NULL, frame = NULL, run = TRUE)
Arguments
infile |
A string containing the path to a video file. |
outfile |
A string containing the path of the image file to write. |
timestamp |
Either a number of seconds, a time-duration-syntax string,
or |
frame |
Either an integerish frame number or |
run |
A logical: run the command through FFmpeg ( |
Value
The compiled FFmpeg command (invisibly when run = TRUE).
See Also
ffm_seek(), the pipeline function it uses to get the frame.
extract_frame_batch() for the many-file (batch) 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_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()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
# run = FALSE returns the reproducible command instead of executing it
extract_frame(video, "frame.png", timestamp = 0.5, run = FALSE)
Extract Still Frames From Many Videos From a Jobs Table
Description
Save one still image for each row, across many input files, using one jobs
table. This is the batch form of extract_frame(), for when your frames
come from more than one input. Each row is one frame. The required columns
name its source and the moment to capture. The function is a thin wrapper
over ffm_batch. It builds one reproducible command for each
frame. The glossary in vignette("tidymedia") explains media terms
such as frame rate.
Usage
extract_frame_batch(jobs, format = "png", run = TRUE, parallel = FALSE, ...)
Arguments
jobs |
A data frame with one row per frame. It needs at least an
|
format |
A string giving the image file extension used when the
function derives |
run |
A logical: run each frame's command through FFmpeg ( |
parallel |
A logical passed to |
... |
Additional arguments forwarded to |
Value
The tibble returned by ffm_batch: jobs with an added command column. When output was derived, it also has the resolved output column. When run = TRUE, it has a success column, plus any columns the forwarded arguments add, such as verified.
References
https://ffmpeg.org/ffmpeg-utils.html#time-duration-syntax
See Also
extract_frame() for the single-frame form. ffm_batch() for the
batch runner and the arguments passed on through ....
segment_video_batch() for the batch function that cuts segments.
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(),
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()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
jobs <- tibble::tibble(
input = c(video, video),
output = c("a.png", "b.png"),
timestamp = c(0.25, 0.75)
)
# run = FALSE compiles one command per frame without calling FFmpeg
extract_frame_batch(jobs, run = FALSE)
Run an FFmpeg Pipeline Over Many Files
Description
Apply a pipeline-building function to every row of a jobs table and compile (and optionally run) the resulting FFmpeg command for each. This is the package's main batch function. It gives one reproducible compiled command per job, collected back into a tibble.
Usage
ffm_batch(
jobs,
.f,
...,
run = TRUE,
parallel = FALSE,
verify = NULL,
progress = FALSE,
manifest = FALSE,
checksums = FALSE
)
Arguments
jobs |
A data frame with one row per job. Its column names are the
arguments passed to |
.f |
A function that takes a job's columns (by name) and returns an ffm pipeline object. |
... |
Additional arguments passed on to every call of |
run |
A logical: run each compiled command through FFmpeg ( |
parallel |
A logical: map over jobs in parallel with furrr
( |
verify |
An optional output check applied to each job (only when
|
progress |
A logical: display a cli progress bar as the jobs run
( |
manifest |
A logical. When |
checksums |
A logical: when |
Details
Each column of jobs is passed by name to .f (as
purrr::pmap() does), so a job table with columns input,
output and start calls
.f(input = ..., output = ..., start = ...).
.f must return a pipeline (see ffm_files). Give
.f a ... argument if jobs carries columns it does not
use.
Two jobs whose pipelines write to the same output path are refused
before any job runs, under run = FALSE as well as run = TRUE.
Paths are compared exactly as written. An output that writes no file may
repeat. Such outputs are - (standard output), a pipe: URL, and
an output whose last -f option is -f null, as
ffm_output_options("-f null") gives.
with_timeout() explains how to limit how long R waits for each program in
a job, and what happens when a program reaches the limit.
Value
jobs as a tibble with an added
command column, which holds the compiled FFmpeg command for each
job. When run = TRUE, it also has a logical success column.
When verify is supplied, it also has a verified column.
When manifest = TRUE, a provenance manifest is attached as an
attribute; read it with ffm_manifest.
See Also
segment_video(), which is built on ffm_batch();
verify_media() for the verification spec and ffm_manifest() for the
provenance manifest.
Other pipeline functions:
ffm_codec(),
ffm_compile(),
ffm_concat(),
ffm_copy(),
ffm_crop(),
ffm_drawbox(),
ffm_drop(),
ffm_files(),
ffm_fps(),
ffm_hstack(),
ffm_jobs(),
ffm_loudnorm(),
ffm_map(),
ffm_output_options(),
ffm_overlay(),
ffm_pixel_format(),
ffm_run(),
ffm_scale(),
ffm_seek(),
ffm_trim(),
ffm_vstack(),
print.tidymedia_ffm()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
jobs <- tibble::tibble(
input = c(video, video),
output = c("a.mp3", "b.mp3")
)
# run = FALSE compiles one command per job without calling FFmpeg
ffm_batch(jobs, run = FALSE, .f = function(input, output, ...) {
ffm_files(input, output) |>
ffm_drop("video") |>
ffm_codec(audio = "libmp3lame")
})
Set Codecs in an FFmpeg Pipeline
Description
Set the audio codec, the video codec, or both, for the output file. Use
ffmpeg_codecs() to see a list of the codecs in your FFmpeg version.
The glossary in vignette("tidymedia") explains media terms such as
codec and stream copy.
Usage
ffm_codec(object, audio = NULL, video = NULL)
Arguments
object |
An FFmpeg pipeline ( |
audio |
A string that names the audio codec, or |
video |
A string that names the video codec, or |
Value
object with an added instruction to change the codecs.
References
https://ffmpeg.org/ffmpeg-codecs.html
See Also
ffm_copy(), the shortcut for stream copy, ffmpeg_codecs() to
list the codecs you can use, and standardize_video(), a task function
built on it.
Other pipeline functions:
ffm_batch(),
ffm_compile(),
ffm_concat(),
ffm_copy(),
ffm_crop(),
ffm_drawbox(),
ffm_drop(),
ffm_files(),
ffm_fps(),
ffm_hstack(),
ffm_jobs(),
ffm_loudnorm(),
ffm_map(),
ffm_output_options(),
ffm_overlay(),
ffm_pixel_format(),
ffm_run(),
ffm_scale(),
ffm_seek(),
ffm_trim(),
ffm_vstack(),
print.tidymedia_ffm()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
ffm_files(video, "output.mp4") |>
ffm_codec(video = "libx264", audio = "aac") |>
ffm_compile()
Compile the tidymedia pipeline into an FFmpeg command
Description
Compile all the instructions into one string, the FFmpeg command that runs them.
Usage
ffm_compile(object)
Arguments
object |
An FFmpeg pipeline ( |
Value
A string with the FFmpeg command that carries out all the instructions in the tidymedia pipeline.
See Also
ffm_run() to compile and run in one step, and ffm_batch() to
compile over many files.
Other pipeline functions:
ffm_batch(),
ffm_codec(),
ffm_concat(),
ffm_copy(),
ffm_crop(),
ffm_drawbox(),
ffm_drop(),
ffm_files(),
ffm_fps(),
ffm_hstack(),
ffm_jobs(),
ffm_loudnorm(),
ffm_map(),
ffm_output_options(),
ffm_overlay(),
ffm_pixel_format(),
ffm_run(),
ffm_scale(),
ffm_seek(),
ffm_trim(),
ffm_vstack(),
print.tidymedia_ffm()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
# ffm_compile() returns the reproducible FFmpeg command as a string
ffm_files(video, "output.mp4") |>
ffm_trim(start = 1, end = 5) |>
ffm_crop(width = 160, height = 120) |>
ffm_codec(video = "libx264") |>
ffm_compile()
Concatenate Multiple Inputs in an FFmpeg Pipeline
Description
Join the pipeline's input files one after another with FFmpeg's
concat demuxer. Like
ffm_hstack, this is a pipeline function for several inputs. It
uses stream copy, so it is fast and lossless. But every input must share the
same parameters, such as codec, resolution and frame rate. The glossary in
vignette("tidymedia") explains media terms such as codec, re-encode
and stream copy.
Usage
ffm_concat(object)
Arguments
object |
An FFmpeg pipeline ( |
Details
To join inputs with different parameters, you must re-encode with the concat
filter. The package does not wrap that filter yet, so use
ffmpeg.
The demuxer needs a list file that names the inputs. When you call
ffm_concat(), it writes one to a temporary path and stores it in the
pipeline, so the compiled command can refer to it. It also copies codecs and
maps all streams, as ffm_copy would.
Value
object with an added instruction to concatenate the inputs.
See Also
concatenate_videos(), the task function built on this function.
Other pipeline functions:
ffm_batch(),
ffm_codec(),
ffm_compile(),
ffm_copy(),
ffm_crop(),
ffm_drawbox(),
ffm_drop(),
ffm_files(),
ffm_fps(),
ffm_hstack(),
ffm_jobs(),
ffm_loudnorm(),
ffm_map(),
ffm_output_options(),
ffm_overlay(),
ffm_pixel_format(),
ffm_run(),
ffm_scale(),
ffm_seek(),
ffm_trim(),
ffm_vstack(),
print.tidymedia_ffm()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
# Join two inputs end-to-end (they must share codec/resolution/frame rate)
ffm_files(c(video, video), "output.mp4") |>
ffm_concat() |>
ffm_compile()
Copy the codecs and map all streams
Description
Copy the audio, the video, or both, with stream copy and no re-encoding. It
can also map all streams from the input. This is the fast, lossless path when
you only need to put the streams in a new container or cut on keyframes. The
glossary in vignette("tidymedia") explains media terms such as codec,
container, keyframe and stream copy.
Usage
ffm_copy(object, audio = TRUE, video = TRUE, streams = TRUE)
Arguments
object |
An FFmpeg pipeline ( |
audio |
A logical. |
video |
A logical. |
streams |
A logical. |
Value
object with an added instruction to copy codecs, map all
streams, or both.
See Also
ffm_codec() and ffm_map(), which ffm_copy() calls, and
segment_video(), which uses it for fast copy cuts.
Other pipeline functions:
ffm_batch(),
ffm_codec(),
ffm_compile(),
ffm_concat(),
ffm_crop(),
ffm_drawbox(),
ffm_drop(),
ffm_files(),
ffm_fps(),
ffm_hstack(),
ffm_jobs(),
ffm_loudnorm(),
ffm_map(),
ffm_output_options(),
ffm_overlay(),
ffm_pixel_format(),
ffm_run(),
ffm_scale(),
ffm_seek(),
ffm_trim(),
ffm_vstack(),
print.tidymedia_ffm()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
ffm_files(video, "output.mp4") |>
ffm_copy() |>
ffm_compile()
Crop Frames in an FFmpeg Pipeline
Description
Make the video's frames smaller by cropping them.
Usage
ffm_crop(object, width, height, x = "(in_w-out_w)/2", y = "(in_h-out_h)/2")
Arguments
object |
An FFmpeg pipeline ( |
width |
The width of the output video, in pixels. Give a positive real number or a string that contains an FFmpeg expression. |
height |
The height of the output video, in pixels. Give a positive real number or a string that contains an FFmpeg expression. |
x |
The horizontal position of the left edge of the output video, in
pixels of the input video. Give a positive real number or a string that
contains an FFmpeg expression. The default is |
y |
The vertical position of the top edge of the output video, in pixels
of the input video. Give a positive real number or a string that contains
an FFmpeg expression. The default is |
Value
object with an added instruction to crop the frames.
References
https://ffmpeg.org/ffmpeg-filters.html#crop
See Also
ffm_scale() to resize instead of crop. crop_video() and
format_for_web() are the task functions built on ffm_crop().
Other pipeline functions:
ffm_batch(),
ffm_codec(),
ffm_compile(),
ffm_concat(),
ffm_copy(),
ffm_drawbox(),
ffm_drop(),
ffm_files(),
ffm_fps(),
ffm_hstack(),
ffm_jobs(),
ffm_loudnorm(),
ffm_map(),
ffm_output_options(),
ffm_overlay(),
ffm_pixel_format(),
ffm_run(),
ffm_scale(),
ffm_seek(),
ffm_trim(),
ffm_vstack(),
print.tidymedia_ffm()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
# Crop to a centered 160x120 region
ffm_files(video, "output.mp4") |>
ffm_crop(width = 160, height = 120) |>
ffm_compile()
Draw a Colored Box on the Videos in an FFmpeg Pipeline
Description
Add a video filter that draws a colored rectangle on the input video.
Usage
ffm_drawbox(
object,
x = 0,
y = 0,
width = "in_w",
height = "in_h",
color = "black",
thickness = "fill"
)
Arguments
object |
An FFmpeg pipeline ( |
x |
The horizontal position of the left edge of the box, in pixels of
the input video. Give a nonnegative real number or a string that contains
an FFmpeg expression. The default is |
y |
The vertical position of the top edge of the box, in pixels of the
input video. Give a nonnegative real number or a string that contains an
FFmpeg expression. The default is |
width |
The width of the box, in pixels. Give a positive real number or
a string that contains an FFmpeg expression. The default is |
height |
The height of the box, in pixels. Give a positive real number
or a string that contains an FFmpeg expression. The default is
|
color |
A string with the color of the box, in FFmpeg color syntax. The
reference link below explains that syntax. With the special value
|
thickness |
The thickness of the box edge, in pixels. The value
|
Value
object with an added instruction to apply the drawbox
filter.
References
https://ffmpeg.org/ffmpeg-filters.html#drawbox
https://ffmpeg.org/ffmpeg-utils.html#color-syntax
See Also
anonymize_video(), the task function that uses
ffm_drawbox() to fill regions.
Other pipeline functions:
ffm_batch(),
ffm_codec(),
ffm_compile(),
ffm_concat(),
ffm_copy(),
ffm_crop(),
ffm_drop(),
ffm_files(),
ffm_fps(),
ffm_hstack(),
ffm_jobs(),
ffm_loudnorm(),
ffm_map(),
ffm_output_options(),
ffm_overlay(),
ffm_pixel_format(),
ffm_run(),
ffm_scale(),
ffm_seek(),
ffm_trim(),
ffm_vstack(),
print.tidymedia_ffm()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
# Draw a filled red box covering the top-left quarter of the frame
ffm_files(video, "output.mp4") |>
ffm_drawbox(width = "in_w/2", height = "in_h/2", color = "red") |>
ffm_compile()
Drop Streams from an FFmpeg Pipeline
Description
Remove one or more streams from the media file. For example, remove the
video, audio, subtitles or data stream from a media file. The glossary in
vignette("tidymedia") explains media terms such as stream.
Usage
ffm_drop(object, streams = c("video", "audio", "subtitles", "data"))
Arguments
object |
An FFmpeg pipeline ( |
streams |
A character vector with one or more of these strings:
|
Value
object with an added instruction to drop these streams from
the output file when the pipeline runs.
See Also
extract_audio(), the task function that uses ffm_drop() to
drop the video stream.
Other pipeline functions:
ffm_batch(),
ffm_codec(),
ffm_compile(),
ffm_concat(),
ffm_copy(),
ffm_crop(),
ffm_drawbox(),
ffm_files(),
ffm_fps(),
ffm_hstack(),
ffm_jobs(),
ffm_loudnorm(),
ffm_map(),
ffm_output_options(),
ffm_overlay(),
ffm_pixel_format(),
ffm_run(),
ffm_scale(),
ffm_seek(),
ffm_trim(),
ffm_vstack(),
print.tidymedia_ffm()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
# Drop the audio stream (keep video only)
ffm_files(video, "output.mp4") |>
ffm_drop(streams = "audio") |>
ffm_compile()
Specify Files in an FFmpeg Pipeline
Description
Start an FFmpeg pipeline by specifying input and output files.
Usage
ffm_files(input, output, overwrite = TRUE)
Arguments
input |
A character vector of paths to the input media files of the pipeline. Give more than one path for stacking. |
output |
A string with the path of the output media file of the pipeline. |
overwrite |
A logical. If |
Value
An FFmpeg pipeline object.
See Also
ffm_compile() to build the command and ffm_run() to run it. The
task functions, such as standardize_video() and segment_video(), are
built on the pipeline functions.
Other pipeline functions:
ffm_batch(),
ffm_codec(),
ffm_compile(),
ffm_concat(),
ffm_copy(),
ffm_crop(),
ffm_drawbox(),
ffm_drop(),
ffm_fps(),
ffm_hstack(),
ffm_jobs(),
ffm_loudnorm(),
ffm_map(),
ffm_output_options(),
ffm_overlay(),
ffm_pixel_format(),
ffm_run(),
ffm_scale(),
ffm_seek(),
ffm_trim(),
ffm_vstack(),
print.tidymedia_ffm()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
ffm_files(video, "output.mp4") |>
ffm_compile()
Set the Frame Rate in an FFmpeg Pipeline
Description
Resample the video to a constant frame rate with FFmpeg's fps filter.
The filter duplicates or drops frames as needed. It is added to the end of
the video filters, like the other filters that take one input. The glossary
in vignette("tidymedia") explains media terms such as frame rate.
Usage
ffm_fps(object, fps)
Arguments
object |
An FFmpeg pipeline ( |
fps |
The target frame rate. Give a positive real number of frames per
second, or a string that contains an FFmpeg frame rate expression. For
example, |
Value
object with an added instruction to resample the frame rate.
See Also
standardize_video(), the task function that uses ffm_fps()
to set the frame rate.
Other pipeline functions:
ffm_batch(),
ffm_codec(),
ffm_compile(),
ffm_concat(),
ffm_copy(),
ffm_crop(),
ffm_drawbox(),
ffm_drop(),
ffm_files(),
ffm_hstack(),
ffm_jobs(),
ffm_loudnorm(),
ffm_map(),
ffm_output_options(),
ffm_overlay(),
ffm_pixel_format(),
ffm_run(),
ffm_scale(),
ffm_seek(),
ffm_trim(),
ffm_vstack(),
print.tidymedia_ffm()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
ffm_files(video, "output.mp4") |>
ffm_fps(fps = 30) |>
ffm_compile()
Horizontally Stack Multiple Videos in an FFmpeg Pipeline
Description
Add a complex video filter that stacks several videos horizontally (side by side). It can also resize the videos to the same height.
Usage
ffm_hstack(object, shortest = FALSE, resize = FALSE)
Arguments
object |
An FFmpeg pipeline ( |
shortest |
A logical that says whether to trim the duration of all
videos to that of the shortest video. The default is |
resize |
A logical that says whether to resize the input videos to the same height. Resizing takes longer, and for now it works only with two inputs. It fits both inputs to the same aspect ratio, so it assumes the inputs share one. |
Value
object with an added instruction to stack the videos
horizontally.
See Also
ffm_vstack() for vertical stacking, and compare_videos(), the
task function built on both.
Other pipeline functions:
ffm_batch(),
ffm_codec(),
ffm_compile(),
ffm_concat(),
ffm_copy(),
ffm_crop(),
ffm_drawbox(),
ffm_drop(),
ffm_files(),
ffm_fps(),
ffm_jobs(),
ffm_loudnorm(),
ffm_map(),
ffm_output_options(),
ffm_overlay(),
ffm_pixel_format(),
ffm_run(),
ffm_scale(),
ffm_seek(),
ffm_trim(),
ffm_vstack(),
print.tidymedia_ffm()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
# Stack two inputs side-by-side (pass more than one input to ffm_files())
ffm_files(c(video, video), "output.mp4") |>
ffm_hstack() |>
ffm_compile()
Build a Jobs Table From a Directory
Description
List the media files in a directory and return them as a jobs table for
ffm_batch(). The table is a tibble with one row per file and an
input column of full paths. Start a batch here, instead of with your
own list.files() call.
Usage
ffm_jobs(directory, type, extension = NULL, recursive = FALSE)
Arguments
directory |
A single string naming an existing directory. |
type |
The media category to list, one of |
extension |
An optional character vector of file extensions narrowing
the search within |
recursive |
A logical: descend into subdirectories ( |
Details
The table has only the input column. ffm_batch() passes every column
of the jobs table to .f by name. So if .f has no argument for a
column, and no ... argument, the batch stops with R's "unused
argument" error.
Add the columns your pipeline needs with the usual data-frame tools. Some
*_batch() task functions need an output column. Others need
columns for their task, such as start and end. The examples
below make an output column from input.
crop_video_batch() and extract_audio_batch() handle the other columns of
the table as follows:
They read a column named like one of their per-row arguments in place of that argument, row by row. Each help page lists these arguments. Examples are a
widthcolumn incrop_video_batch()and anaudio_codeccolumn inextract_audio_batch().They replace a column named like one that
ffm_batch()adds. For example, the compiled command replaces acommandcolumn. The Value section offfm_batch()lists the added columns.They return every other column unchanged.
Value
A tibble with one row per matching file
and one character column, input, with each file's full path. Files
whose names start with a dot are left out. Rows are in the order
list.files returns them.
Every row is a path that exists and is not a directory. A subdirectory
whose own name ends in a listed extension is never a row. On macOS and
Linux, a symbolic link whose target is gone is never a row either.
Windows reports such a link as existing, so there it can still be a row.
The call gives an error, instead of zero rows, when nothing matches. With
recursive = TRUE the search follows a symbolic link to a directory,
so a row can name a file outside directory.
The scanned extensions include .mka as audio and .ts as
video. separate_audio_video() recommends .mka or .m4a for
multi-track audio, and this function reads both as audio, so it lists a
folder of that output. Not every container that can hold several audio
streams is audio here. .ts, like .mp4 and .mkv, is
video, so multi-track audio written to one of those is a row under
type = "video". The name .ts also belongs to TypeScript
source files, and this function reads names rather than file contents. A
folder of TypeScript sources therefore comes back as video rows when you
ask for type = "video".
See Also
ffm_batch(), which consumes the returned table.
Other pipeline functions:
ffm_batch(),
ffm_codec(),
ffm_compile(),
ffm_concat(),
ffm_copy(),
ffm_crop(),
ffm_drawbox(),
ffm_drop(),
ffm_files(),
ffm_fps(),
ffm_hstack(),
ffm_loudnorm(),
ffm_map(),
ffm_output_options(),
ffm_overlay(),
ffm_pixel_format(),
ffm_run(),
ffm_scale(),
ffm_seek(),
ffm_trim(),
ffm_vstack(),
print.tidymedia_ffm()
Examples
folder <- system.file("extdata", package = "tidymedia")
jobs <- ffm_jobs(folder, type = "video")
jobs
# Derive an output column, then hand the whole table to ffm_batch().
# Two inputs sharing a name (a.mp4 and a.mkv) would derive one output here;
# ffm_batch() refuses jobs that share an output before any of them runs.
jobs$output <- file.path(tempdir(), paste0(
tools::file_path_sans_ext(basename(jobs$input)), ".mp3"
))
ffm_batch(jobs, run = FALSE, .f = function(input, output, ...) {
ffm_files(input, output) |> ffm_drop("video")
})
Normalize Loudness in an FFmpeg Pipeline
Description
Add FFmpeg's loudnorm (EBU R128) audio filter. It normalizes the
input's perceived loudness toward a target integrated loudness, true-peak
ceiling and loudness range. The filter compiles to -af, or joins an
existing audio filter chain in the order the filters were added. The glossary
in vignette("tidymedia") explains media terms such as LUFS and true
peak.
Usage
ffm_loudnorm(
object,
target_loudness = -23,
true_peak = -1,
loudness_range = 7,
measured_i = NULL,
measured_tp = NULL,
measured_lra = NULL,
measured_thresh = NULL,
offset = NULL,
linear = FALSE,
print_format = NULL
)
Arguments
object |
An FFmpeg pipeline ( |
target_loudness |
The target integrated loudness, in LUFS
(a number in |
true_peak |
The maximum true peak, in dBTP
(a number in |
loudness_range |
The target loudness range, in LU
(a number in |
measured_i, measured_tp, measured_lra, measured_thresh |
Measured input
values from an earlier |
offset |
The |
linear |
A logical. |
print_format |
The format of the measurement report for an analysis
pass: |
Details
This is single-pass (dynamic) loudnorm. The pipeline stays one
reproducible command, with no measurement pass. The defaults follow EBU
Recommendation R 128 (2014): target_loudness = -23 LUFS and
true_peak = -1 dBTP. Loudness is measured per ITU-R BS.1770-4. The
default
loudness_range = 7 is FFmpeg's own loudnorm default. EBU
R128 does not prescribe a single value.
Two filters are added, not one. loudnorm is followed by
asetnsamples, which regroups the filtered audio into frames of 4096
samples and does not pad the last one. Dynamic loudnorm resamples to
192 kHz and gives frames of 192000 samples. Some encoders accept whatever
frame they are given, FLAC and Vorbis among them. Even those encoders refuse
to open at all on frames of 192000 samples.
Value
object with an added instruction to normalize loudness.
References
EBU Recommendation R 128 (2014), Loudness normalisation and permitted maximum level of audio signals; ITU-R BS.1770-4. https://ffmpeg.org/ffmpeg-filters.html#loudnorm
See Also
normalize_audio(), the task function built on this filter.
Other pipeline functions:
ffm_batch(),
ffm_codec(),
ffm_compile(),
ffm_concat(),
ffm_copy(),
ffm_crop(),
ffm_drawbox(),
ffm_drop(),
ffm_files(),
ffm_fps(),
ffm_hstack(),
ffm_jobs(),
ffm_map(),
ffm_output_options(),
ffm_overlay(),
ffm_pixel_format(),
ffm_run(),
ffm_scale(),
ffm_seek(),
ffm_trim(),
ffm_vstack(),
print.tidymedia_ffm()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
ffm_files(video, "output.mp4") |>
ffm_loudnorm() |>
ffm_compile()
Read a Batch Provenance Manifest
Description
Retrieve the reproducibility manifest recorded by ffm_batch() when it was
run with manifest = TRUE. The manifest is a tibble with one row per
job. Each row has the compiled command and the FFmpeg and FFprobe versions
used. It also has the time of the run, the input and output paths, and the
output file size.
When the batch ran with checksums = TRUE, each row also has md5
checksums of the input and output files. With the manifest, a batch run
leaves a record that others can check.
Usage
ffm_manifest(x, path = NULL)
Arguments
x |
A tibble returned by |
path |
An optional file path. When supplied, the manifest is also
written there as CSV (via |
Value
The manifest tibble; invisibly when
path is written.
See Also
ffm_batch(), which records the manifest.
Other verification functions:
verify_media()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
jobs <- tibble::tibble(input = video, output = tempfile(fileext = ".mp3"))
res <- ffm_batch(jobs, manifest = TRUE, .f = function(input, output, ...) {
ffm_files(input, output) |> ffm_drop("video")
})
ffm_manifest(res)
Set the Stream Mapping in an FFmpeg Pipeline
Description
Choose which input streams go into the output, with FFmpeg's -map
option. The default, "0", maps every stream from the first input. The
glossary in vignette("tidymedia") explains media terms such as stream.
Usage
ffm_map(object, mapping = "0", replace = FALSE)
Arguments
object |
An FFmpeg pipeline ( |
mapping |
A character vector of one or more stream specifiers. Each one
adds one |
replace |
A logical. |
Details
mapping can be a character vector. Each element adds one -map,
in the order given. For example, ffm_map(object, c("0:v", "0:a:1"))
keeps the video and the second audio track of the input.
A second ffm_map() call adds to the maps already set. It does
not replace them. Pass replace = TRUE to discard them instead. That is
how you narrow the all-streams map that ffm_copy sets. Adding
to that map puts the stream in the output twice, and does not select it.
ffm_map() is the only pipeline function that adds to earlier calls.
Every other ffm_* function that sets a value, ffm_copy
included, replaces it. ffm_map() is different because its arguments
are partial choices that combine. For example, you keep the video,
then name one audio track.
When the pipeline uses a function with several inputs, such as
ffm_hstack, your mapping is added beside the automatic
-map "[vout]" of the filtered stream. For example,
ffm_map(object, "0:a") keeps the audio of the first input next to the
stacked video.
Value
object with an added instruction to map streams.
See Also
ffm_copy(), which maps all streams, and separate_audio_video(),
a task function built on ffm_map().
Other pipeline functions:
ffm_batch(),
ffm_codec(),
ffm_compile(),
ffm_concat(),
ffm_copy(),
ffm_crop(),
ffm_drawbox(),
ffm_drop(),
ffm_files(),
ffm_fps(),
ffm_hstack(),
ffm_jobs(),
ffm_loudnorm(),
ffm_output_options(),
ffm_overlay(),
ffm_pixel_format(),
ffm_run(),
ffm_scale(),
ffm_seek(),
ffm_trim(),
ffm_vstack(),
print.tidymedia_ffm()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
ffm_files(video, "output.mp4") |>
ffm_map(mapping = "0") |>
ffm_compile()
# Keep the video and the second audio track only
ffm_files(video, "output.mkv") |>
ffm_map(mapping = c("0:v", "0:a:1")) |>
ffm_compile()
Add Raw Output Options to an FFmpeg Pipeline
Description
Add one or more raw FFmpeg output options to the pipeline, after any added
before. Output options are the flags after the input and before the output
file. Use this function for an option that has no pipeline function of its
own. ffm_compile() still decides where the options go and how the rest
of the command is quoted. So this is not the same as writing the command
string yourself.
Usage
ffm_output_options(object, ...)
Arguments
object |
An FFmpeg pipeline ( |
... |
One or more strings. Each string is a group of options separated
by white space, for example |
Value
object with the added output options.
See Also
ffmpeg(), the direct command that takes any FFmpeg arguments, and
ffm_compile(), which places these options.
Other pipeline functions:
ffm_batch(),
ffm_codec(),
ffm_compile(),
ffm_concat(),
ffm_copy(),
ffm_crop(),
ffm_drawbox(),
ffm_drop(),
ffm_files(),
ffm_fps(),
ffm_hstack(),
ffm_jobs(),
ffm_loudnorm(),
ffm_map(),
ffm_overlay(),
ffm_pixel_format(),
ffm_run(),
ffm_scale(),
ffm_seek(),
ffm_trim(),
ffm_vstack(),
print.tidymedia_ffm()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
# Extract a single frame by adding a raw output option
ffm_files(video, "frame.png") |>
ffm_output_options("-frames:v 1") |>
ffm_compile()
Overlay One Video on Another in an FFmpeg Pipeline
Description
Draw the second input (the overlay) on top of the first input (the main
video) at position x and y. Like ffm_hstack, this
is a pipeline function for several inputs. It forces the
-filter_complex path and manages its own stream labels internally. It
needs exactly two inputs. The first is the background, and the second is
drawn over it. The glossary in vignette("tidymedia") explains media
terms such as stream.
Usage
ffm_overlay(object, x = 0, y = 0, shortest = FALSE, scale = NULL)
Arguments
object |
An FFmpeg pipeline ( |
x |
The horizontal position of the overlay's left edge, as a number of
pixels or an FFmpeg expression. The default is |
y |
The vertical position of the overlay's top edge, as a number of
pixels or an FFmpeg expression. The default is |
shortest |
A logical that says whether to end the output when the
shorter input ends. The default is |
scale |
An optional fraction ( |
Details
x and y accept plain numbers or FFmpeg overlay expressions. A
plain number counts pixels from the top-left of the main video. In an
expression, main_w and main_h are the main video's dimensions.
overlay_w and overlay_h are the overlay's dimensions. For
example, x = "main_w-overlay_w-16" puts the overlay 16 pixels from the
right edge.
When scale is set, the overlay is first resized to a fraction of the
main video's width, and its aspect ratio is kept. The task function
picture_in_picture uses this resize. Otherwise, to resize the
overlay yourself, filter it in a separate pipeline first.
Value
object with an added instruction to draw the second input on
the first.
See Also
picture_in_picture(), the task function built on this function.
Other pipeline functions:
ffm_batch(),
ffm_codec(),
ffm_compile(),
ffm_concat(),
ffm_copy(),
ffm_crop(),
ffm_drawbox(),
ffm_drop(),
ffm_files(),
ffm_fps(),
ffm_hstack(),
ffm_jobs(),
ffm_loudnorm(),
ffm_map(),
ffm_output_options(),
ffm_pixel_format(),
ffm_run(),
ffm_scale(),
ffm_seek(),
ffm_trim(),
ffm_vstack(),
print.tidymedia_ffm()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
# Draw the second input over the first, 16px in from the top-right corner
ffm_files(c(video, video), "output.mp4") |>
ffm_overlay(x = "main_w-overlay_w-16", y = 16) |>
ffm_compile()
Set the Pixel Format in an FFmpeg Pipeline
Description
Set the pixel format of the output with FFmpeg's -pix_fmt option. For
example, use "yuv420p" for broad player compatibility. The glossary in
vignette("tidymedia") explains media terms such as pixel format.
Usage
ffm_pixel_format(object, format)
Arguments
object |
An FFmpeg pipeline ( |
format |
A string that names the pixel format of the output file. |
Value
object with an added instruction to set the pixel format.
See Also
standardize_video() and format_for_web(), the task functions
that use ffm_pixel_format() to set the pixel format.
Other pipeline functions:
ffm_batch(),
ffm_codec(),
ffm_compile(),
ffm_concat(),
ffm_copy(),
ffm_crop(),
ffm_drawbox(),
ffm_drop(),
ffm_files(),
ffm_fps(),
ffm_hstack(),
ffm_jobs(),
ffm_loudnorm(),
ffm_map(),
ffm_output_options(),
ffm_overlay(),
ffm_run(),
ffm_scale(),
ffm_seek(),
ffm_trim(),
ffm_vstack(),
print.tidymedia_ffm()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
ffm_files(video, "output.mp4") |>
ffm_pixel_format("yuv420p") |>
ffm_compile()
Run the FFmpeg Pipeline
Description
Compile the instructions in the pipeline and run them all through FFmpeg.
Usage
ffm_run(object, verify = NULL)
Arguments
object |
An FFmpeg pipeline ( |
verify |
An optional named list of the properties you expect the output
to have, for example |
Value
FFmpeg's standard output as a character vector, returned invisibly.
On a non-zero exit it has a status attribute. You call
ffm_run() to write the output file, not for its return value. The
pipeline runs as a vector of arguments and never through a shell. So paths
with spaces or special characters are safe.
When FFmpeg exits non-zero
If FFmpeg refuses a run, ffm_run() gives an error of class
tidymedia_ffmpeg_exit. A caller can catch a failed run without
reading the error text:
tryCatch( ffm_run(pipeline), tidymedia_ffmpeg_exit = function(cnd) cnd$tm_status )
The tm_status field is one integer, the exit status exactly as
system2() reported it. If a signal stopped FFmpeg, the field holds
the shell's number, 128 plus the signal number, unchanged. That number
stands for the signal, not for a status FFmpeg chose to return.
Two other paths give this class and carry this field, so one handler covers all three:
the
loudnormanalysis pass ofnormalize_audio(two_pass = TRUE), when FFmpeg exits non-zero.the error about several audio tracks that
separate_audio_videoadds to a failed audio output.
Each of those two paths also gives a second, narrower class before this one.
In the same order, they are tidymedia_loudnorm_no_measurement and
tidymedia_multitrack_separation. Catch that class when you want only
that failure.
Two related paths do not give this class, each for its own reason:
-
normalize_audio(two_pass = TRUE)also gives an error when the analysis pass exits zero and prints no measurement block that can be read. FFmpeg did not exit non-zero there. So that error has only the classtidymedia_loudnorm_no_measurement, and notm_status. -
normalize_audio_batch(two_pass = TRUE)reports in one error every row that failed in its analysis phase. The failed rows can include rows that exited zero and rows that FFmpeg refused. So a non-zero exit is one of its causes, not the fact it reports, and no single status can stand for the mix. It also has only the classtidymedia_loudnorm_no_measurement. It carriestm_rows, the failed rows counted from 1. It also carriestm_row_status, their exit statuses in the same order, withNAwhere a row exited zero.
So tidymedia_loudnorm_no_measurement is the one class that covers
the analysis pass in both forms.
See Also
ffm_compile() to get the command without running it, ffm_batch()
to run many files, and verify_media() for the verify list.
Other pipeline functions:
ffm_batch(),
ffm_codec(),
ffm_compile(),
ffm_concat(),
ffm_copy(),
ffm_crop(),
ffm_drawbox(),
ffm_drop(),
ffm_files(),
ffm_fps(),
ffm_hstack(),
ffm_jobs(),
ffm_loudnorm(),
ffm_map(),
ffm_output_options(),
ffm_overlay(),
ffm_pixel_format(),
ffm_scale(),
ffm_seek(),
ffm_trim(),
ffm_vstack(),
print.tidymedia_ffm()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
out <- tempfile(fileext = ".mp4")
ffm_files(video, out) |>
ffm_scale(width = 160, height = 120) |>
ffm_codec(video = "libx264") |>
ffm_run(verify = list(width = 160, height = 120))
Scale (Resize) Frames in an FFmpeg Pipeline
Description
Scale (resize) the input video's frames to a width and height in pixels, or with an FFmpeg expression.
Usage
ffm_scale(object, width, height)
Arguments
object |
An FFmpeg pipeline ( |
width |
The width of the output video, in pixels. Give a positive real number or a string that contains an FFmpeg expression. |
height |
The height of the output video, in pixels. Give a positive real number or a string that contains an FFmpeg expression. |
Value
object with an added instruction to resize the frames.
See Also
ffm_crop() to crop instead of resize. standardize_video() is the
task function built on ffm_scale().
Other pipeline functions:
ffm_batch(),
ffm_codec(),
ffm_compile(),
ffm_concat(),
ffm_copy(),
ffm_crop(),
ffm_drawbox(),
ffm_drop(),
ffm_files(),
ffm_fps(),
ffm_hstack(),
ffm_jobs(),
ffm_loudnorm(),
ffm_map(),
ffm_output_options(),
ffm_overlay(),
ffm_pixel_format(),
ffm_run(),
ffm_seek(),
ffm_trim(),
ffm_vstack(),
print.tidymedia_ffm()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
ffm_files(video, "output.mp4") |>
ffm_scale(width = 160, height = 120) |>
ffm_compile()
Cut a Continuous Section from an FFmpeg Pipeline by Seeking
Description
Keep one continuous section of the input with FFmpeg's fast -ss and
-to seek options. It does not use the trim filter of
ffm_trim. Unlike the filter, seeking can use stream copy, so it
is the tool for fast, lossless cuts. The glossary in
vignette("tidymedia") explains media terms such as keyframe,
re-encode and stream copy.
Usage
ffm_seek(object, start = NULL, end = NULL, reencode = TRUE)
Arguments
object |
An FFmpeg pipeline ( |
start |
The start of the kept section, in seconds or in FFmpeg time
duration syntax. |
end |
The end of the kept section, in seconds or in FFmpeg time duration
syntax. |
reencode |
A logical. |
Details
The reencode argument trades accuracy against speed:
-
reencode = TRUE(the default) is frame-accurate. The section is re-encoded, so it starts and ends on the exact frames you ask for. This is the safe default. -
reencode = FALSEis a fast, lossless copy. But the cut points move to the nearest keyframes. So the output duration can differ from the request by up to the gap between two keyframes. Use it withffm_copyfor the fastest path.
Value
object with an added instruction to cut the input by seeking.
References
https://ffmpeg.org/ffmpeg.html#Main-options
See Also
ffm_trim() for the filter that cuts, ffm_copy() for the fast
copy path, and segment_video(), the task function built on it.
Other pipeline functions:
ffm_batch(),
ffm_codec(),
ffm_compile(),
ffm_concat(),
ffm_copy(),
ffm_crop(),
ffm_drawbox(),
ffm_drop(),
ffm_files(),
ffm_fps(),
ffm_hstack(),
ffm_jobs(),
ffm_loudnorm(),
ffm_map(),
ffm_output_options(),
ffm_overlay(),
ffm_pixel_format(),
ffm_run(),
ffm_scale(),
ffm_trim(),
ffm_vstack(),
print.tidymedia_ffm()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
# Fast, lossless copy cut (snaps to keyframes)
ffm_files(video, "output.mp4") |>
ffm_seek(start = 1, end = 5, reencode = FALSE) |>
ffm_copy() |>
ffm_compile()
Trim the Duration of the FFmpeg Pipeline
Description
Trim the input so that the output keeps one continuous part of the input. If
start is NULL, the kept section starts at the beginning of the
input. If both end and duration are NULL, the kept
section ends at the end of the input. The glossary in
vignette("tidymedia") explains media terms such as stream copy.
Usage
ffm_trim(
object,
start = NULL,
end = NULL,
duration = NULL,
units = c("tds", "pts", "frame"),
setpts = TRUE
)
Arguments
object |
An FFmpeg pipeline ( |
start |
The time of the start of the kept section, given in
|
end |
The time of the first frame that is dropped, given in
|
duration |
The maximum duration of the output, given in time duration syntax. |
units |
A string that says how |
setpts |
A logical that says whether the output timestamps change to
start at zero. If |
Value
object with added instructions to trim the duration.
References
https://ffmpeg.org/ffmpeg-filters.html#trim
https://ffmpeg.org/ffmpeg-utils.html#time-duration-syntax
See Also
ffm_seek(), the faster cut by seeking, which can use stream copy.
ffm_trim() is the filter that cuts on exact frames.
Other pipeline functions:
ffm_batch(),
ffm_codec(),
ffm_compile(),
ffm_concat(),
ffm_copy(),
ffm_crop(),
ffm_drawbox(),
ffm_drop(),
ffm_files(),
ffm_fps(),
ffm_hstack(),
ffm_jobs(),
ffm_loudnorm(),
ffm_map(),
ffm_output_options(),
ffm_overlay(),
ffm_pixel_format(),
ffm_run(),
ffm_scale(),
ffm_seek(),
ffm_vstack(),
print.tidymedia_ffm()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
ffm_files(video, "output.mp4") |>
ffm_trim(start = 1, end = 5) |>
ffm_compile()
Vertically Stack Multiple Videos in an FFmpeg Pipeline
Description
Add a complex video filter that stacks several videos vertically (one above the other). It can also resize the videos to the same width.
Usage
ffm_vstack(object, shortest = FALSE, resize = FALSE)
Arguments
object |
An FFmpeg pipeline ( |
shortest |
A logical that says whether to trim the duration of all
videos to that of the shortest video. The default is |
resize |
A logical that says whether to resize the input videos to the same width. Resizing takes longer, and for now it works only with two inputs. It fits both inputs to the same aspect ratio, so it assumes the inputs share one. |
Details
This is the vertical form of ffm_hstack. Both are pipeline
functions for several inputs. They force the -filter_complex path and
manage their own stream labels internally. The glossary in
vignette("tidymedia") explains media terms such as stream.
Value
object with an added instruction to stack the videos
vertically.
See Also
ffm_hstack() for horizontal stacking, and compare_videos(), the
task function built on both.
Other pipeline functions:
ffm_batch(),
ffm_codec(),
ffm_compile(),
ffm_concat(),
ffm_copy(),
ffm_crop(),
ffm_drawbox(),
ffm_drop(),
ffm_files(),
ffm_fps(),
ffm_hstack(),
ffm_jobs(),
ffm_loudnorm(),
ffm_map(),
ffm_output_options(),
ffm_overlay(),
ffm_pixel_format(),
ffm_run(),
ffm_scale(),
ffm_seek(),
ffm_trim(),
print.tidymedia_ffm()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
# Stack two inputs one above the other (pass more than one input to ffm_files())
ffm_files(c(video, video), "output.mp4") |>
ffm_vstack() |>
ffm_compile()
Run a raw FFmpeg command
Description
Send a raw argument string to the FFmpeg command-line program. This is a direct command. The function passes the string to FFmpeg unchanged, after the path of the FFmpeg program. So you are responsible for the quoting and the order of the options.
Usage
ffmpeg(command)
Arguments
command |
A string containing the arguments to pass to FFmpeg. |
Value
A character vector containing the text output by FFmpeg.
See Also
ffmpeg_codecs() and ffmpeg_encoders() ask FFmpeg what it
supports. The ffm_*() pipeline functions, such as
ffm_run(), are a safer way to build a command.
Other direct command functions:
ffprobe(),
mediainfo()
Examples
# A direct command: the function passes the string to FFmpeg unchanged
ffmpeg("-version")
Get a data frame of all installed codecs
Description
Ask FFmpeg for its list of installed codecs, and return the list as a data
frame with information about each codec. The glossary in
vignette("tidymedia") explains media terms such as codec and encoder.
Usage
ffmpeg_codecs(sort_by_type = TRUE)
Arguments
sort_by_type |
A logical. |
Value
A tibble with the following variables:
name |
A character vector including the name/code of each codec |
details |
A character vector including details about each codec |
type |
A factor vector indicating whether each codec supports
|
decoding |
A logical vector indicating whether each codec supports decoding |
encoding |
A logical vector indicating whether each codec supports encoding |
intraframe |
A logical vector indicating whether each codec is an intra-frame-only codec |
lossy |
A logical vector indicating whether each codec supports lossy compression |
lossless |
A logical vector indicating whether each codec supports lossless compression |
See Also
ffmpeg_encoders() for the encoder list, ffm_codec() to set a
codec in a pipeline, and ffmpeg() for the direct command.
Other capability functions:
ffmpeg_encoders(),
hardware_encoder(),
refresh_ffmpeg_capabilities()
Examples
head(ffmpeg_codecs())
ffmpeg_codecs(sort_by_type = FALSE)
Get a data frame of all installed encoders
Description
Ask FFmpeg for its list of installed encoders, and return the list as a data
frame with information about each encoder. The glossary in
vignette("tidymedia") explains media terms such as codec and encoder.
Usage
ffmpeg_encoders(sort_by_type = TRUE)
Arguments
sort_by_type |
A logical. |
Value
A tibble with the following variables:
name |
A character vector including the name/code of each encoder |
details |
A character vector including details about each encoder |
type |
A factor vector indicating whether each encoder supports
|
frame_mt |
A logical vector indicating whether each encoder supports frame-level multithreading |
slice_mt |
A logical vector indicating whether each encoder supports slice-level multithreading |
experimental |
A logical vector indicating whether each encoder is experimental |
horiz_band |
A logical vector indicating whether each encoder supports draw_horiz_band |
direct_render |
A logical vector indicating whether each encoders supports direct rending method 1 |
See Also
ffmpeg_codecs() for the codec list, ffm_codec() to set a codec
in a pipeline, and ffmpeg() for the direct command.
Other capability functions:
ffmpeg_codecs(),
hardware_encoder(),
refresh_ffmpeg_capabilities()
Examples
head(ffmpeg_encoders())
ffmpeg_encoders(sort_by_type = FALSE)
Send a command to the FFprobe program
Description
ffprobe() runs the FFprobe program with the arguments in command and
returns its output. FFprobe reads information about media files.
Usage
ffprobe(command)
Arguments
command |
A string with the arguments to give FFprobe. |
Details
ffprobe() is a direct command. The package passes command to FFprobe
exactly as you wrote it, so you must add any quotes that it needs. To get
tibbles instead, use probe_all() and the other probe_*() functions. These
functions quote their arguments for you.
Value
A character vector with the text that FFprobe writes to standard
output, one element for each line. Messages on standard error, such as
FFprobe's banner and errors, are not returned. On macOS and Linux, a
shell redirect such as 2>&1 in command returns them too.
See Also
probe_all() and the other probe_*() functions, which return
tibbles.
Other direct command functions:
ffmpeg(),
mediainfo()
Examples
ffprobe("-version")
Find the location of a dependency program
Description
Each of these functions returns the location of one program as a string:
find_ffmpeg(), find_ffprobe(), find_ffplay() and find_mediainfo().
Usage
find_ffmpeg()
find_mediainfo()
find_ffprobe()
find_ffplay()
Details
The function looks on the PATH first. If the program is not there, the
function reads the location that set_program() saved. That location is in
a file under tools::R_user_dir("tidymedia", "config"). If neither place has
the program, the function gives a warning and returns NULL.
Value
The location of the program as a string, or NULL when it could
not be found.
Problems with a saved location
A saved location that no longer works gives a warning, and the function
returns NULL. The warning has one of two classes that you can catch:
-
tidymedia_location_gone: the function read the location, but no program is there now. The condition holds the program name intm_programand the location intm_location. -
tidymedia_location_unreadable: the file does not hold exactly one location. It is empty, has more than one line, or has one empty line. The condition holds the program name intm_programand the file intm_file.
A line that holds only spaces counts as a location. So it gives
tidymedia_location_gone, not tidymedia_location_unreadable.
To fix either problem, forget the location with unset_program(), or
replace it with set_program().
Locations saved by earlier versions
Versions of the package before 0.2.0 saved locations in a different folder,
rappdirs::user_config_dir("tidymedia", "R"). The functions still read a
file in that folder. They read it only when the current folder has no file
for the program. program_status() looks in the same places, in the same
order.
A tidymedia_location_unreadable warning names the file that the function
read. That file can be the one in the old folder.
set_program() writes to the current folder only. After it writes a file
for a program, the old file for that program is not read.
unset_program() removes the file in both folders. So the old location does
not come back after the current file is gone.
See Also
set_program() to save the location of a program that is not on
the PATH, and install_on_win() to download FFmpeg on Windows.
Other program management functions:
install_on_win(),
program_status(),
set_program(),
unset_program()
Examples
# Returns the path to the binary, or NULL with a warning if it is not found
find_ffmpeg()
find_mediainfo()
Re-encode a video for web playback
Description
Re-encode a video into a widely compatible, web-friendly form: H.264 video
with yuv420p and +faststart, and AAC audio. Odd dimensions are
padded down to even values, as the codec requires. The glossary in
vignette("tidymedia") explains media terms such as codec, pixel format
and re-encode.
Usage
format_for_web(
infile,
outfile,
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. |
hardware |
The encoder backend. |
fallback |
A logical. When a |
quality |
A number, or |
audio_stream |
The audio track to carry into the output, as a number that counts from |
run |
A logical: run the command through FFmpeg ( |
Value
The compiled FFmpeg command (invisibly when run = TRUE).
See Also
ffm_codec() and ffm_pixel_format(), among the pipeline functions
it wraps;
has_hardware_encoder() for the hardware toggle;
standardize_video() for a configurable re-encode;
format_for_web_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_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(),
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_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")
format_for_web(video, "web.mp4", run = FALSE)
Re-encode Many Videos for the Web From a Jobs Table
Description
Re-encode many videos into a widely compatible, web-friendly form, using one
jobs table. This is the batch form of format_for_web(), for when you
have more than one file. Each row is one input. The function is a thin
wrapper over ffm_batch. It builds one reproducible command for
each input. Each command uses the same fixed H.264, AAC and
+faststart steps as format_for_web(), with no per-row settings.
The glossary in vignette("tidymedia") explains media terms such as
codec and re-encode.
Usage
format_for_web_batch(
jobs,
hardware = c("none", "nvenc", "videotoolbox"),
fallback = FALSE,
quality = NULL,
audio_stream = NULL,
run = TRUE,
parallel = FALSE,
...
)
Arguments
jobs |
A data frame with one row per input. It needs at least an
|
hardware |
The encoder backend for every row. |
fallback |
A logical. When a |
quality |
A number, or |
audio_stream |
The audio track to carry into each output, as a number that counts from |
run |
A logical: run each command through FFmpeg ( |
parallel |
A logical: process the jobs in parallel with furrr
( |
... |
Additional arguments forwarded to |
Value
The jobs tibble with an added command column. When run = TRUE, it also has a success column, plus verified or a provenance manifest, each when requested through .... See ffm_batch.
See Also
format_for_web(), the single-input form it wraps;
ffm_batch(), the batch runner; standardize_video_batch() for a configurable re-encode.
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(),
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(),
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(),
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")
jobs <- tibble::tibble(input = c(video, video), output = c("a.mp4", "b.mp4"))
format_for_web_batch(jobs, run = FALSE)
Get the duration of a media file
Description
get_duration() uses the MediaInfo program to look up the duration of a
media file. You choose the section of the file and the unit.
Usage
get_duration(
file,
section = c("General", "Video", "Audio"),
unit = c("ms", "sec", "min", "hour")
)
Arguments
file |
A character vector of one or more media file paths. |
section |
A string indicating the MediaInfo section from which to query
the duration value. Can be either |
unit |
A string indicating whether the duration should be returned in
milliseconds ( |
Details
The function returns one number for each file. The probe_*() functions,
mediainfo_query() and mediainfo_template() return tibbles instead.
Value
A double vector (one per file) giving the duration of the specified section in the specified units.
See Also
mediainfo_parameter() for arbitrary MediaInfo fields, and
probe_all() to read information with FFprobe.
Other metadata functions:
get_frame_rate(),
get_height(),
get_sample_rate(),
get_width(),
mediainfo_parameter(),
mediainfo_query(),
mediainfo_template(),
probe_all(),
probe_container()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
get_duration(video, unit = "sec")
Get the video frame rate of a media file
Description
get_frame_rate() uses the MediaInfo program to look up the video frame
rate of a media file, in frames per second (fps). The glossary in
vignette("tidymedia") explains media terms such as frame rate.
Usage
get_frame_rate(file)
Arguments
file |
A character vector of one or more media file paths. |
Details
The function returns one number for each file. The probe_*() functions,
mediainfo_query() and mediainfo_template() return tibbles instead.
Value
A double vector (one per file) giving the video frame rate in fps.
See Also
mediainfo_parameter() for arbitrary MediaInfo fields, and
probe_all() to read information with FFprobe.
Other metadata functions:
get_duration(),
get_height(),
get_sample_rate(),
get_width(),
mediainfo_parameter(),
mediainfo_query(),
mediainfo_template(),
probe_all(),
probe_container()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
get_frame_rate(video)
Get the video height of a media file
Description
get_height() uses the MediaInfo program to look up the video height of a
media file, in pixels (px).
Usage
get_height(file)
Arguments
file |
A character vector of one or more media file paths. |
Details
The function returns one number for each file. The probe_*() functions,
mediainfo_query() and mediainfo_template() return tibbles instead.
Value
A double vector (one per file) giving the video height in px.
See Also
mediainfo_parameter() for arbitrary MediaInfo fields, and
probe_all() to read information with FFprobe.
Other metadata functions:
get_duration(),
get_frame_rate(),
get_sample_rate(),
get_width(),
mediainfo_parameter(),
mediainfo_query(),
mediainfo_template(),
probe_all(),
probe_container()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
get_height(video)
Get the audio sample rate of a media file
Description
get_sample_rate() uses the MediaInfo program to look up the audio sample
rate of a media file, in hertz (Hz). The glossary in vignette("tidymedia")
explains media terms such as sample rate.
Usage
get_sample_rate(file)
Arguments
file |
A character vector of one or more media file paths. |
Details
The function returns one number for each file. The probe_*() functions,
mediainfo_query() and mediainfo_template() return tibbles instead.
Value
A double vector (one per file) giving the audio sample rate in Hz.
See Also
mediainfo_parameter() for arbitrary MediaInfo fields, and
probe_all() to read information with FFprobe.
Other metadata functions:
get_duration(),
get_frame_rate(),
get_height(),
get_width(),
mediainfo_parameter(),
mediainfo_query(),
mediainfo_template(),
probe_all(),
probe_container()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
get_sample_rate(video)
Get the video width of a media file
Description
get_width() uses the MediaInfo program to look up the video width of a
media file, in pixels (px).
Usage
get_width(file)
Arguments
file |
A character vector of one or more media file paths. |
Details
The function returns one number for each file. The probe_*() functions,
mediainfo_query() and mediainfo_template() return tibbles instead.
Value
A double vector (one per file) giving the video width in px.
See Also
mediainfo_parameter() for arbitrary MediaInfo fields, and
probe_all() to read information with FFprobe.
Other metadata functions:
get_duration(),
get_frame_rate(),
get_height(),
get_sample_rate(),
mediainfo_parameter(),
mediainfo_query(),
mediainfo_template(),
probe_all(),
probe_container()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
get_width(video)
Hardware video encoders
Description
These functions help with optional hardware video encoding.
hardware_encoder() gives the hardware encoder name for a codec family.
has_hardware_encoder() reports whether that encoder is available in
the local FFmpeg build. The package supports two backends: NVIDIA nvenc
(H.264, HEVC and AV1) and Apple videotoolbox (H.264 and HEVC). So
hardware_encoder("h264", "nvenc") is "h264_nvenc", and
hardware_encoder("h264", "videotoolbox") is
"h264_videotoolbox". The glossary in vignette("tidymedia")
explains media terms such as codec, container and hardware encoder.
Usage
hardware_encoder(codec = c("h264", "hevc", "av1", "prores"), hardware)
has_hardware_encoder(codec = c("h264", "hevc", "av1", "prores"), hardware)
Arguments
codec |
The video codec family: one of |
hardware |
The backend: |
Details
has_hardware_encoder() is a cheap check. It asks whether FFmpeg
lists the encoder (via ffmpeg_encoders). That list reflects how
FFmpeg was built. It does not reflect whether working hardware and a driver
are present at run time. An encode can still fail at run time on a machine
with no capable GPU. To override detection in a known environment (or in
tests), set options(tidymedia.hardware_encoders = ) to a character
vector of encoder names to treat as available.
The hardware argument of the task functions uses the same encoder
names and the same check. These task functions have that argument:
standardize_video, format_for_web,
anonymize_video, crop_video,
segment_video, compare_videos,
picture_in_picture, and separate_audio_video
(and their _batch forms). Some of these functions have a
video_codec that defaults to NULL (no codec named), and they
assume the H.264 family. So a container that does not take H.264 (e.g.
.webm) needs an explicit HEVC- or AV1-family video_codec.
AV1 works only under "nvenc". Hardware decoding
(-hwaccel) and GPU filter pipelines are out of scope. Use the
ffmpeg direct command for those.
Value
hardware_encoder() returns a single encoder-name string (e.g.
"h264_nvenc"). has_hardware_encoder() returns a length-one
logical. Neither returns for a codec that the chosen hardware
backend has no encoder for. That pair is a wrong argument, not a machine
without something. So both give the error that codec describes
above. has_hardware_encoder() returns FALSE only for a pair
that the chosen backend has an encoder for and this FFmpeg build does not
list.
See Also
ffmpeg_encoders for the full encoder list.
These task functions have the hardware argument:
standardize_video, format_for_web,
anonymize_video, crop_video,
segment_video, compare_videos,
picture_in_picture, and
separate_audio_video.
Other capability functions:
ffmpeg_codecs(),
ffmpeg_encoders(),
refresh_ffmpeg_capabilities()
Examples
hardware_encoder("h264", "nvenc")
has_hardware_encoder("h264", "nvenc")
Install FFmpeg on Windows
Description
install_on_win() downloads a Windows build of FFmpeg and unpacks it. Then
it saves the locations of ffmpeg, ffprobe and ffplay, as
set_program() does. After that, the package can find these programs.
By default, the call downloads the latest "essentials" build from gyan.dev.
It unpacks the build into the ffmpeg folder under
tools::R_user_dir("tidymedia", "data").
By default, the call asks you to confirm before it does anything. The
question names each file it will download and the folder it will unpack
into. It also names
the saved program locations that the install can replace. If you say no, the
call returns FALSE and changes nothing.
This function works on Windows only. On any other system, it gives an error
before it asks, writes or downloads anything. The error names the system it
found. On macOS, you can install FFmpeg with brew install ffmpeg. On Linux,
you can use sudo apt-get install ffmpeg. On any system, set_program()
tells the package where an installed FFmpeg is.
Usage
install_on_win(
download_url = NULL,
install_dir = NULL,
confirm = TRUE,
archive_checksum = NULL
)
Arguments
download_url |
A string with the address of the FFmpeg archive. If
|
install_dir |
A string with the folder to install FFmpeg into. If
|
confirm |
|
archive_checksum |
A string with the expected SHA-256 checksum of the
archive, as 64 hexadecimal characters in upper or lower case. Defaults to
|
Details
Before the call unpacks the archive, it checks the archive against a SHA-256
checksum. A checksum is a fingerprint of the file's contents. For the
default source, the call downloads the checksum that gyan.dev publishes next
to each build. That file has the archive's address with .sha256 added. For
any other source, give the checksum in archive_checksum.
The published checksum comes from the same site as the archive, over the same connection. So the check finds a damaged or incomplete download. It does not find a source that someone has tampered with.
After the unpack, the call checks each program before it saves any location. The path must be one that R finds as a program. It must be a file, not a folder, and the file must not be empty. The call does not run the program. So a build for the wrong type of processor can pass this check.
The package needs ffmpeg and ffprobe. If either one fails the check, the
call saves no location and gives an error. The error names each failed
program and its full path. If ffplay is missing or fails the check, the
install finishes. A message says that the call did not save ffplay.
Value
TRUE when the install finished. FALSE when you said no to the
question, or when the call could not create the install folder. Other
failures give an error. The section "Errors" lists the error classes the
call gives. A wrong argument gives an error before any of these.
What a failed install leaves behind
When the call gives an error, it tries to leave the install folder as it found it. It removes the files that a failed unpack wrote. It removes a folder that the call created. It does not touch the files that were already in the folder, with one exception.
The exception is a file of yours that the failed unpack wrote over. The call removes that file too, because the file no longer holds what you put there.
On Windows, the removal can fail. After a failed unpack, the unpack library can still hold a file open. Windows does not delete a file that is open.
The error names by full path the entries of the first case below that applies:
each unpacked file that the call could not remove
each folder that the call created and could not remove
each file of yours that the call removed
Two errors come after a successful unpack: tidymedia_program_not_extracted
and tidymedia_program_unusable. These errors leave the unpacked files in
the folder, and they say so.
The call learns which files the unpack made from the archive's own list and from the folder. A program that the list names but that is not in the folder counts as not unpacked. For example, antivirus software can remove a program right after the unpack. The error then says that the unpack reported writing that file.
If none of the unpacked files are in the folder,
tidymedia_program_not_extracted follows the usual rule. The call removes a
folder that it created, and the error says so.
Errors
The call gives an error of its own class in these cases:
-
tidymedia_wrong_platform: the session is not running on Windows. -
tidymedia_confirmation_unavailable: the call must ask you to confirm, but no one can answer in this session. -
tidymedia_download_unavailable: the archive did not download, or nothing readable arrived. -
tidymedia_checksum_unavailable: the call could not download or read the published checksum. -
tidymedia_checksum_mismatch: the downloaded archive does not match its checksum. -
tidymedia_archive_unreadable: the call could not unpack the archive. -
tidymedia_program_not_extracted:ffmpegorffprobeis not at the path where the install would put it. -
tidymedia_program_unusable: the archive madeffmpegorffprobe, but the file cannot be used.
See Also
set_program() to save the location of a program you already have,
and find_ffmpeg() to check where the package finds a program.
Other program management functions:
find_ffmpeg(),
program_status(),
set_program(),
unset_program()
Examples
## Not run:
# Download and install a static FFmpeg build (Windows)
install_on_win()
## End(Not run)
Set a time limit for the rest of a function
Description
local_timeout() sets a time limit for the rest of the function that calls
it. The limit applies to each FFmpeg, FFprobe or MediaInfo program that the
function starts after this call. When the function returns, or stops with an
error, the caller's own limit is back, except in the cases in Details.
Use with_timeout() to set a limit on one expression. Use local_timeout()
to set a limit on the rest of a function, or on several calls that are hard
to wrap in one expression.
Usage
local_timeout(seconds, .local_envir = parent.frame())
Arguments
seconds |
A whole number of seconds. |
.local_envir |
The environment that holds the limit. The default is the
function that calls |
Details
The limit applies to each program, not to the whole function. In a 100-row
batch after local_timeout(600), each program that a row starts gets 600
seconds, plus the delay that with_timeout() describes. The workers of a
parallel = TRUE run use the same limit.
R can wait up to 40 seconds past the limit, and with_timeout() explains
why. It also explains what happens when a limit is reached.
Two calls in one function work like any two local_*() calls. The second
limit applies until the function ends. Then both are undone, and the caller's
limit is back.
In three cases, the caller's limit is not back when the function ends, and there is no error.
The function calls
on.exit()withoutadd = TRUE. That call removes the undo step. Writeon.exit(..., add = TRUE)instead.The
.local_envirbelongs to a function that has returned, or it is an environment such asnew.env().-
local_timeout()is called directly inside the expression ofwith_timeout(). There,local_timeout()belongs to the function around it. So when that function ends, the limit thatwith_timeout()set is in force. Put the inner limit in a function of its own, or use only one of the two.
The first two cases also apply to withr::local_options(), because R's exit
handlers work this way. They do not apply to withr::with_options(), which
puts the option back itself.
Value
The caller's earlier setting, invisibly. It is a list with one
element, the same form that withr::local_options() returns.
See Also
with_timeout() to set a limit for one expression.
tidymedia-package describes the session options.
Examples
bounded <- function() {
local_timeout(30)
getOption("tidymedia.timeout")
}
# In force for the rest of that function...
bounded()
# ...and gone once it has returned.
getOption("tidymedia.timeout", default = "unset")
# Bound every program a whole function starts, at five minutes. Defining the
# function starts nothing; the limit applies when you call it.
convert_all <- function(files) {
local_timeout(300)
for (f in files) extract_audio(f, sub("[.][^.]*$", ".wav", f))
}
Run a MediaInfo command
Description
mediainfo() runs the MediaInfo program with the arguments in command and
returns its output. MediaInfo reads information about media files.
Usage
mediainfo(command)
Arguments
command |
A string with the arguments to give MediaInfo. |
Details
mediainfo() is a direct command. The package passes command to MediaInfo
exactly as you wrote it, so you must add any quotes that it needs. To get a
tibble or a value instead, use mediainfo_template(), mediainfo_query() or
mediainfo_parameter(). These functions quote their arguments for you.
Value
A character vector with the text that MediaInfo writes to standard
output, one element for each line. Messages on standard error are not
returned. On macOS and Linux, a shell redirect such as 2>&1 in command
returns them too.
See Also
mediainfo_template(), mediainfo_query() and
mediainfo_parameter() for a tibble or a value. get_duration() and the
other get_*() functions for common single values.
Other direct command functions:
ffmpeg(),
ffprobe()
Examples
mediainfo("--Version")
Query a single parameter from a single MediaInfo section
Description
mediainfo_parameter() uses the MediaInfo program to read one value, such as
the video width, from media files. MediaInfo groups its values in sections,
such as "General", "Video" and "Audio". You name the section and the
parameter to read.
Usage
mediainfo_parameter(file, section, parameter, typed = TRUE)
Arguments
file |
A character vector of one or more media file paths. |
section |
A string. The name of the MediaInfo section to read
|
parameter |
A string. The name of the MediaInfo parameter to read from
|
typed |
A logical. If |
Details
Give several files in file to get one value for each file. The function
returns a vector, not a tibble. The probe_*() functions read similar
information with FFprobe and return tibbles.
Value
A vector with one value for each element of file. A value is NA
when MediaInfo prints more than one line, for example for a section it
does not know. A parameter that section does not have gives an empty
value. That value is NA when typed = TRUE and "" when
typed = FALSE. A value is also NA for a file that does not exist or
that reaches the time limit.
The function does not stop at those files. It reads the other files, and
then gives one warning that names the files that do not exist or reached
the limit. See with_timeout() for the time limit.
See Also
mediainfo_query() to read several parameters at once.
mediainfo_template() to apply a whole template. probe_all() to read
information with FFprobe. get_duration() and the other get_*()
functions for common single values.
Other metadata functions:
get_duration(),
get_frame_rate(),
get_height(),
get_sample_rate(),
get_width(),
mediainfo_query(),
mediainfo_template(),
probe_all(),
probe_container()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
mediainfo_parameter(video, section = "Video", parameter = "Width")
Query multiple parameters from a single MediaInfo section
Description
mediainfo_query() uses the MediaInfo program to read several parameters
from one section, and returns a tibble. To read parameters from more than
one section in one call, use mediainfo_template().
Usage
mediainfo_query(file, section, parameters, names = parameters, typed = TRUE)
Arguments
file |
A character vector of one or more media file paths. |
section |
A string. The name of the MediaInfo section to read
|
parameters |
A character vector of one or more MediaInfo parameters to
read from |
names |
A character vector of column names, one for each element of
|
typed |
A logical. If |
Details
Give several files in file to get one row for each file. The first column,
file, names the input file. The probe_*() functions read similar
information with FFprobe.
Value
A tibble with one row for each input file. The first column is
file, and then there is one column for each parameter.
A file that the function could not read gets a row of NA values. The
function reads the other files, and then gives one warning that names the
files it could not read. A file that reaches the time limit counts as not
read; see with_timeout().
See Also
mediainfo_parameter() to read a single value.
mediainfo_template() to apply a whole template. probe_all() to read
information with FFprobe. get_duration() and the other get_*()
functions for common single values.
Other metadata functions:
get_duration(),
get_frame_rate(),
get_height(),
get_sample_rate(),
get_width(),
mediainfo_parameter(),
mediainfo_template(),
probe_all(),
probe_container()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
mediainfo_query(video, section = "Video", parameters = c("Width", "Height"))
Describe media files by applying a MediaInfo template
Description
mediainfo_template() uses the MediaInfo program to describe media files,
and returns a tibble. It applies a MediaInfo template, which can read many
parameters from many sections.
Usage
mediainfo_template(
file,
template = c("brief", "extended", "custom"),
templatefile = NULL,
typed = TRUE
)
Arguments
file |
A character vector of one or more media file paths. |
template |
A string. Use |
templatefile |
The path to your own MediaInfo template, a |
typed |
A logical. If |
Details
The package comes with two templates, "brief" and "extended". You can
also give your own template file. Give several files in file to get one
row for each file. The first column, file, names the input file. The
probe_*() functions read similar information with FFprobe.
Value
A tibble with one row for each input file. The template sets the columns, their names and their order. The function keeps the column names of a custom template, but removes spaces at their start and end.
A file that the function could not read gets a row of NA values. The
function reads the other files, and then gives one warning that names the
files it could not read. A file that reaches the time limit counts as not
read; see with_timeout().
See Also
mediainfo_query() to read one section. mediainfo_parameter() to
read a single value. probe_all() to read information with FFprobe.
get_duration() and the other get_*() functions for common single
values.
Other metadata functions:
get_duration(),
get_frame_rate(),
get_height(),
get_sample_rate(),
get_width(),
mediainfo_parameter(),
mediainfo_query(),
probe_all(),
probe_container()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
mediainfo_template(video, template = "brief")
Normalize a file's audio loudness (EBU R128)
Description
Normalize the perceived loudness of a file's audio toward an EBU R128 target.
The function uses FFmpeg's single-pass loudnorm filter. It can also
downmix the channel count and resample. The output holds one audio
stream and no video, whatever the input and whatever container
outfile names. So the output of this function is audio, as with
extract_audio and convert_audio. It does not
carry the other streams through. To normalize a recording's soundtrack
and keep its picture, first normalize to an audio file. Then put the
audio back with the picture using the ffmpeg direct command.
The glossary in vignette("tidymedia") explains media terms such as
LUFS, true peak and sample rate.
Usage
normalize_audio(
infile,
outfile,
target_loudness = -23,
true_peak = -1,
loudness_range = 7,
channels = NULL,
sample_rate = NULL,
audio_codec = NULL,
two_pass = FALSE,
audio_stream = NULL,
run = TRUE
)
Arguments
infile |
A string containing the path to a media file (with audio). An input with no audio stream is an FFmpeg error, not a silent copy of the video. |
outfile |
A string containing the path of the audio file to write. The
function accepts any container that FFmpeg can write. The compiled command
does not depend on which container it is. An audio container ( |
target_loudness |
The target integrated loudness, in LUFS
(a number in |
true_peak |
The maximum true peak, in dBTP
(a number in |
loudness_range |
The target loudness range, in LU
(a number in |
channels |
The output channel count, e.g. |
sample_rate |
The output sample rate in Hz, e.g. |
audio_codec |
An optional string naming the output audio encoder (e.g.
|
two_pass |
A logical. When |
audio_stream |
The audio track to normalize, as a number that counts from |
run |
A logical: run the (correction) command through FFmpeg
( |
Details
The default targets follow EBU Recommendation R 128 (2014). They are
target_loudness = -23 LUFS and true_peak = -1 dBTP. Loudness
is measured per ITU-R BS.1770-4. The default loudness_range is
7. This is
single-pass (dynamic) loudnorm. The same input and arguments always
compile to one reproducible command, with no separate measurement pass. The
filter changes the audio, so FFmpeg re-encodes it. Set audio_codec to
name the output encoder, or leave it NULL to use the default of the
output container. Leaving channels at NULL keeps the source
channel layout. FFmpeg's loudnorm filter resamples its output, up to
192 kHz, capped by the encoder. So the output sample rate is not the
source rate unless you set it. Set sample_rate to control the output
rate.
The function warns when no audio_stream is named and infile
carries tracks that the output will not. extract_audio and
convert_audio emit the same warning. Naming a track with
audio_stream silences it, as does
suppressWarnings(classes = "tidymedia_dropped_audio").
The check costs one FFprobe call per distinct input, which is one call here, because this function takes a single infile. The warning is given when FFprobe is available and the input can be probed. Otherwise the check is skipped silently. It never runs under run = FALSE,
and never changes the compiled command. Under two_pass = TRUE, the
warning comes before the analysis pass. So it arrives while adding
audio_stream can still save that pass.
To switch the check off and skip its FFprobe call, use options(tidymedia.check_tracks = FALSE) for the session. Use withr::local_options(tidymedia.check_tracks = FALSE) for the rest of one function.
Value
The compiled FFmpeg command (invisibly when run = TRUE). Under
two_pass = TRUE this is the correction command built from the
measured values.
References
EBU Recommendation R 128 (2014), Loudness normalisation and permitted maximum level of audio signals; ITU-R BS.1770-4.
See Also
ffm_loudnorm(), the pipeline function it wraps.
normalize_audio_batch() for the many-file form.
extract_audio() and convert_audio(), the other task functions whose
output is one audio stream.
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_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(),
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_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")
# The output holds audio only, so name an audio file for it
normalize_audio(video, "normalized.wav", run = FALSE)
# Normalize to a streaming target and downmix to mono
normalize_audio(video, "mono.wav", target_loudness = -16, channels = 1,
run = FALSE)
# Name the output audio encoder instead of taking the container's default
normalize_audio(video, "normalized.m4a", audio_codec = "aac", run = FALSE)
Normalize Many Files' Audio Loudness From a Jobs Table
Description
Normalize the audio loudness of many input files (EBU R128) from a single
jobs tibble. This is the batch (table-driven) form of
normalize_audio(), for when you have more than one file to normalize. Each
row is one input, and the only required column names its source. The function
is a thin wrapper over ffm_batch. It gives one reproducible
compiled command per input. Each row uses the same loudnorm pipeline,
and the same check of each value, as normalize_audio(). Set
two_pass = TRUE for accurate measured/linear normalization across the
whole table (see two_pass). The glossary in
vignette("tidymedia") explains media terms such as LUFS, encoder and
sample rate.
Usage
normalize_audio_batch(
jobs,
target_loudness = -23,
true_peak = -1,
loudness_range = 7,
channels = NULL,
sample_rate = NULL,
audio_codec = NULL,
two_pass = FALSE,
audio_stream = NULL,
run = TRUE,
parallel = FALSE,
...
)
Arguments
jobs |
A data frame with one row per input and (at least) an
|
target_loudness, true_peak, loudness_range |
The EBU R128 loudness targets
applied to every row, unless |
channels |
The output channel count applied to every row, unless
|
sample_rate |
The output sample rate in Hz applied to every row, unless
|
audio_codec |
The output audio encoder applied to every row, unless
|
two_pass |
A logical that selects the normalization mode for
every row. It applies to the whole table and is not a per-row
column. |
audio_stream |
The audio track to normalize, as a number that counts from |
run |
A logical: run each input's command through FFmpeg ( |
parallel |
A logical passed to |
... |
Additional arguments forwarded to |
Details
The function warns once for the whole batch when a row names no
audio_stream and its input carries tracks that the output will not.
The warning names every affected row. Naming a track silences it. Use the
audio_stream argument, or an audio_stream cell on every row.
suppressWarnings(classes = "tidymedia_dropped_audio") silences it
too.
The check costs one FFprobe call per distinct input it has to probe. A repeated input is probed once, and a row that names a track is not probed at all. The warning is given when FFprobe is available and the input can be probed. Otherwise the check is skipped silently. Those probes run one at a time, before any row starts, so parallel does not reach them. A sweep long enough to look like a hang reports its progress. The check never runs under
run = FALSE and never changes any compiled command. It is skipped
entirely when every row names a track. Under two_pass = TRUE, the
warning comes before the analysis pass. So it arrives while adding
audio_stream can still save that pass.
To switch the check off and skip the whole sweep, use options(tidymedia.check_tracks = FALSE) for the session. Use withr::local_options(tidymedia.check_tracks = FALSE) for the rest of one function.
Value
The tibble returned by ffm_batch: jobs with an added command column. When output was derived, it also has the resolved output column. When run = TRUE, it has a success column, plus any columns the forwarded arguments add, such as verified. Under two_pass = TRUE, the result
also carries the five measured columns (measured_I etc.) and a
logical silent column. The command column then holds the
linear correction commands. It is NA for silent rows, which carry
NA measurements and are not normalized. The columns of the two-pass
result do not depend on how many rows are silent. The verified
column (under verify) and the provenance manifest (under
manifest, read with ffm_manifest) are present
whenever requested. That holds even when every row is silent.
Silent rows carry NA for those outputs.
References
EBU Recommendation R 128 (2014), Loudness normalisation and permitted maximum level of audio signals; ITU-R BS.1770-4.
See Also
normalize_audio() for the single-input form.
ffm_batch() for the batch runner and the arguments forwarded through
....
standardize_video_batch() for the table-driven form on the video side.
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(),
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(),
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(),
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")
jobs <- tibble::tibble(
input = c(video, video),
output = c(tempfile(fileext = ".m4a"), tempfile(fileext = ".m4a")),
target_loudness = c(-23, -16)
)
# run = FALSE compiles one command per input without calling FFmpeg
normalize_audio_batch(jobs, run = FALSE)
# Accurate two-pass (measured/linear) normalization across the whole table.
# This one runs FFmpeg to measure each input, so it needs the binary.
if (nzchar(Sys.which("ffmpeg"))) {
normalize_audio_batch(jobs, two_pass = TRUE)
}
Inset one video over another (picture-in-picture)
Description
Composite a smaller overlay video onto a main video in one
corner (or the center). This is the classic picture-in-picture layout for
pairing a speaker with a screen recording, or a stimulus with a webcam. Built
on the ffm_overlay pipeline function, which resizes the overlay
to a fraction of the main video's width and positions it. The glossary in
vignette("tidymedia") explains media terms such as codec, encoder and
stream copy.
Usage
picture_in_picture(
main,
overlay,
outfile,
position = c("topright", "topleft", "bottomright", "bottomleft", "center"),
scale = 0.25,
margin = 16,
audio_input = NULL,
video_codec = NULL,
audio_codec = "copy",
hardware = c("none", "nvenc", "videotoolbox"),
fallback = FALSE,
quality = NULL,
run = TRUE
)
Arguments
main |
A string giving the path to the background (full-size) video. |
overlay |
A string giving the path to the inset video. |
outfile |
A string giving the path to write the result to. |
position |
Where to place the inset: one of |
scale |
The inset's width as a fraction of the main video's width, aspect
preserved ( |
margin |
The gap in pixels between the inset and the video edges (ignored
for |
audio_input |
The input file whose audio to keep, as a number that counts from |
video_codec |
A string naming the output video codec, or |
audio_codec |
A string naming the codec for the carried audio track.
|
hardware |
The encoder backend. |
fallback |
A logical. When a |
quality |
A number, or |
run |
A logical: run the command through FFmpeg ( |
Details
Audio is dropped unless audio_input names an input to carry (0 = the
main video, 1 = the overlay). A carried track is
stream-copied unless audio_codec names an encoder.
Value
The compiled FFmpeg command (invisibly when run = TRUE).
See Also
ffm_overlay(), the pipeline function it wraps;
has_hardware_encoder() for the
hardware argument; compare_videos() for
side-by-side stacking.
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_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(),
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_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")
picture_in_picture(video, video, "pip.mp4", run = FALSE)
Inset One Video Over Another For Many Outputs From a Jobs Table
Description
Composite an inset (overlay) video onto a main video for many outputs from a
single jobs tibble. This is the batch (table-driven) form of
picture_in_picture(), for when you have more than one to produce. Its two
inputs have distinct roles, so jobs carries fixed main and
overlay columns (not a list-column) plus an output column.
This is a thin wrapper over ffm_batch: one reproducible overlay
command per row, sharing the pipeline with picture_in_picture(). The
glossary in vignette("tidymedia") explains media terms such as codec,
encoder and stream copy.
Usage
picture_in_picture_batch(
jobs,
position = c("topright", "topleft", "bottomright", "bottomleft", "center"),
scale = 0.25,
margin = 16,
audio_input = NULL,
video_codec = NULL,
audio_codec = "copy",
hardware = c("none", "nvenc", "videotoolbox"),
fallback = FALSE,
quality = NULL,
run = TRUE,
parallel = FALSE,
...
)
Arguments
jobs |
A data frame with one row per output and (at least) |
position, scale, margin |
Defaults applied to every row lacking the
corresponding column. |
audio_input |
The input file whose audio to keep, as a number that counts from |
video_codec |
A string naming the output video codec, applied to every
row lacking a |
audio_codec |
A string naming the codec for the carried audio track,
applied to every row lacking an |
hardware, fallback |
The encoder backend and its fallback behavior, applied to the whole batch. They are a property of the machine, not of a row, so neither is read as a |
quality |
A number, or |
run |
A logical: run each command through FFmpeg ( |
parallel |
A logical: process the jobs in parallel with furrr
( |
... |
Additional arguments forwarded to |
Value
The jobs tibble with an added command column. When run = TRUE, it also has a success column, plus verified or a provenance manifest, each when requested through .... See ffm_batch.
See Also
picture_in_picture(), the one-output function it wraps;
ffm_batch(), the batch runner; has_hardware_encoder() for the
hardware argument. concatenate_videos_batch() and
compare_videos_batch(), the other batch functions that take several
inputs per row.
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(),
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(),
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(),
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")
jobs <- tibble::tibble(main = video, overlay = video, output = "pip.mp4")
picture_in_picture_batch(jobs, run = FALSE)
Print an FFmpeg pipeline
Description
Print a tidymedia ffm pipeline by showing the FFmpeg command it
currently compiles to (via ffm_compile).
Usage
## S3 method for class 'tidymedia_ffm'
print(x, ...)
Arguments
x |
A tidymedia |
... |
Ignored. |
Value
x, invisibly.
See Also
ffm_compile(), which produces the printed command.
Other pipeline functions:
ffm_batch(),
ffm_codec(),
ffm_compile(),
ffm_concat(),
ffm_copy(),
ffm_crop(),
ffm_drawbox(),
ffm_drop(),
ffm_files(),
ffm_fps(),
ffm_hstack(),
ffm_jobs(),
ffm_loudnorm(),
ffm_map(),
ffm_output_options(),
ffm_overlay(),
ffm_pixel_format(),
ffm_run(),
ffm_scale(),
ffm_seek(),
ffm_trim(),
ffm_vstack()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
ffm_files(video, "output.mp4") |>
ffm_trim(start = 1, end = 5)
Look up information about media files using FFprobe
Description
probe_all() uses the FFprobe program to read information about media
files. It returns two tibbles. One describes each file as a whole, and one
describes each stream in the files.
Usage
probe_all(infile, typed = TRUE, parallel = FALSE)
Arguments
infile |
A character vector of one or more media files to probe, as file paths or web links. |
typed |
A logical. If |
parallel |
A logical. If |
Details
Give several files in infile to read them all in one call. The function
stacks the rows, and the first column, file, names the input file. So you
can join and filter the results for a whole batch with dplyr.
The MediaInfo functions, mediainfo_*(), return tibbles or values. The
get_*() functions return one value for each file.
The glossary in vignette("tidymedia") explains media terms such as
container and stream.
Value
A list of two tibbles. container has one row for each input file.
streams has one row for each stream. Both tibbles start with a file
column that names the input file. A file with no readable streams gets one
row in streams, with NA in every other column.
The function does not stop at a file that it could not probe. That file
gets a row of NA values in both tibbles, and the function gives a
warning. A file that reaches the time limit counts as not probed; see
with_timeout().
See Also
mediainfo_template() and mediainfo_query() to read information
with MediaInfo. get_duration() and the other get_*() functions for
single values.
Other metadata functions:
get_duration(),
get_frame_rate(),
get_height(),
get_sample_rate(),
get_width(),
mediainfo_parameter(),
mediainfo_query(),
mediainfo_template(),
probe_container()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
info <- probe_all(video)
info$container
info$streams
Shortcut functions for probing specific information
Description
These functions return one part of what probe_all() returns.
probe_container() returns the container tibble, and probe_streams()
returns the streams tibble. probe_video() and probe_audio() return only
the video rows or the audio rows of streams.
Usage
probe_container(probe = NULL, infile = NULL, typed = TRUE, parallel = FALSE)
probe_streams(probe = NULL, infile = NULL, typed = TRUE, parallel = FALSE)
probe_video(probe = NULL, infile = NULL, typed = TRUE, parallel = FALSE)
probe_audio(probe = NULL, infile = NULL, typed = TRUE, parallel = FALSE)
Arguments
probe |
A list made by |
infile |
A character vector of one or more media files. Must be |
typed |
A logical that the function passes to |
parallel |
A logical that the function passes to |
Details
Give each function either the output of probe_all() in probe, or one or
more files in infile. Give exactly one of the two, or the function gives
an error. With infile, the function probes the files again. For large
files, probe once with probe_all() and reuse the result.
These functions use FFprobe and return tibbles. The MediaInfo functions,
mediainfo_*(), and the get_*() functions are the other ways to read
information. The glossary in vignette("tidymedia") explains media terms
such as container and stream.
Value
A tibble with only the requested information. When you give
infile, a file that could not be probed gives a warning, as in
probe_all().
See Also
probe_all() for the full probe. mediainfo_query() to read
information with MediaInfo. get_width() and the other get_*()
functions for single values.
Other metadata functions:
get_duration(),
get_frame_rate(),
get_height(),
get_sample_rate(),
get_width(),
mediainfo_parameter(),
mediainfo_query(),
mediainfo_template(),
probe_all()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
# Probe directly from a file location ...
probe_container(infile = video)
# ... or reuse a probe object to avoid reprobing large files
info <- probe_all(video)
probe_video(info)
probe_audio(info)
Report which dependency programs tidymedia can find
Description
program_status() looks for the four programs that the package uses:
ffmpeg, ffprobe, ffplay and mediainfo. It returns a table with one
row for each program. The row shows where the program is and which version
it reports. The call does not install, write or change anything.
Usage
program_status()
Details
The call looks in the same places as find_ffmpeg(). First it looks on the
PATH, then at a location saved by set_program(). For locations saved by
versions before 0.2.0, see the section "Locations saved by earlier versions"
in find_ffmpeg().
A program that is not installed and has no saved location gets NA in both
columns. This case gives no warning, so four missing programs give one table
and not four warnings.
A saved location that cannot be used still gives a warning. Without it, the
NA would look like a program you never had. Each warning names the saved
location or the file that holds it, so you can fix it. There are two cases:
-
tidymedia_location_gone: no program is at the saved location now. -
tidymedia_location_unreadable: the file that stores the location does not hold exactly one location.
In both cases, the row has NA in both columns. unset_program() forgets
the location, and set_program() replaces it.
The version is what the program reports about itself. For ffmpeg,
ffprobe and ffplay, it is the FFmpeg build number. For mediainfo, it is
the MediaInfo library version.
Sometimes the call finds a program but cannot get its version. Then the row
has a location and an NA version. This happens when the program call fails.
It also happens when the time limit in options(tidymedia.timeout = ) stops
it.
Value
A tibble with one row for each program and three columns:
-
program, the name of the program. -
location, the path to the program, orNA. -
version, the version that the program reported, orNA.
See Also
find_ffmpeg() and the other find_*() functions to look up one
program. set_program() to save the location of a program that is not on
the PATH. unset_program() to forget a saved location.
Other program management functions:
find_ffmpeg(),
install_on_win(),
set_program(),
unset_program()
Examples
# One row per program; NA where the program was not found
program_status()
Forget what tidymedia remembers about your FFmpeg build
Description
Discard the package's record of which encoders your FFmpeg build has. The next query then asks FFmpeg again.
Usage
refresh_ffmpeg_capabilities()
Details
The first call in an R session that uses hardware = "nvenc" or
hardware = "videotoolbox" asks FFmpeg which encoders it has. The
package remembers that answer for the rest of the session. Later calls reuse
it and do not start FFmpeg again each time, so a large batch stays fast.
So the package does not see a change to your FFmpeg build until you discard the record. Examples of a change are a new FFmpeg install, a new graphics card (GPU) driver, or a different FFmpeg program. There are three ways to discard the record:
Call
refresh_ffmpeg_capabilities()yourself, at any time.Call
set_program(orset_ffmpeg). It discards the record for you, because the record describes the old program.Call
unset_programand have it remove something. When it forgets a saved location, the package can find a different program. A call that removed nothing keeps the record, because the program in use did not change. A call that removed one saved file and then failed on another discards the record. The file it removed may have named the program that the record came from.
The glossary in vignette("tidymedia") explains media terms such as
encoder and hardware encoder.
Value
NULL, invisibly. Called for its side effect.
Parallel workers
Each R process keeps its own record, and a worker does not get the record of
your session. So in a batch on W workers, each worker asks FFmpeg
once. Your session can also ask once, before the jobs start. Discarding the
record in your session does not reach the workers.
The tidymedia.hardware_encoders option works in a different way. The
package copies your value into each worker for the duration of the call, and
then puts back the worker's own value. So a batch under your setting does not
ask FFmpeg for an encoder list at all. Every worker gives the same answer as
your session.
Functions that never use the record
ffmpeg_encoders and ffmpeg_codecs ask FFmpeg on
every call. So they always show the build as it is now, whether or not you
called this function.
See Also
has_hardware_encoder uses the remembered answer.
hardware_encoder gives the encoder name without asking
FFmpeg.
ffmpeg_encoders always gives a fresh encoder list.
set_program points the package at a different FFmpeg program.
Other capability functions:
ffmpeg_codecs(),
ffmpeg_encoders(),
hardware_encoder()
Examples
# After installing FFmpeg, or a GPU driver or OS update mid-session:
refresh_ffmpeg_capabilities()
Sample frames from a video at a fixed rate
Description
Sample a video into a numbered image sequence. Sample at a fixed rate
(fps) or at a fixed interval (interval, seconds between
frames). This is the first step for per-frame coding and for computer-vision
feature pipelines. Provide exactly one of fps or interval.
Usage
sample_frames(
infile,
outdir,
fps = NULL,
interval = NULL,
format = "png",
prefix = NULL,
run = TRUE
)
Arguments
infile |
A string containing the path to a video file. |
outdir |
A string naming the directory to write the image sequence to. The function creates it (recursively) if it does not exist. |
fps |
The sampling rate, in frames per second: either a positive number
or an FFmpeg framerate expression string (for example |
interval |
The number of seconds between sampled frames (a positive
number). The function uses the reciprocal as the frame rate. Provide
exactly one of |
format |
A string giving the output image file extension (one of
|
prefix |
A string used as the basename stem of each image, or
|
run |
A logical: run the command through FFmpeg ( |
Details
extract_frame saves one frame, and
extract_frame_batch saves a set of frames that you list. This
function is different. It builds a single FFmpeg command whose output
is a printf-style file name pattern. FFmpeg's image2 muxer fills the
pattern. FFmpeg decides the frame count when it decodes the video, and you
do not list the frames. The function writes frames to outdir as
<prefix>_<n>.<format>, where <n> is a zero-padded integer
starting at 1. The glossary in vignette("tidymedia") explains media
terms such as frame rate.
Value
The compiled FFmpeg command (invisibly when run = TRUE).
See Also
ffm_fps(), the pipeline function it uses to set the sampling rate.
extract_frame() for a single frame, and extract_frame_batch() for a
set of frames that you list. sample_frames_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_batch(),
segment_video(),
segment_video_batch(),
separate_audio_video(),
separate_audio_video_batch(),
standardize_video(),
standardize_video_batch(),
strip_metadata(),
strip_metadata_batch()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
# run = FALSE returns the reproducible command instead of executing it
sample_frames(video, tempdir(), fps = 2, run = FALSE)
Sample frames from many videos at a fixed rate from a jobs table
Description
Sample many videos into numbered image sequences, using one jobs table. This
is the batch form of sample_frames(). Each row is one input video,
sampled at a fixed rate into its own image sequence. The function is a thin
wrapper over ffm_batch. It builds one reproducible command for
each input. The glossary in vignette("tidymedia") explains media terms
such as frame rate.
Usage
sample_frames_batch(
jobs,
fps = NULL,
interval = NULL,
outdir = NULL,
format = "png",
run = TRUE,
parallel = FALSE,
...
)
Arguments
jobs |
A data frame with one row per input. It needs at least an
|
fps, interval |
The sampling rate applied to every row, as in
|
outdir |
An optional single output directory for all rows. An
|
format |
A string giving the output image file extension, as in
|
run |
A logical: run each input's command through FFmpeg ( |
parallel |
A logical passed to |
... |
Additional arguments forwarded to |
Details
Supply the sampling rate once as the single fps or interval
argument, which applies to every row. Or supply it per row as an fps
or interval column, which overrides the argument of the same name.
Supply exactly one of the two, fps or interval, across arguments and
columns.
Value
The tibble returned by ffm_batch: jobs with an added command column. When outdir was derived, it also has the resolved outdir column. When run = TRUE, it has a success column, plus any columns the forwarded arguments add, such as verified.
See Also
sample_frames() for the single-video form. ffm_batch() for the
batch runner and the arguments passed on through ....
extract_frame_batch() for the batch function that takes a list of
frames.
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(),
segment_video(),
segment_video_batch(),
separate_audio_video(),
separate_audio_video_batch(),
standardize_video(),
standardize_video_batch(),
strip_metadata(),
strip_metadata_batch()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
jobs <- tibble::tibble(
input = c(video, video),
outdir = c(file.path(tempdir(), "a"), file.path(tempdir(), "b"))
)
# run = FALSE compiles one command per input without calling FFmpeg
sample_frames_batch(jobs, fps = 2, run = FALSE)
Segment Video
Description
Use FFmpeg to quickly break a single video file into multiple smaller video
files (with the same encoding). Pairs of start and stop timestamps set the
segments. The function names each segment file after infile. It
appends a suffix of an underscore (_) and an integer indicating which
segment, based on the order provided in start and end. The
glossary in vignette("tidymedia") explains media terms such as codec,
keyframe and stream copy.
Usage
segment_video(
infile,
start,
end,
outfiles = NULL,
reencode = TRUE,
video_codec = NULL,
audio_codec = "copy",
hardware = c("none", "nvenc", "videotoolbox"),
fallback = FALSE,
quality = NULL,
audio_stream = NULL,
run = TRUE,
parallel = FALSE
)
Arguments
infile |
A string containing the path to a video file. |
start |
A vector containing one or more timestamps indicating the
start of each segment to create. Can be either a numeric vector indicating
seconds or a character vector with time duration syntax. Must have the same
length as |
end |
A vector containing one or more timestamps indicating the stop
of each segment to create. Can be either a numeric vector indicating
seconds or a character vector with time duration syntax. Must have the same
length as |
outfiles |
Either NULL or a character vector indicating the filename
(with extension) for each segment to create. If NULL, will append a
zero-padded integer to |
reencode |
A logical passed to |
video_codec |
A string naming the output video codec, or |
audio_codec |
A string naming the output audio codec.
|
hardware |
The encoder backend. |
fallback |
A logical. When a |
quality |
A number, or |
audio_stream |
The audio track to carry into the output, as a number that counts from |
run |
A logical: run each segment's command ( |
parallel |
A logical passed to |
Value
The tibble returned by
ffm_batch: one row per segment with its command (and,
when run = TRUE, success).
References
https://ffmpeg.org/ffmpeg-utils.html#time-duration-syntax
See Also
ffm_seek(), the pipeline function it uses to cut; ffm_batch(),
the runner; has_hardware_encoder() for the hardware argument;
segment_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_batch(),
separate_audio_video(),
separate_audio_video_batch(),
standardize_video(),
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_batch(),
separate_audio_video(),
separate_audio_video_batch(),
standardize_video(),
standardize_video_batch()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
# Two segments; run = FALSE compiles one command per segment
segment_video(video, start = c(0, 0.5), end = c(0.5, 1), run = FALSE)
Segment Many Videos From a Jobs Table
Description
Cut segments across many input files from a single jobs tibble. This is the
batch (table-driven) form of segment_video(), for when your segments
span more than one input. Each row is one segment; the four required columns
name its source, destination, and cut points. This is a thin wrapper over
ffm_batch: one reproducible compiled command per segment. The
glossary in vignette("tidymedia") explains media terms such as codec,
keyframe and stream copy.
Usage
segment_video_batch(
jobs,
reencode = TRUE,
video_codec = NULL,
audio_codec = "copy",
hardware = c("none", "nvenc", "videotoolbox"),
fallback = FALSE,
quality = NULL,
audio_stream = NULL,
run = TRUE,
parallel = FALSE,
...
)
Arguments
jobs |
A data frame with one row per segment and (at least) the columns
|
reencode |
A logical passed to |
video_codec |
A string naming the output video codec, applied to every
row lacking a |
audio_codec |
A string naming the output audio codec, applied to every
row lacking an |
hardware, fallback |
The encoder backend and its fallback behavior, applied to the whole batch. They are a property of the machine, not of a row, so neither is read as a |
quality |
A number, or |
audio_stream |
The audio track to carry into each output, as a number that counts from |
run |
A logical: run each segment's command through FFmpeg
( |
parallel |
A logical passed to |
... |
Additional arguments forwarded to |
Value
The tibble returned by ffm_batch: jobs with an added command column. When output was derived, it also has the resolved output column. When run = TRUE, it has a success column, plus any columns the forwarded arguments add, such as verified.
References
https://ffmpeg.org/ffmpeg-utils.html#time-duration-syntax
See Also
segment_video() for the single-input, parallel-vector form.
ffm_batch() for the batch runner and the arguments forwarded through
.... has_hardware_encoder() for the hardware argument.
ffm_seek() for the cut trade-off.
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(),
separate_audio_video(),
separate_audio_video_batch(),
standardize_video(),
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(),
separate_audio_video(),
separate_audio_video_batch(),
standardize_video(),
standardize_video_batch()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
jobs <- tibble::tibble(
input = c(video, video),
output = c("a.mp4", "b.mp4"),
start = c(0, 0.5),
end = c(0.5, 1)
)
# run = FALSE compiles one command per segment without calling FFmpeg
segment_video_batch(jobs, run = FALSE)
Split a media file into separate audio and video files
Description
By default, each stream is copied, not re-encoded (audio_codec =
"copy", video_codec = "copy"). A copy loses no quality and is fast.
Each output container must then support the source codec. For example, write
AAC audio from an MP4 to .aac or .m4a, not to .mp3. To
re-encode a stream, name an encoder (audio_codec = "libmp3lame"). Pass
NULL to set no codec option, so the output extension picks the
encoder. Each argument governs only its own output file. Where the video is
re-encoded, hardware = "nvenc" or "videotoolbox" moves that
encode onto a GPU. The audio output is never affected. The glossary in
vignette("tidymedia") explains media terms such as codec, container
and stream copy.
Usage
separate_audio_video(
infile,
audiofile,
videofile,
audio_codec = "copy",
video_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 media file. |
audiofile |
A string containing the path of the audio file to write. |
videofile |
A string containing the path of the video file to write. |
audio_codec |
A string that names the encoder for |
video_codec |
A string that names the encoder for |
hardware |
The encoder backend for |
fallback |
A logical. When a |
quality |
A number, or |
audio_stream |
The audio track to write to |
run |
A logical: run the commands through FFmpeg ( |
Value
A named character vector of the two compiled commands
(audio, video). It is invisible when run = TRUE. Under
run = TRUE, the audio command runs first and the video command runs
second. The video command runs whether or not the audio command succeeded.
A failed audio command still aborts the call. By then, the video command
has written videofile, unless it failed too. See When the
audio output fails.
When the audio output fails
The two commands run in order: audio first, video second. The video command runs even when the audio command failed, so a failed audio half does not cost you the video. In that case, the call still aborts with the audio failure. That error carries one added line that names the video file that was written. When the video command fails too, the added line is not there. The audio failure is still the error you get. FFmpeg's own output for the failed video command is printed above it.
A time limit reached on the audio command is held like any other audio
failure, so the video command still runs. The video command gets a fresh
limit of its own, because with_timeout() limits each program
that the call starts, not the call. So a call whose audio half reaches the
limit can wait up to two limits, not one.
A failed command treats its own output path by the same rule on either path.
It removes a partial file that the run wrote. It leaves a file that was
already at that path, and that FFmpeg never wrote to, exactly as it was. So
neither failure path promises that the path is empty afterwards. It promises
only that nothing half-written is left there. The audio failure's own error
says which of the two happened to audiofile. The same error's
tm_video_error field says what became of the video command. It holds
the condition that command raised when it failed too, and NULL when it
succeeded.
The default keeps every audio track. So FFmpeg fails when it writes a
multi-track input to a container that holds only one track (.aac,
.mp3, .wav). When that happens, the error also reports how many
audio tracks infile carries, and it names the two ways out. Use
audio_stream to write one track, or use a container such as
.mka or .m4a to keep them all.
The error carries that extra report only when all four of these hold:
No
audio_streamwas named.FFmpeg returned a non-zero exit status.
-
infilecarries more than one audio track. The extension of
audiofileis not among the containers named here as holding several audio streams.
Those containers are .mka, .m4a, .mp4, .mov, .mkv, .webm, .ogg, .opus and .ts. The
nine are an exclusion list and not a survey. FFmpeg
writes several audio streams into other containers too, .avi and
.nut among them. A failure on one of those still gets the report. The
container condition keeps the report off a call that already does what the
report advises. When a call writes to one of the nine,
the failure cannot be the container refusing a second audio stream. The
report would then leave unnamed whatever FFmpeg did object to.
If any of the four does not hold, the error you get is the one the run itself raised, whatever that error is. It has the same class, the same status field and the same message. The one difference is the line saying that the video output was written. A failing audio half carries that line when the video command wrote its file and the audio failure is an rlang condition. When the exit status is the one that does not hold, there is no exit status to carry. A run that never reached FFmpeg has none.
The report states what the call did: the track count, and that every
track was mapped into one output. It never states why FFmpeg refused.
FFmpeg's own error and exit status are printed beneath it and carried on the
condition. They remain the only authority on the cause. Several causes look
alike from here. A stream copy into a container that will not hold the source
codec fails on a multi-track input too. The default audio_codec =
"copy" into .mp3 is one example. An unknown encoder and a missing
output directory fail the same way.
The condition carries two class names, so a caller can catch it at either
width. It is tidymedia_ffmpeg_exit, the class that every non-zero
FFmpeg exit raises. An exit-status handler catches that class, and the number
is on the condition's tm_status field. It is also
tidymedia_multitrack_separation, the class of this report itself.
Catch that class when it is this failure in particular you want:
tryCatch(
separate_audio_video("three-tracks.mkv", "audio.mp3", "video.mp4"),
tidymedia_ffmpeg_exit = function(cnd) cnd$tm_status
)
When the report is omitted, the error that reaches the caller is the one the
run itself raised, apart from that video-output line. A non-zero exit still
answers to tidymedia_ffmpeg_exit. A failure that is not an exit
answers to neither class here. An FFmpeg that the package cannot locate
raises an error with no tidymedia_ class at all. A reached limit
raises tidymedia_timeout.
Counting the tracks means running FFprobe, so the report is not guaranteed.
The error has it when FFprobe is available and infile can be probed.
Otherwise the package omits it silently and leaves FFmpeg's own error alone.
So the report may not appear, and its absence is never itself a second
failure. The count never runs under run = FALSE and never changes the
compiled commands. It is skipped when audio_stream names a track, or
when audiofile names one of the multi-stream containers above. With
one track mapped, the track count cannot be what FFmpeg objected to.
See Also
ffm_map() and ffm_codec(), the pipeline functions it wraps.
has_hardware_encoder() for the hardware argument.
extract_audio() to pull out just the audio.
probe_audio() to list an input's audio tracks.
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_batch(),
standardize_video(),
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_batch(),
standardize_video(),
standardize_video_batch()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
separate_audio_video(video, "audio.aac", "video.mp4", run = FALSE)
# transcode the audio to MP3 while copying the video through untouched
separate_audio_video(video, "audio.mp3", "video.mp4",
audio_codec = "libmp3lame", run = FALSE)
# write only the second audio track (this sample has one, so compile only)
separate_audio_video(video, "audio.aac", "video.mp4",
audio_stream = 1, run = FALSE)
Separate Audio and Video for Many Files From a Jobs Table
Description
Split the audio and video streams of many input files from a single jobs
tibble. This is the batch (table-driven) form of
separate_audio_video(), for when you have more than one file. Each row is
one input that gives two outputs. The input,
audiofile and videofile columns are all required. The function
is a thin wrapper over ffm_batch. It turns every input row into
two single-output jobs, one per stream. So a jobs table of N rows
returns 2N rows, with one reproducible compiled command per stream.
Each stream uses the same map and stream-copy pipeline as
separate_audio_video(). The glossary in vignette("tidymedia")
explains media terms such as codec, container and stream copy.
Usage
separate_audio_video_batch(
jobs,
audio_codec = "copy",
video_codec = "copy",
hardware = c("none", "nvenc", "videotoolbox"),
fallback = FALSE,
quality = NULL,
audio_stream = NULL,
run = TRUE,
parallel = FALSE,
...
)
Arguments
jobs |
A data frame with one row per input. It has at least an
|
audio_codec |
A string that names the encoder for every
|
video_codec |
A string that names the encoder for every
|
hardware, fallback |
The encoder backend for every |
quality |
A number, or |
audio_stream |
The audio track to write to each |
run |
A logical: run each command through FFmpeg ( |
parallel |
A logical: process the jobs in parallel with furrr
( |
... |
Additional arguments forwarded to |
Value
A tibble with two rows per input,
one per stream. It has the reshaped input, a single output
path, a stream marker ("audio" or "video"), and an
added command column. When run = TRUE, it also has a
success column. A run also gives verified and the
provenance manifest, each when requested via .... When jobs supplies
either codec column, a
single codec column carries each row's resolved encoder for its own
stream (NA where none is set). When audio_stream is supplied
as either the argument or a jobs column, an audio_stream
column likewise carries each row's resolved track. That is the selected
index on an audio row. It is NA on every video row, which takes no
audio, and on an audio row that named no track. So NA does not by
itself mark a video row. Read the stream column for that. The
columns match the output of the other _batch functions, plus the
stream marker. See ffm_batch.
Failed audio outputs
A row whose audio command does not finish cleanly is recorded as
success = FALSE, and the batch does not abort. One warning for the
whole batch, emitted once, names such rows. It lists every affected
input row and the ways out.
A row reaches that warning only when all four of these hold:
It named no
audio_stream.The row is recorded
success = FALSE.Its input carries more than one audio track.
The extension of its
audiofileis not among the containers named here as holding several audio streams.
Those containers are .mka, .m4a, .mp4, .mov, .mkv, .webm, .ogg, .opus and .ts. No exit status is among those
conditions, and the difference from separate_audio_video is
deliberate. The batch runner records whether a row succeeded and not
how. So it records a non-zero exit, a hard error and a reached limit the same
way. It treats alike a row put here by any of them. The
nine are an exclusion list and not a survey. FFmpeg
writes several audio streams into other containers too, .avi and
.nut among them. A row that fails on one of those is still named. The
container condition keeps a row off the list when it already does what the
warning advises. Such a row is silently not named. A batch whose failed audio
rows all write to those nine does not warn at all. The
headline count follows the rows actually named.
Each bullet of the warning states what that row did: its track count, and that every track was mapped into one output. It never states why FFmpeg refused. Several causes look alike from here. Examples are a stream copy into a container that will not hold the source codec, an unknown encoder and a missing output directory.
The check runs FFprobe on the failed rows only. So the function emits the
warning when FFprobe is available and the input can be probed, and skips it
silently otherwise. The warning may not appear, and its absence is never
itself a second failure. The check never runs under run = FALSE and
never changes any compiled command. Suppress the warning with
suppressWarnings(classes = "tidymedia_multitrack_separation").
The warning names the same event as the error of
separate_audio_video and answers to the same class. But it
carries no exit status: no tm_status field, and no
tidymedia_ffmpeg_exit class. The batch runner records, per row,
whether the row succeeded, not how FFmpeg exited. The
success column holds that record. So the exit number is gone by the
time this warning is assembled. To catch a specific row's exit status, use
separate_audio_video().
See Also
separate_audio_video(), the one-file function it wraps.
ffm_batch(), the batch runner.
has_hardware_encoder() for the hardware argument.
segment_video_batch() for the other batch function where one input file
can give several outputs.
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(),
standardize_video(),
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(),
standardize_video(),
standardize_video_batch()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
jobs <- tibble::tibble(
input = c(video, video),
audiofile = c("a1.aac", "a2.aac"),
videofile = c("v1.mp4", "v2.mp4")
)
# run = FALSE compiles two commands per input without calling FFmpeg
separate_audio_video_batch(jobs, run = FALSE)
Set the location of a dependency program
Description
set_program() saves the location of a program, so the package can find it
in later sessions. set_ffmpeg(), set_ffprobe(), set_ffplay() and
set_mediainfo() do the same for one program each.
The location goes in a file named after the program, such as
ffmpeg_location.txt. The file is under
tools::R_user_dir("tidymedia", "config"). find_ffmpeg() and the other
find_*() functions read it when the program is not on the PATH.
Usage
set_program(
program = c("ffmpeg", "ffprobe", "ffplay", "mediainfo"),
location,
confirm = TRUE
)
set_mediainfo(location, confirm = TRUE)
set_ffmpeg(location, confirm = TRUE)
set_ffprobe(location, confirm = TRUE)
set_ffplay(location, confirm = TRUE)
Arguments
program |
A string naming the program to set the location for. |
location |
A string with the location of the program. |
confirm |
Whether to ask before the call writes the location. |
Details
The file stays after the session ends, so the call asks you to confirm first. It writes nothing until you agree. The question shows the location as you typed it, which is what the call writes. It also shows the full path of the file. If you say no, the call changes nothing.
In a session where no one can answer, the call gives an error. Pass
confirm = FALSE to write without the question, for example in a script
that runs on its own.
For locations saved by versions before 0.2.0, see the section "Locations
saved by earlier versions" in find_ffmpeg().
Value
Invisibly, TRUE when the call wrote the location and FALSE when
you said no.
See Also
find_ffmpeg() and the other find_*() functions to find a
program, and install_on_win() to download FFmpeg on Windows.
Other program management functions:
find_ffmpeg(),
install_on_win(),
program_status(),
unset_program()
Examples
## Not run:
# Point tidymedia at a binary in a non-standard location; asks first
set_mediainfo("C:/Program Files/MediaInfo/mediainfo.exe")
# In an unattended script, where there is no one to ask
set_mediainfo("C:/Program Files/MediaInfo/mediainfo.exe", confirm = FALSE)
## End(Not run)
Standardize a video to a reproducible format
Description
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 |
height |
The output height in pixels (a positive number), or |
fps |
The output frame rate (a positive number or FFmpeg framerate
expression such as |
video_codec |
A string naming the output video codec (default
|
audio_codec |
A string naming the output audio codec. The default
|
pixel_format |
A string naming the output pixel format (default
|
hardware |
The encoder backend. |
fallback |
A logical. When a |
quality |
A number, or |
audio_stream |
The audio track to carry into the output, as a number that counts from |
run |
A logical: run the command through FFmpeg ( |
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.
Value
The compiled FFmpeg command (invisibly when run = TRUE).
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)
# Pin resolution and frame rate too
standardize_video(video, "std.mp4", width = 1280, height = 720, fps = 30,
run = FALSE)
# Carry only the second audio track instead of all of them
standardize_video(video, "std.mp4", audio_stream = 1, run = FALSE)
Standardize Many Videos From a Jobs Table
Description
Re-encode many files to a reproducible format, using one jobs table. This is
the batch form of standardize_video(), for when you have more than one
video to standardize. Each row is one input, and the only required column
names its source. The function is a thin wrapper over
ffm_batch. It builds one reproducible command for each input.
The glossary in vignette("tidymedia") explains media terms such as
codec, pixel format and frame rate.
Usage
standardize_video_batch(
jobs,
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,
parallel = FALSE,
...
)
Arguments
jobs |
A data frame with one row per input. It needs at least an
|
width, height |
Optional target dimensions for every row, unless
|
fps |
Optional target frame rate applied to every row, unless
|
video_codec |
A string naming the video codec for every row, unless
|
audio_codec |
A string naming the audio codec for every row, unless
|
pixel_format |
A string naming the pixel format applied to every row,
unless |
hardware |
The encoder backend for every row. |
fallback |
A logical. When a |
quality |
A number, or |
audio_stream |
The audio track to carry into each output, as a number that counts from |
run |
A logical: run each input's command through FFmpeg ( |
parallel |
A logical passed to |
... |
Additional arguments forwarded to |
Value
The tibble returned by ffm_batch: jobs with an added command column. When output was derived, it also has the resolved output column. When run = TRUE, it has a success column, plus any columns the forwarded arguments add, such as verified.
See Also
standardize_video() for the single-input form; ffm_batch() for
the batch runner and the arguments forwarded through ...;
segment_video_batch() and extract_frame_batch() for the other batch
task functions.
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(),
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()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
jobs <- tibble::tibble(
input = c(video, video),
output = c("a.mp4", "b.mp4"),
width = c(640, 320)
)
# run = FALSE compiles one command per input without calling FFmpeg
standardize_video_batch(jobs, run = FALSE)
Strip identifying metadata from a media file
Description
Remove a media file's container and global metadata tags, together with any
chapters, and write a de-identified copy. The tags include creation time,
GPS or other location, device make and model, title and comment. Use it to
de-identify research recordings, for example for an IRB (a research ethics
board). The audio and video streams are stream-copied, not re-encoded. So the operation is
lossless and fast, and the picture and sound are bit-for-bit unchanged. That
includes any rotation display matrix, which is stream side data and not a
metadata tag. The glossary in vignette("tidymedia") explains media
terms such as container, stream and stream copy.
Usage
strip_metadata(infile, outfile, run = TRUE)
Arguments
infile |
A string containing the path to a media file. |
outfile |
A string containing the path of the de-identified file to
write. Use the same container extension as |
run |
A logical: run the command through FFmpeg ( |
Details
The output is written bit-exactly (-fflags +bitexact). So FFmpeg does
not stamp the container again with a fresh creation_time, or with an
encoder tag that names its own version. Either tag would defeat
de-identification and reproducibility.
Because the streams are copied and not re-encoded, some data is not removed.
Those are identifiers inside the encoded bitstream, and per-stream
metadata such as handler_name or language. Removing them would
require one of two things. One is re-encoding, which is out of scope for this
function, so use the direct command ffmpeg for it. The other
is per-stream metadata mapping that must probe the file first.
Value
The compiled FFmpeg command (invisibly when run = TRUE).
See Also
anonymize_video() removes faces or regions from the picture, for
visual de-identification. probe_container() and mediainfo_query()
inspect a file's metadata before and after. This function wraps the
pipeline functions ffm_copy() and ffm_output_options().
strip_metadata_batch() is 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(),
standardize_video_batch(),
strip_metadata_batch()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
strip_metadata(video, "clean.mp4", run = FALSE)
Strip Metadata From Many Files From a Jobs Table
Description
De-identify many files, using one jobs table. This is the batch form of
strip_metadata(), for when you have more than one file to scrub. Each row
is one input, and the only required column names its source. The function
is a thin wrapper over ffm_batch. It builds one reproducible
stream-copy strip command for each input. Each command uses the same steps
as strip_metadata(), so it is bit-exact and drops the same metadata.
The glossary in vignette("tidymedia") explains media terms such as
stream and stream copy.
Usage
strip_metadata_batch(jobs, run = TRUE, parallel = FALSE, ...)
Arguments
jobs |
A data frame with one row per input. It needs at least an
|
run |
A logical: run each input's command through FFmpeg ( |
parallel |
A logical passed to |
... |
Additional arguments forwarded to |
Value
The tibble returned by ffm_batch: jobs with an added command column. When output was derived, it also has the resolved output column. When run = TRUE, it has a success column, plus any columns the forwarded arguments add, such as verified.
See Also
strip_metadata() for the single-input form; ffm_batch() for the
batch runner and the arguments forwarded through ...;
standardize_video_batch() and anonymize_video_batch() for the other
batch task functions.
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(),
standardize_video_batch(),
strip_metadata()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
jobs <- tibble::tibble(input = video, output = "clean.mp4")
# run = FALSE compiles one command per input without calling FFmpeg
strip_metadata_batch(jobs, run = FALSE)
Tidy eval helpers
Description
The .data pronoun is reexported from rlang. It represents the current
slice of data inside data-masking verbs. If you have a column name stored in
a string, use .data[["var"]] to refer to that column. See the rlang reference for details.
Value
This page documents no function and returns no value. .data is
not called either: it is an object, of class rlang_fake_data_pronoun,
that has meaning only inside a data-masking verb, where it stands for the
current slice of data. Subsetting it there, as .data[["var"]], gives
that column.
Forget the location of a dependency program
Description
unset_program() forgets the location that set_program() saved for a
program. After that, find_ffmpeg() and the other find_*() functions look
for the program on the PATH only.
Usage
unset_program(program)
Arguments
program |
A string naming the program to forget. One of |
Details
The call deletes the file that holds the location. It does not ask you to
confirm first. It does not remove the program, and it does not change the
PATH. A program on the PATH is still found afterwards.
If no location is saved for the program, the call gives a warning and
returns FALSE. It does not give an error, because the program is already
forgotten.
The call also clears a location saved by a version before 0.2.0. See the
section "Locations saved by earlier versions" in find_ffmpeg().
Value
Invisibly, TRUE when the call removed a saved location, and FALSE
when there was none to remove.
See Also
set_program() to save a location, and program_status() to see
where the package finds each program.
Other program management functions:
find_ffmpeg(),
install_on_win(),
program_status(),
set_program()
Examples
## Not run:
# Forget a location set_program() remembered, so that find_mediainfo() goes
# back to answering from the PATH
unset_program("mediainfo")
## End(Not run)
Verify a Media File Against Expected Properties
Description
Probe a media file and check its structural metadata against a set of expectations, returning a tidy pass/fail tibble with one row per checked property. A reproducible command tells you what ran. This function tells you whether the result is what you asked for. Use it after a conversion to confirm that the output has the duration, dimensions, codecs and other properties the pipeline was meant to produce.
Usage
verify_media(
file,
duration = NULL,
width = NULL,
height = NULL,
video_codec = NULL,
audio_codec = NULL,
sample_rate = NULL,
...,
tolerance = 0.1
)
Arguments
file |
A string naming a single media file to verify. |
duration |
Expected container duration in seconds (numeric). |
width, height |
Expected video-frame dimensions in pixels (numeric). |
video_codec, audio_codec |
Expected codec names for the first video and
audio stream (strings, e.g. |
sample_rate |
Expected audio sample rate in Hz (numeric). |
... |
Further expectations given as |
tolerance |
The absolute tolerance for numeric checks (default |
Details
The glossary in vignette("tidymedia") explains media terms such as codec,
stream and keyframe.
Checks are structural (drawn from FFprobe metadata), not perceptual: this
does not measure visual or audio quality. The named arguments cover the most
common properties; pass any other FFprobe field by name through ... (for
example pix_fmt = "yuv420p" or bit_rate = 141800). Extra names are
resolved against the probe columns in the order container, then video stream,
then audio stream, and the first match wins.
Numeric checks pass when abs(actual - expected) <= tolerance. With the
default tolerance of 0.1, whole-number properties (width, height, sample
rate) must match exactly. The duration check allows a small difference, for
example for cuts that snap to a keyframe. String checks (the codecs) must
match exactly. A property whose stream or column is absent yields an NA
actual value and a failing check.
Value
A tibble with one row per checked property
and columns file, check, expected, actual, and pass (logical).
See Also
ffm_run() and ffm_batch(), which accept a verify = spec.
Other verification functions:
ffm_manifest()
Examples
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
verify_media(video, width = 320, height = 240, video_codec = "h264")
Set a time limit for one call
Description
with_timeout() runs expr with a time limit of its own. The limit applies
to each FFmpeg, FFprobe or MediaInfo program that expr starts. When
with_timeout() returns, or stops with an error, the limit that was in
force before the call is back.
The session limit, options(tidymedia.timeout = ), applies to every call in
the session. with_timeout() applies to one call. For example, you can give
one test conversion five minutes in a session with a one-hour limit.
Usage
with_timeout(expr, seconds)
Arguments
expr |
An expression. It is run once, where you wrote it, and its value is returned. |
seconds |
A whole number of seconds. |
Details
The limit applies to each program, not to the whole call. In a 100-row batch
inside with_timeout(expr, 600), each program that a row starts gets 600
seconds, plus the delay in "How long the wait can be". The workers of a
parallel = TRUE run use the same limit.
The limit is a whole number of seconds. The package does not round a fraction, because R would read a limit below one second as no limit.
A limit set with options(tidymedia.timeout = ) follows the same rule, with
one difference. options(tidymedia.timeout = NULL) removes the option, so
it means no limit. A function that can start a program gives an error for
a wrong value, even when run = FALSE. ffm_batch() gives that error
before it starts any job. A function that starts no program gives no such
error. For example, has_hardware_encoder() starts none when you set
tidymedia.hardware_encoders. A probe_*() function that you give a
probe object also starts none.
Most functions check their own arguments before the limit. So a wrong
argument gives its own error, even when the limit is also wrong. A few
arguments of the _batch functions are checked inside each job, after the
limit. An example is the pixel_format of anonymize_video_batch(). When
the limit is also wrong, the error is about the limit.
Value
The value of expr.
How long the wait can be
The limit sets how long R waits for a program, and the wait can be longer. When the limit is reached, R asks the program to stop. R asks again 20 seconds later, and kills the program 20 seconds after that. So R can wait up to 40 seconds past the limit. For example, five hung files under a 1-second limit can take about three and a half minutes.
R does not guarantee that the program stops. A program can survive the attempts to stop it. How fast a program stops also depends on its version.
What happens when the limit is reached
A reached limit is never silent. The call gives an error or a warning.
These functions give an error with the class tidymedia_timeout, which names
the program and the limit:
the task functions whose names do not end in
_batch, exceptsegment_video()-
ffmpeg_codecs(),ffmpeg_encoders()andhas_hardware_encoder()when it asks FFmpeg -
verify_media(), because a check with no answer is not a "no"
These functions give a warning instead, so that one hung file does not lose the rest of the work:
-
probe_all(), the otherprobe_*()functions,mediainfo_parameter(),mediainfo_query(),mediainfo_template()and theget_*()functions giveNAfor that file. One warning at the end says how many files timed out. -
ffm_batch(),segment_video()and the_batchtask functions setsuccess = FALSEfor that job. One warning at the end says how many jobs timed out. It has the classtidymedia_batch_timeout. Two steps of these calls give an error instead. One is the analysis pass ofnormalize_audio_batch(two_pass = TRUE). The other is the check that FFmpeg has the hardware encoder thathardwarenames, such as"nvenc". That check asks FFmpeg only whentidymedia.hardware_encodersis not set and the session has no stored answer. The glossary invignette("tidymedia")explains hardware encoders. The dropped-track check of
extract_audio(),convert_audio(),normalize_audio()and their_batchforms warns that it could not check. The track count thatseparate_audio_video()reads after a failed run warns the same way. A batch manifest, seeffm_manifest(), andprogram_status()warn when they cannot read a program version. These warnings have the classtidymedia_probe_timeout, and the call goes on as it would for an unreadable input.
suppressWarnings(classes = "tidymedia_dropped_audio") hides the
dropped-track warning, but not the warning that the check timed out. To hide
both, add "tidymedia_probe_timeout" to classes.
The task functions and ffm_run() delete a part-written output file after a
timeout, as they do after any failed run. ffmpeg() cannot tell which of
your arguments is the output, so it leaves that file. Check the output of a
timed-out ffmpeg() call yourself.
See Also
local_timeout() to set a limit for the rest of a function.
tidymedia-package describes the session options.
Examples
# Inside the call, the limit is the one you gave.
with_timeout(getOption("tidymedia.timeout"), 30)
# Outside it, the session's own setting is untouched.
getOption("tidymedia.timeout", default = "unset")
# Bound one conversion at five minutes, whatever the session is set to.
# Needs FFmpeg, and writes to a temporary file.
if (nzchar(Sys.which("ffmpeg"))) {
video <- system.file("extdata", "sample.mp4", package = "tidymedia")
with_timeout(extract_audio(video, tempfile(fileext = ".wav")), 300)
}