Initial vid-repair scaffold
This commit is contained in:
83
vid-repair-core/src/scan/ffprobe.rs
Normal file
83
vid-repair-core/src/scan/ffprobe.rs
Normal file
@@ -0,0 +1,83 @@
|
||||
use std::path::Path;
|
||||
use std::process::Command;
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use serde_json::Value;
|
||||
|
||||
use super::types::{ProbeData, StreamInfo};
|
||||
|
||||
pub fn run_ffprobe(path: &Path, ffprobe_path: &str) -> Result<ProbeData> {
|
||||
let output = Command::new(ffprobe_path)
|
||||
.arg("-v")
|
||||
.arg("error")
|
||||
.arg("-print_format")
|
||||
.arg("json")
|
||||
.arg("-show_format")
|
||||
.arg("-show_streams")
|
||||
.arg(path)
|
||||
.output()
|
||||
.with_context(|| format!("Failed to run ffprobe on {}", path.display()))?;
|
||||
|
||||
if !output.status.success() {
|
||||
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||
anyhow::bail!(
|
||||
"ffprobe failed for {}: {}",
|
||||
path.display(),
|
||||
stderr.trim()
|
||||
);
|
||||
}
|
||||
|
||||
let raw: Value = serde_json::from_slice(&output.stdout)
|
||||
.with_context(|| format!("Failed to parse ffprobe output for {}", path.display()))?;
|
||||
|
||||
let format_name = raw
|
||||
.get("format")
|
||||
.and_then(|fmt| fmt.get("format_name"))
|
||||
.and_then(|v| v.as_str())
|
||||
.map(|s| s.to_string());
|
||||
|
||||
let duration = raw
|
||||
.get("format")
|
||||
.and_then(|fmt| fmt.get("duration"))
|
||||
.and_then(|v| v.as_str())
|
||||
.and_then(|s| s.parse::<f64>().ok());
|
||||
|
||||
let streams = raw
|
||||
.get("streams")
|
||||
.and_then(|v| v.as_array())
|
||||
.map(|arr| {
|
||||
arr.iter()
|
||||
.map(|stream| StreamInfo {
|
||||
codec_type: stream
|
||||
.get("codec_type")
|
||||
.and_then(|v| v.as_str())
|
||||
.map(|s| s.to_string()),
|
||||
codec_name: stream
|
||||
.get("codec_name")
|
||||
.and_then(|v| v.as_str())
|
||||
.map(|s| s.to_string()),
|
||||
width: stream.get("width").and_then(|v| v.as_u64()).map(|v| v as u32),
|
||||
height: stream
|
||||
.get("height")
|
||||
.and_then(|v| v.as_u64())
|
||||
.map(|v| v as u32),
|
||||
sample_rate: stream
|
||||
.get("sample_rate")
|
||||
.and_then(|v| v.as_str())
|
||||
.map(|s| s.to_string()),
|
||||
channels: stream
|
||||
.get("channels")
|
||||
.and_then(|v| v.as_u64())
|
||||
.map(|v| v as u32),
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
})
|
||||
.unwrap_or_default();
|
||||
|
||||
Ok(ProbeData {
|
||||
format_name,
|
||||
duration,
|
||||
streams,
|
||||
raw,
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user