feat: add AdjustExistingTrackDrift use case to adjust drift scale of existing tracks
- Implemented AdjustExistingTrackDrift struct with execute method to modify drift scale of existing tracks in a project. - Added tests for adjusting drift scale, handling non-existent track IDs, and invalid scale values. - Updated MediaTrackInfo and AudioTrack entities to include drift_scale field. - Enhanced Project entity with needs_mkvmerge method to determine if mkvmerge is required based on drift scale. - Integrated drift scale adjustments into existing track list UI, allowing users to modify drift values. - Updated various use cases and UI components to support drift scale functionality, including add audio/subtitle forms and batch processing. - Implemented mkvmerge availability check and integrated it into the application workflow for conditional processing.
This commit is contained in:
@@ -3,9 +3,13 @@ use crate::domain::value_objects::SyncOffset;
|
||||
|
||||
/// Campo de entrada para offset de sincronização em segundos (ex: "-1.2").
|
||||
/// Converte para SyncOffset(ms) internamente ao confirmar.
|
||||
/// Também suporta campo opcional de velocidade original (%) para correção de drift via mkvmerge.
|
||||
pub struct SyncOffsetField {
|
||||
pub raw: String,
|
||||
pub error: Option<String>,
|
||||
/// Percentual de velocidade original (ex: "99.983" → scale 0.99983). Padrão: "100.00".
|
||||
pub drift_raw: String,
|
||||
drift_error: Option<String>,
|
||||
}
|
||||
|
||||
impl SyncOffsetField {
|
||||
@@ -14,10 +18,12 @@ impl SyncOffsetField {
|
||||
SyncOffsetField {
|
||||
raw: format!("{:.1}", seconds),
|
||||
error: None,
|
||||
drift_raw: "100.00".to_string(),
|
||||
drift_error: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Renderiza o campo e retorna true se o valor mudou.
|
||||
/// Renderiza o campo de offset (sem o campo de drift).
|
||||
pub fn ui(&mut self, ui: &mut egui::Ui, label: &str) -> bool {
|
||||
let mut changed = false;
|
||||
ui.horizontal(|ui| {
|
||||
@@ -35,6 +41,42 @@ impl SyncOffsetField {
|
||||
changed
|
||||
}
|
||||
|
||||
/// Renderiza offset + campo de velocidade original (drift) quando `mkvmerge_available`.
|
||||
///
|
||||
/// - Quando `mkvmerge_available = false`: campo de velocidade é exibido desabilitado
|
||||
/// com tooltip pedindo instalação do MKVToolNix.
|
||||
/// - Quando `scale ≠ 1.0`: exibe aviso discreto em laranja.
|
||||
pub fn ui_with_drift(&mut self, ui: &mut egui::Ui, label: &str, mkvmerge_available: bool) -> bool {
|
||||
let offset_changed = self.ui(ui, label);
|
||||
|
||||
ui.horizontal(|ui| {
|
||||
ui.label("Velocidade original (%):");
|
||||
let resp = ui.add_enabled(
|
||||
mkvmerge_available,
|
||||
egui::TextEdit::singleline(&mut self.drift_raw).desired_width(70.0),
|
||||
);
|
||||
if !mkvmerge_available {
|
||||
resp.on_hover_text(
|
||||
"Instale MKVToolNix para usar correção de drift de velocidade.",
|
||||
);
|
||||
}
|
||||
if let Ok(pct) = self.drift_raw.trim().parse::<f64>() {
|
||||
if (pct - 100.0).abs() > 0.001 {
|
||||
ui.colored_label(
|
||||
egui::Color32::from_rgb(255, 160, 0),
|
||||
"⚠ requer mkvmerge",
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if let Some(ref err) = self.drift_error {
|
||||
ui.colored_label(egui::Color32::RED, err);
|
||||
}
|
||||
|
||||
offset_changed
|
||||
}
|
||||
|
||||
/// Tenta converter o valor atual para SyncOffset.
|
||||
pub fn parse(&mut self) -> Option<SyncOffset> {
|
||||
match SyncOffset::from_seconds_str(&self.raw) {
|
||||
@@ -48,4 +90,26 @@ impl SyncOffsetField {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Converte o percentual de velocidade para fator de escala (f64).
|
||||
/// "100.00" → 1.0, "99.983" → 0.99983.
|
||||
/// Retorna `1.0` em caso de erro (fallback seguro).
|
||||
pub fn parse_drift(&mut self) -> f64 {
|
||||
let trimmed = self.drift_raw.trim().trim_end_matches('%');
|
||||
match trimmed.parse::<f64>() {
|
||||
Ok(pct) if pct >= 1.0 && pct <= 999.99 => {
|
||||
self.drift_error = None;
|
||||
pct / 100.0
|
||||
}
|
||||
Ok(_) => {
|
||||
self.drift_error =
|
||||
Some("Velocidade deve estar entre 1.0% e 999.99%".to_string());
|
||||
1.0
|
||||
}
|
||||
Err(_) => {
|
||||
self.drift_error = Some("Valor inválido".to_string());
|
||||
1.0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user