pub struct SegmentedFileMuxer { /* private fields */ }Expand description
Builds a SegmentedFileMuxer the same two-phase way as a plain
FileMuxer (every track’s shape must be known before the first byte
is written) — create picks the rotation policy and how segments get
named, add_stream registers each track exactly like
FileMuxer::add_stream, open writes the first segment’s header and
returns one Sink per track.
let mut muxer = SegmentedFileMuxer::create(
SegmentPolicy::Duration(Duration::from_secs(600)),
|index| PathBuf::from(format!("rec_{index:04}.mp4")),
);
muxer.add_stream("video", video_encoder.parameters(), video_time_base);
muxer.add_stream("audio", audio_encoder.parameters(), audio_time_base);
let mut sinks = muxer.open()?;Implementations§
Source§impl SegmentedFileMuxer
impl SegmentedFileMuxer
Sourcepub fn create(
policy: SegmentPolicy,
naming: impl FnMut(u64) -> PathBuf + Send + 'static,
) -> Self
pub fn create( policy: SegmentPolicy, naming: impl FnMut(u64) -> PathBuf + Send + 'static, ) -> Self
naming(index) names each segment file, index starting at 0 —
called once up front for the first segment and again on every
rotation. Typically a closure building a path from a fixed
directory/prefix (e.g. |i| dir.join(format!("rec_{i:04}.mp4")));
a timestamp-based scheme works just as well since index is only
ever used to call this, never to build the path itself.
Sourcepub fn add_stream(
&mut self,
name: impl Into<String>,
parameters: Parameters,
time_base: Rational,
)
pub fn add_stream( &mut self, name: impl Into<String>, parameters: Parameters, time_base: Rational, )
Registers one more track every segment file will hold — same
contract as FileMuxer::add_stream (same order rules, same
name/parameters/time_base meaning), except this can’t fail:
nothing here touches ffmpeg yet, it’s only recorded for
SegmentedFileMuxer::open (and every later rotation) to replay.
Whichever stream’s parameters.medium() is
ffmpeg::media::Type::Video (at most one is expected) becomes
the keyframe-gating track described in SegmentedFileMuxer::open’s
own docs — no separate flag to pass.
Sourcepub fn open(self) -> Result<Vec<Box<dyn Sink>>>
pub fn open(self) -> Result<Vec<Box<dyn Sink>>>
Writes the first segment’s header and returns one Sink per
track, in the order SegmentedFileMuxer::add_stream added them —
same shape as FileMuxer::open. All returned Sinks share one
rotation lock: a track’s consume blocks while another track (on
its own thread) is mid-rotation, same tradeoff FileMuxer’s own
shared file lock already makes.
Rotation timing: once a segment has run at least as long as the
configured SegmentPolicy, the cut happens on the video
track’s next keyframe (found via add_stream’s parameters — see
its own docs) — not immediately, and not on an arbitrary packet —
so every segment file is independently decodable from its own
first frame, the same way a real segment/HLS muxer cuts. A segment
can therefore run somewhat longer than requested if keyframes are
sparse; there’s no hard cap. If no track’s parameters.medium()
was Video (an audio-only recording), any packet on any track is
an equally valid cut point, so rotation happens as soon as the
policy is due.
The final segment is finalized the same way a plain FileMuxer
finalizes its one file: once every track has reported Eos or
ControlMsg::Stop (see FileMuxer::open’s own docs) — a
rotation mid-recording reuses that exact mechanism to close the
outgoing segment before opening the next one.