Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
name: ci

on:
push:
pull_request:

env:
Expand Down
14 changes: 9 additions & 5 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
Package: compost
Version: 0.1.0.7
Title: Video Compositing via FFmpeg
Description: Wraps common FFmpeg filter_complex patterns (overlay, chromakey,
concat, scale, vstack) into clean R functions for video compositing, and
lowers an OpenTimelineIO timeline (via rotio) to a rendered video.
Version: 0.1.0.8
Title: Video Compositing via 'FFmpeg'
Description: Wraps common 'FFmpeg' <https://ffmpeg.org/> filter_complex
patterns (overlay, chromakey, concat, scale, vstack) into clean R
functions for video compositing, and lowers an 'OpenTimelineIO'
<https://opentimeline.io/> timeline (via the 'rotio' package) to a
rendered video.
Authors@R: c(
person("Troy", "Hernandez",
email = "troy@cornball.ai",
role = c("aut", "cre"),
comment = c(ORCID = "0009-0005-4248-604X")),
person("cornball.ai", role = "cph"))
License: MIT + file LICENSE
URL: https://github.com/cornball-ai/compost
BugReports: https://github.com/cornball-ai/compost/issues
Encoding: UTF-8
SystemRequirements: ffmpeg (>= 5.0)
Imports:
Expand Down
4 changes: 4 additions & 0 deletions R/align.R
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ align_audio <- function(clip, narration, sr = 8000L, hop = 80L) {
#' @return A data frame with one row per chunk: \code{chunk}, \code{file},
#' \code{frames}, \code{fps}, \code{offset} (narration seconds),
#' \code{correlation}, and \code{overlap} (frames; 0 for the first chunk).
#' @examples
#' \dontrun{
#' align_overlaps(c("media/chunk01.mp4", "media/chunk02.mp4"), "audio.mp3")
#' }
#' @export
align_overlaps <- function(files, narration, fps = 24) {
n <- length(files)
Expand Down
6 changes: 6 additions & 0 deletions R/rms.R
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
#'
#' Slices the audio into \code{window}-sample blocks and prints each block's
#' overall RMS level (dB) as ametadata to \code{mfile}.
#' @param window Window size in samples.
#' @param mfile Path the ametadata print stream is written to.
#' @return A single ffmpeg filter-chain string.
#' @keywords internal
.rms_filter <- function(window, mfile) {
sprintf(paste0("asetnsamples=%d,astats=metadata=1:reset=1,",
Expand All @@ -19,6 +22,9 @@
#' The print stream alternates a \code{pts_time:<t>} line and an
#' \code{RMS_level=<db>} line per window. Digital silence prints \code{-inf},
#' mapped to -120.
#' @param lines Character vector of ffmpeg ametadata print output.
#' @return A list with numeric \code{time} (window centre, seconds) and
#' \code{rms} (RMS level in dB).
#' @keywords internal
.parse_rms <- function(lines) {
tt <- rr <- numeric(length(lines))
Expand Down
28 changes: 28 additions & 0 deletions cran-comments.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
## Submission

This is a new submission.

## Test environments

- Local: Ubuntu 24.04, R release
- Windows 10: R 4.6.0 and R-devel (pre-release), via `R CMD check --as-cran`

## R CMD check results

0 errors | 0 warnings | 1 note

The one NOTE is the expected "New submission" / Maintainer note.

## Notes for the reviewer

- **System requirement.** The package wraps the `ffmpeg` command-line tool
(declared in `SystemRequirements:`, version >= 5.0). Every exported function
shells out to `ffmpeg`/`ffprobe`; nothing is reimplemented in R.

- **`\dontrun` in examples.** All examples are wrapped in `\dontrun{}` rather
than `\donttest{}`. This is deliberate: the examples require both the
`ffmpeg` binary (which is not guaranteed to be present on the check machines)
and user-supplied media files (video/audio that does not ship with the
package). They cannot execute in CRAN's environment, which is the documented
case for `\dontrun` over `\donttest`. The package's tests cover the
command-construction logic without invoking `ffmpeg`.
5 changes: 5 additions & 0 deletions man/align_overlaps.Rd
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,8 @@ each join's overlap from the positions: the seconds by which chunk
chained chunk's duplicated head and an undersized chunk's shortfall both
fall out of where the words actually are.
}
\examples{
\dontrun{
align_overlaps(c("media/chunk01.mp4", "media/chunk02.mp4"), "audio.mp3")
}
}
7 changes: 7 additions & 0 deletions man/dot-parse_rms.Rd
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@
\usage{
.parse_rms(lines)
}
\arguments{
\item{lines}{Character vector of ffmpeg ametadata print output.}
}
\value{
A list with numeric \code{time} (window centre, seconds) and
\code{rms} (RMS level in dB).
}
\description{
The print stream alternates a \code{pts_time:<t>} line and an
\code{RMS_level=<db>} line per window. Digital silence prints \code{-inf},
Expand Down
8 changes: 8 additions & 0 deletions man/dot-rms_filter.Rd
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@
\usage{
.rms_filter(window, mfile)
}
\arguments{
\item{window}{Window size in samples.}

\item{mfile}{Path the ametadata print stream is written to.}
}
\value{
A single ffmpeg filter-chain string.
}
\description{
Slices the audio into \code{window}-sample blocks and prints each block's
overall RMS level (dB) as ametadata to \code{mfile}.
Expand Down
Loading