feat: implement project management and media track handling

- Added domain entities for audio, subtitle, and video tracks.
- Created a Project entity to manage media editing sessions.
- Implemented value objects for file paths, sync offsets, track IDs, and languages.
- Developed infrastructure for asynchronous FFmpeg process execution.
- Built a user interface for selecting video files, adding audio and subtitle tracks, and managing output settings.
- Integrated error handling and logging for media processing tasks.
This commit is contained in:
2026-02-28 13:42:23 -03:00
parent eff779a1df
commit ce236eca5d
47 changed files with 6818 additions and 2 deletions
+51
View File
@@ -0,0 +1,51 @@
use eframe::egui;
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.
pub struct SyncOffsetField {
pub raw: String,
pub error: Option<String>,
}
impl SyncOffsetField {
pub fn new(initial: SyncOffset) -> Self {
let seconds = initial.as_ms() as f64 / 1000.0;
SyncOffsetField {
raw: format!("{:.1}", seconds),
error: None,
}
}
/// Renderiza o campo e retorna true se o valor mudou.
pub fn ui(&mut self, ui: &mut egui::Ui, label: &str) -> bool {
let mut changed = false;
ui.horizontal(|ui| {
ui.label(label);
if ui.text_edit_singleline(&mut self.raw).changed() {
changed = true;
self.error = None;
}
ui.label("s");
});
if let Some(ref err) = self.error {
ui.colored_label(egui::Color32::RED, err);
}
changed
}
/// Tenta converter o valor atual para SyncOffset.
pub fn parse(&mut self) -> Option<SyncOffset> {
match SyncOffset::from_seconds_str(&self.raw) {
Ok(offset) => {
self.error = None;
Some(offset)
}
Err(e) => {
self.error = Some(format!("Valor inválido: {}", e));
None
}
}
}
}