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
+59
View File
@@ -0,0 +1,59 @@
use anyhow::{anyhow, Context, Result};
use tokio::io::{AsyncBufReadExt, BufReader};
use tokio::process::Command;
use tokio::sync::mpsc;
/// Executa o FFmpeg de forma assíncrona, capturando stderr em tempo real.
/// As linhas de saída são enviadas pelo canal `progress_tx`.
pub async fn run_ffmpeg_async(
args: Vec<String>,
progress_tx: mpsc::UnboundedSender<String>,
) -> Result<()> {
let mut child = Command::new("ffmpeg")
.args(&args)
.stderr(std::process::Stdio::piped())
.stdout(std::process::Stdio::null())
.spawn()
.context("Falha ao iniciar ffmpeg")?;
// Lê stderr em stream para exibir progresso em tempo real
if let Some(stderr) = child.stderr.take() {
let reader = BufReader::new(stderr);
let mut lines = reader.lines();
let tx = progress_tx.clone();
tokio::spawn(async move {
while let Ok(Some(line)) = lines.next_line().await {
let _ = tx.send(line);
}
});
}
let status = child.wait().await.context("Erro ao aguardar ffmpeg")?;
if !status.success() {
return Err(anyhow!(
"FFmpeg encerrou com código de saída: {:?}",
status.code()
));
}
Ok(())
}
/// Verifica se um binário está disponível no PATH.
pub fn check_binary_available(binary: &str) -> Result<()> {
std::process::Command::new(binary)
.arg("-version")
.stdout(std::process::Stdio::null())
.stderr(std::process::Stdio::null())
.status()
.map_err(|_| anyhow!("'{}' não encontrado no PATH. Por favor, instale o FFmpeg.", binary))?;
Ok(())
}
/// Verifica se ffmpeg e ffprobe estão disponíveis.
pub fn validate_dependencies() -> Result<()> {
check_binary_available("ffmpeg")?;
check_binary_available("ffprobe")?;
Ok(())
}