Skip to main content

unbundle/
lib.rs

1//! # unbundle
2//!
3//! Unbundle media files — extract still frames, audio tracks, and subtitles
4//! from video files.
5//!
6//! `unbundle` provides a clean, ergonomic API for extracting video frames as
7//! [`image::DynamicImage`] values, audio tracks as encoded byte vectors, and
8//! subtitle tracks as structured text, powered by FFmpeg via the
9//! [`ffmpeg-next`](https://crates.io/crates/ffmpeg-next) crate.
10//!
11//! ## Quick Start
12//!
13//! ### Extract a Video Frame
14//!
15//! ```no_run
16//! use unbundle::MediaFile;
17//!
18//! let mut unbundler = MediaFile::open("input.mp4").unwrap();
19//! let frame = unbundler.video().frame(0).unwrap();
20//! frame.save("first_frame.png").unwrap();
21//! ```
22//!
23//! ### Extract Audio
24//!
25//! ```no_run
26//! use unbundle::{AudioFormat, MediaFile};
27//!
28//! let mut unbundler = MediaFile::open("input.mp4").unwrap();
29//! unbundler.audio().save("output.wav", AudioFormat::Wav).unwrap();
30//! ```
31//!
32//! ### Extract Frames by Range
33//!
34//! ```no_run
35//! use std::time::Duration;
36//!
37//! use unbundle::{FrameRange, MediaFile};
38//!
39//! let mut unbundler = MediaFile::open("input.mp4").unwrap();
40//!
41//! // Every 30th frame
42//! let frames = unbundler.video().frames(FrameRange::Interval(30)).unwrap();
43//!
44//! // Frames between two timestamps
45//! let frames = unbundler.video().frames(
46//!     FrameRange::TimeRange(Duration::from_secs(10), Duration::from_secs(20))
47//! ).unwrap();
48//! ```
49//!
50//! ### Extract Subtitles
51//!
52//! ```no_run
53//! use unbundle::{MediaFile, SubtitleFormat};
54//!
55//! let mut unbundler = MediaFile::open("input.mkv").unwrap();
56//! unbundler.subtitle().save("output.srt", SubtitleFormat::Srt).unwrap();
57//! ```
58//!
59//! ## Features
60//!
61//! - **Frame extraction** — by frame number, timestamp, range, interval, or
62//!   specific frame list
63//! - **Audio extraction** — to WAV, MP3, FLAC, or AAC (file or in-memory)
64//! - **Subtitle extraction** — decode text-based subtitles to SRT, WebVTT, or
65//!   raw text
66//! - **Container remuxing** — lossless format conversion (e.g. MKV → MP4)
67//! - **Rich metadata** — video dimensions, frame rate, frame count, audio
68//!   sample rate, channels, codec info, multi-track audio/subtitle metadata
69//! - **Configurable output** — pixel format (RGB8, RGBA8, GRAY8) and target
70//!   resolution with aspect ratio preservation
71//! - **Progress & cancellation** — cooperative callbacks and
72//!   `CancellationToken` for long-running operations
73//! - **Streaming iteration** — lazy `FrameIterator` (pull-based) and
74//!   `for_each_frame` (push-based) without buffering entire frame sets
75//! - **Validation** — inspect media files for structural issues before
76//!   extraction
77//! - **Chapter support** — extract chapter metadata (titles, timestamps)
78//! - **Frame metadata** — per-frame decode info (PTS, keyframe, picture type)
79//! - **Segmented extraction** — extract from multiple disjoint time ranges
80//! - **Stream probing** — lightweight `MediaProbe` for quick inspection
81//! - **Thumbnail helpers** — single thumbnails, grids, and smart selection
82//! - **Efficient seeking** — seeks to nearest keyframe, then decodes forward
83//! - **Zero-copy in-memory audio** — uses FFmpeg's dynamic buffer I/O
84//!
85//! ### Optional Features
86//!
87//! | Feature | Description |
88//! |---------|-------------|
89//! | `async` | `FrameStream` and `AudioFuture` for async extraction via Tokio |
90//! | `rayon` | `frames_parallel()` distributes decoding across rayon threads |
91//! | `hardware` | Hardware-accelerated decoding (CUDA, VAAPI, DXVA2, D3D11VA, VideoToolbox, QSV) |
92//! | `scene` | Scene change detection via FFmpeg's `scdet` filter |
93//! | `full` | Enables all of the above |
94//!
95//! ## Requirements
96//!
97//! FFmpeg development libraries must be installed on your system. See the
98//! [README](https://github.com/skanderjeddi/unbundle#installation) for
99//! platform-specific instructions.
100
101pub mod audio;
102pub mod audio_iterator;
103pub mod configuration;
104mod conversion;
105#[cfg(feature = "encode")]
106pub mod encode;
107pub mod error;
108#[cfg(feature = "gif")]
109pub mod gif;
110#[cfg(feature = "hardware")]
111pub mod hardware_acceleration;
112pub mod keyframe;
113#[cfg(feature = "loudness")]
114pub mod loudness;
115pub mod metadata;
116pub mod packet_iterator;
117pub mod probe;
118pub mod progress;
119#[cfg(feature = "rayon")]
120mod rayon;
121pub mod remux;
122#[cfg(feature = "scene")]
123pub mod scene;
124#[cfg(feature = "async")]
125pub mod stream;
126pub mod subtitle;
127pub mod thumbnail;
128#[cfg(feature = "transcode")]
129pub mod transcode;
130pub mod unbundle;
131pub mod validation;
132pub mod variable_framerate;
133pub mod video;
134pub mod video_iterator;
135#[cfg(feature = "waveform")]
136pub mod waveform;
137
138pub use audio::{AudioFormat, AudioHandle};
139pub use audio_iterator::{AudioChunk, AudioIterator};
140pub use configuration::{ExtractOptions, FrameOutputOptions, PixelFormat};
141#[cfg(feature = "encode")]
142pub use encode::{VideoCodec, VideoEncoder, VideoEncoderOptions};
143pub use error::UnbundleError;
144#[cfg(feature = "gif")]
145pub use gif::GifOptions;
146#[cfg(feature = "hardware")]
147pub use hardware_acceleration::{HardwareAccelerationMode, HardwareDeviceType};
148pub use keyframe::{GroupOfPicturesInfo, KeyFrameMetadata};
149#[cfg(feature = "loudness")]
150pub use loudness::LoudnessInfo;
151pub use metadata::{
152    AudioMetadata, ChapterMetadata, MediaMetadata, SubtitleMetadata, VideoMetadata,
153};
154pub use packet_iterator::{PacketInfo, PacketIterator};
155pub use probe::MediaProbe;
156pub use progress::{CancellationToken, OperationType, ProgressCallback, ProgressInfo};
157pub use remux::Remuxer;
158#[cfg(feature = "scene")]
159pub use scene::{SceneChange, SceneDetectionMode, SceneDetectionOptions};
160#[cfg(feature = "async")]
161pub use stream::{AudioFuture, FrameStream};
162pub use subtitle::{BitmapSubtitleEvent, SubtitleEvent, SubtitleFormat, SubtitleHandle};
163pub use thumbnail::{ThumbnailHandle, ThumbnailOptions};
164#[cfg(feature = "transcode")]
165pub use transcode::Transcoder;
166pub use unbundle::MediaFile;
167pub use validation::ValidationReport;
168pub use variable_framerate::VariableFrameRateAnalysis;
169pub use video::{FrameMetadata, FrameRange, FrameType, VideoHandle};
170pub use video_iterator::FrameIterator;
171#[cfg(feature = "waveform")]
172pub use waveform::{WaveformBin, WaveformData, WaveformOptions};