subx_cli/cli/sync_args.rs
1//! Audio-subtitle synchronization command-line arguments and options.
2//!
3//! This module defines the command-line interface for the `sync` subcommand,
4//! which handles timing alignment between video audio tracks and subtitle files.
5//! It supports both automatic synchronization using audio analysis and manual
6//! adjustment with specified time offsets.
7//!
8//! # Synchronization Methods
9//!
10//! ## Automatic Synchronization
11//! Uses advanced audio analysis to detect speech patterns and align them
12//! with subtitle timestamps:
13//! - **Speech detection**: Identifies speech segments in audio
14//! - **Pattern matching**: Correlates speech timing with subtitle timing
15//! - **Offset calculation**: Determines optimal time shift
16//! - **Confidence scoring**: Evaluates alignment quality
17//!
18//! ## Manual Synchronization
19//! Applies user-specified time offset to all subtitle entries:
20//! - Positive offset: Delays subtitles (subtitles appear later)
21//! - Negative offset: Advances subtitles (subtitles appear earlier)
22//! - Preserves relative timing between subtitle entries
23//!
24//! # Examples
25//!
26//! ```bash
27//! # Automatic synchronization
28//! subx sync video.mp4 subtitle.srt
29//!
30//! # Manual offset: delay subtitles by 2.5 seconds
31//! subx sync video.mp4 subtitle.srt --offset 2.5
32//!
33//! # Batch processing with custom parameters
34//! subx sync video.mp4 subtitle.srt --batch --range 10.0 --threshold 0.8
35//! ```
36
37// src/cli/sync_args.rs
38use clap::Args;
39use std::path::PathBuf;
40
41/// Command-line arguments for audio-subtitle synchronization.
42///
43/// The sync command aligns subtitle timing with video audio tracks using
44/// either automatic audio analysis or manual time offset adjustment.
45/// It provides fine-tuned control over the synchronization process with
46/// configurable parameters for different content types.
47///
48/// # Workflow
49///
50/// 1. **Audio Analysis**: Extract audio features from the video file
51/// 2. **Speech Detection**: Identify speech segments and timing
52/// 3. **Pattern Matching**: Correlate speech patterns with subtitle timing
53/// 4. **Offset Calculation**: Determine optimal time adjustment
54/// 5. **Validation**: Verify synchronization quality
55/// 6. **Application**: Apply timing adjustments to subtitle file
56///
57/// # Examples
58///
59/// ```rust
60/// use subx_cli::cli::SyncArgs;
61/// use std::path::PathBuf;
62///
63/// // Automatic synchronization
64/// let auto_args = SyncArgs {
65/// video: PathBuf::from("movie.mp4"),
66/// subtitle: PathBuf::from("movie.srt"),
67/// offset: None,
68/// batch: false,
69/// range: Some(15.0),
70/// threshold: Some(0.75),
71/// };
72///
73/// // Manual synchronization with 2-second delay
74/// let manual_args = SyncArgs {
75/// video: PathBuf::from("movie.mp4"),
76/// subtitle: PathBuf::from("movie.srt"),
77/// offset: Some(2.0),
78/// batch: false,
79/// range: None,
80/// threshold: None,
81/// };
82/// ```
83#[derive(Args, Debug)]
84pub struct SyncArgs {
85 /// Video file path for audio analysis.
86 ///
87 /// The video file from which audio will be extracted and analyzed
88 /// for speech pattern detection. Supports common video formats:
89 ///
90 /// # Supported Formats
91 /// - MP4, MKV, AVI (most common)
92 /// - MOV, WMV, FLV
93 /// - M4V, 3GP, WEBM
94 /// - VOB, TS, MTS
95 ///
96 /// # Requirements
97 /// - File must contain at least one audio track
98 /// - Audio track should contain speech (not just music/effects)
99 /// - Minimum duration of 30 seconds recommended for accuracy
100 ///
101 /// # Examples
102 /// ```bash
103 /// # Standard video file
104 /// subx sync /path/to/movie.mp4 subtitle.srt
105 ///
106 /// # High-definition video
107 /// subx sync "./Movies/Film (2023) [1080p].mkv" subtitle.srt
108 /// ```
109 pub video: PathBuf,
110
111 /// Subtitle file path to be synchronized.
112 ///
113 /// The subtitle file whose timing will be adjusted to match the
114 /// video's audio track. Supports all major subtitle formats:
115 ///
116 /// # Supported Formats
117 /// - SRT (SubRip): Most common format
118 /// - ASS/SSA (Advanced SubStation Alpha): Rich formatting
119 /// - VTT (WebVTT): Web-optimized format
120 /// - SUB (MicroDVD): Frame-based format
121 ///
122 /// # File Requirements
123 /// - Must contain valid timestamps
124 /// - Should have reasonable subtitle density (not too sparse)
125 /// - Text content should roughly correspond to audio speech
126 ///
127 /// # Examples
128 /// ```bash
129 /// # Various subtitle formats
130 /// subx sync video.mp4 subtitle.srt
131 /// subx sync video.mp4 subtitle.ass
132 /// subx sync video.mp4 subtitle.vtt
133 /// ```
134 pub subtitle: PathBuf,
135
136 /// Manual time offset in seconds (overrides automatic detection).
137 ///
138 /// When specified, disables automatic synchronization and applies
139 /// a fixed time offset to all subtitle entries. Positive values
140 /// delay subtitles (appear later), negative values advance them.
141 ///
142 /// # Precision
143 /// Supports fractional seconds with millisecond precision:
144 /// - 2.5 = 2 seconds, 500 milliseconds
145 /// - -1.25 = -1 second, -250 milliseconds
146 /// - 0.1 = 100 milliseconds
147 ///
148 /// # Use Cases
149 /// - **Fine-tuning**: Small adjustments after automatic sync
150 /// - **Known offset**: When you know the exact timing difference
151 /// - **Problematic audio**: When automatic detection fails
152 /// - **Batch processing**: Apply same offset to multiple files
153 ///
154 /// # Examples
155 /// ```bash
156 /// # Delay subtitles by 2.5 seconds
157 /// subx sync video.mp4 subtitle.srt --offset 2.5
158 ///
159 /// # Advance subtitles by 1 second
160 /// subx sync video.mp4 subtitle.srt --offset -1.0
161 ///
162 /// # Fine adjustment by 300ms
163 /// subx sync video.mp4 subtitle.srt --offset 0.3
164 /// ```
165 #[arg(long)]
166 pub offset: Option<f64>,
167
168 /// Enable batch processing mode for multiple file pairs.
169 ///
170 /// When enabled, optimizes processing for handling multiple video-subtitle
171 /// pairs efficiently. This mode provides enhanced performance and
172 /// consistent parameters across all processed files.
173 ///
174 /// # Batch Mode Features
175 /// - **Parallel processing**: Multiple files processed simultaneously
176 /// - **Consistent parameters**: Same sync settings for all files
177 /// - **Progress tracking**: Overall progress across all files
178 /// - **Error resilience**: Continues processing if individual files fail
179 ///
180 /// # File Discovery
181 /// In batch mode, the command can automatically discover matching pairs:
182 /// - Video and subtitle files with same base name
183 /// - Common naming patterns (e.g., movie.mp4 + movie.srt)
184 /// - Multiple subtitle languages (e.g., movie.en.srt, movie.es.srt)
185 ///
186 /// # Examples
187 /// ```bash
188 /// # Process multiple files in directory
189 /// subx sync --batch /path/to/videos/ /path/to/subtitles/
190 ///
191 /// # Batch with custom parameters
192 /// subx sync --batch --range 20.0 --threshold 0.85 videos/ subs/
193 /// ```
194 #[arg(long)]
195 pub batch: bool,
196
197 /// Maximum offset detection range in seconds.
198 ///
199 /// Defines the maximum time range (both positive and negative) within
200 /// which the automatic synchronization algorithm will search for the
201 /// optimal offset. This parameter balances detection accuracy with
202 /// processing time.
203 ///
204 /// # Default Behavior
205 /// If not specified, uses the value from configuration file
206 /// (`max_offset_seconds`). Common defaults are 10-30 seconds depending
207 /// on content type and expected synchronization accuracy.
208 ///
209 /// # Recommendations
210 /// - **Precise timing**: 5-10 seconds for high-quality sources
211 /// - **Standard content**: 10-20 seconds for most videos
212 /// - **Problematic sync**: 30-60 seconds for heavily offset content
213 /// - **Performance priority**: 5-15 seconds for faster processing
214 ///
215 /// # Trade-offs
216 /// - **Larger range**: Higher chance of finding correct offset, slower processing
217 /// - **Smaller range**: Faster processing, may miss large offsets
218 ///
219 /// # Examples
220 /// ```bash
221 /// # High precision with smaller range
222 /// subx sync video.mp4 subtitle.srt --range 5.0
223 ///
224 /// # Handle large offsets
225 /// subx sync video.mp4 subtitle.srt --range 60.0
226 ///
227 /// # Balanced approach
228 /// subx sync video.mp4 subtitle.srt --range 15.0
229 /// ```
230 #[arg(long)]
231 pub range: Option<f32>,
232
233 /// Correlation threshold for automatic synchronization (0.0-1.0).
234 ///
235 /// Sets the minimum correlation coefficient required between audio
236 /// speech patterns and subtitle timing for a synchronization to be
237 /// considered successful. Higher values require stronger correlation
238 /// but provide more reliable results.
239 ///
240 /// # Scale Interpretation
241 /// - **0.9-1.0**: Excellent correlation (very reliable)
242 /// - **0.8-0.9**: Good correlation (reliable for most content)
243 /// - **0.7-0.8**: Acceptable correlation (may need verification)
244 /// - **0.6-0.7**: Weak correlation (results questionable)
245 /// - **Below 0.6**: Poor correlation (likely incorrect sync)
246 ///
247 /// # Configuration Override
248 /// If not specified, uses the value from configuration file
249 /// (`correlation_threshold`). This allows consistent behavior
250 /// across different synchronization operations.
251 ///
252 /// # Content Type Recommendations
253 /// - **Dialog-heavy content**: 0.8-0.9 (speech patterns clear)
254 /// - **Action/music-heavy**: 0.7-0.8 (speech less prominent)
255 /// - **Documentary/interview**: 0.85-0.95 (clear speech patterns)
256 /// - **Animated content**: 0.75-0.85 (consistent voice patterns)
257 ///
258 /// # Examples
259 /// ```bash
260 /// # High precision requirement
261 /// subx sync video.mp4 subtitle.srt --threshold 0.9
262 ///
263 /// # More permissive for difficult content
264 /// subx sync video.mp4 subtitle.srt --threshold 0.7
265 ///
266 /// # Balanced approach
267 /// subx sync video.mp4 subtitle.srt --threshold 0.8
268 /// ```
269 #[arg(long)]
270 pub threshold: Option<f32>,
271}
272
273/// Synchronization method enumeration.
274///
275/// Defines the approach used for subtitle-audio alignment based on
276/// the provided command-line arguments. The method is automatically
277/// determined by the presence of manual offset parameters.
278///
279/// # Method Selection
280/// - **Manual**: When `--offset` parameter is provided
281/// - **Auto**: When no offset is specified (default behavior)
282///
283/// # Examples
284///
285/// ```rust
286/// use subx_cli::cli::{SyncArgs, SyncMethod};
287/// use std::path::PathBuf;
288///
289/// // Auto sync (no offset specified)
290/// let auto_args = SyncArgs {
291/// video: PathBuf::from("video.mp4"),
292/// subtitle: PathBuf::from("subtitle.srt"),
293/// offset: None,
294/// batch: false,
295/// range: None,
296/// threshold: None,
297/// };
298/// assert_eq!(auto_args.sync_method(), SyncMethod::Auto);
299///
300/// // Manual sync (offset specified)
301/// let manual_args = SyncArgs {
302/// video: PathBuf::from("video.mp4"),
303/// subtitle: PathBuf::from("subtitle.srt"),
304/// offset: Some(2.5),
305/// batch: false,
306/// range: None,
307/// threshold: None,
308/// };
309/// assert_eq!(manual_args.sync_method(), SyncMethod::Manual);
310/// ```
311#[derive(Debug, Clone, PartialEq)]
312pub enum SyncMethod {
313 /// Automatic synchronization using audio analysis.
314 ///
315 /// Performs sophisticated audio-subtitle correlation analysis:
316 /// 1. **Audio extraction**: Extract audio track from video
317 /// 2. **Speech detection**: Identify speech segments and pauses
318 /// 3. **Pattern analysis**: Create timing fingerprint
319 /// 4. **Correlation**: Match patterns with subtitle timing
320 /// 5. **Optimization**: Find best offset within specified range
321 Auto,
322
323 /// Manual synchronization using specified time offset.
324 ///
325 /// Applies a fixed time shift to all subtitle entries:
326 /// - Simple and fast operation
327 /// - Preserves relative timing between subtitles
328 /// - Useful for known timing differences
329 /// - No audio analysis required
330 Manual,
331}
332
333impl SyncArgs {
334 /// Determines the synchronization method based on provided arguments.
335 ///
336 /// This method automatically selects between manual and automatic
337 /// synchronization based on whether a manual offset was specified.
338 /// It provides a convenient way to branch synchronization logic.
339 ///
340 /// # Logic
341 /// - Returns `SyncMethod::Manual` if `offset` field is `Some(value)`
342 /// - Returns `SyncMethod::Auto` if `offset` field is `None`
343 ///
344 /// # Examples
345 ///
346 /// ```rust
347 /// use subx_cli::cli::{SyncArgs, SyncMethod};
348 /// use std::path::PathBuf;
349 ///
350 /// let args = SyncArgs {
351 /// video: PathBuf::from("video.mp4"),
352 /// subtitle: PathBuf::from("subtitle.srt"),
353 /// offset: Some(1.5),
354 /// batch: false,
355 /// range: None,
356 /// threshold: None,
357 /// };
358 ///
359 /// match args.sync_method() {
360 /// SyncMethod::Manual => println!("Using manual offset: {}", args.offset.unwrap()),
361 /// SyncMethod::Auto => println!("Using automatic synchronization"),
362 /// }
363 /// ```
364 pub fn sync_method(&self) -> SyncMethod {
365 if self.offset.is_some() {
366 SyncMethod::Manual
367 } else {
368 SyncMethod::Auto
369 }
370 }
371}
372
373#[cfg(test)]
374mod tests {
375 use super::*;
376
377 #[test]
378 fn test_sync_method_selection_manual() {
379 let args = SyncArgs {
380 video: PathBuf::from("video.mp4"),
381 subtitle: PathBuf::from("subtitle.srt"),
382 offset: Some(2.5),
383 batch: false,
384 range: None,
385 threshold: None,
386 };
387 assert_eq!(args.sync_method(), SyncMethod::Manual);
388 }
389
390 #[test]
391 fn test_sync_method_selection_auto() {
392 let args = SyncArgs {
393 video: PathBuf::from("video.mp4"),
394 subtitle: PathBuf::from("subtitle.srt"),
395 offset: None,
396 batch: false,
397 range: None,
398 threshold: None,
399 };
400 assert_eq!(args.sync_method(), SyncMethod::Auto);
401 }
402}