Skip to main content

SegmentedFileMuxer

Struct SegmentedFileMuxer 

Source
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

Source

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.

Source

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.

Source

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.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more