- 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.
94 lines
2.7 KiB
Rust
94 lines
2.7 KiB
Rust
use eframe::egui;
|
|
|
|
/// Estado da execução do FFmpeg.
|
|
#[derive(Default, PartialEq)]
|
|
pub enum ExecutionState {
|
|
#[default]
|
|
Idle,
|
|
Running,
|
|
Success,
|
|
Error(String),
|
|
}
|
|
|
|
/// Painel de execução: botão "Gerar MKV", progresso e erros.
|
|
pub struct ExecutionPanel {
|
|
pub state: ExecutionState,
|
|
pub log_lines: Vec<String>,
|
|
}
|
|
|
|
impl ExecutionPanel {
|
|
pub fn new() -> Self {
|
|
ExecutionPanel {
|
|
state: ExecutionState::Idle,
|
|
log_lines: Vec::new(),
|
|
}
|
|
}
|
|
|
|
pub fn add_log(&mut self, line: String) {
|
|
self.log_lines.push(line);
|
|
// Limita o histórico de log
|
|
if self.log_lines.len() > 200 {
|
|
self.log_lines.remove(0);
|
|
}
|
|
}
|
|
|
|
/// Renderiza o painel. Retorna `true` se o botão "Gerar MKV" foi clicado.
|
|
pub fn ui(&mut self, ui: &mut egui::Ui, can_generate: bool) -> bool {
|
|
let mut clicked = false;
|
|
|
|
ui.group(|ui| {
|
|
ui.heading("Gerar arquivo");
|
|
|
|
let is_running = self.state == ExecutionState::Running;
|
|
|
|
if ui
|
|
.add_enabled(
|
|
can_generate && !is_running,
|
|
egui::Button::new(if is_running {
|
|
"Processando…"
|
|
} else {
|
|
"Gerar MKV"
|
|
}),
|
|
)
|
|
.clicked()
|
|
{
|
|
clicked = true;
|
|
}
|
|
|
|
match &self.state {
|
|
ExecutionState::Idle => {}
|
|
ExecutionState::Running => {
|
|
ui.spinner();
|
|
ui.label("Processando...");
|
|
}
|
|
ExecutionState::Success => {
|
|
ui.colored_label(egui::Color32::GREEN, "✓ Arquivo gerado com sucesso!");
|
|
}
|
|
ExecutionState::Error(msg) => {
|
|
ui.colored_label(egui::Color32::RED, "✗ Erro durante o processamento:");
|
|
ui.add(
|
|
egui::TextEdit::multiline(&mut msg.as_str())
|
|
.desired_rows(4)
|
|
.desired_width(f32::INFINITY),
|
|
);
|
|
}
|
|
}
|
|
|
|
// Log de progresso
|
|
if !self.log_lines.is_empty() {
|
|
ui.collapsing("Log detalhado", |ui| {
|
|
egui::ScrollArea::vertical()
|
|
.max_height(150.0)
|
|
.show(ui, |ui| {
|
|
for line in &self.log_lines {
|
|
ui.label(egui::RichText::new(line).monospace().size(11.0));
|
|
}
|
|
});
|
|
});
|
|
}
|
|
});
|
|
|
|
clicked
|
|
}
|
|
}
|