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