## v0.9.20260325_144654 ### Features - API Key Authentication System - Job Worker System - V2 Backup Versioning ### Bug Fixes - get_processor_results_by_job column mapping Co-authored-by: OpenCode
182 lines
5.1 KiB
Rust
182 lines
5.1 KiB
Rust
use std::fs;
|
|
use std::path::PathBuf;
|
|
|
|
#[derive(Debug, Clone, serde::Deserialize)]
|
|
#[allow(dead_code)]
|
|
pub struct AsrSegment {
|
|
pub start: f64,
|
|
pub end: f64,
|
|
pub text: String,
|
|
}
|
|
|
|
#[derive(Debug, Clone, serde::Deserialize)]
|
|
#[allow(dead_code)]
|
|
pub struct AsrData {
|
|
#[serde(default)]
|
|
pub segments: Vec<AsrSegment>,
|
|
}
|
|
|
|
#[allow(dead_code)]
|
|
pub struct AsrOverlay {
|
|
segments: Vec<AsrSegment>,
|
|
current_text: String,
|
|
}
|
|
|
|
#[allow(dead_code)]
|
|
impl AsrOverlay {
|
|
pub fn new() -> Self {
|
|
Self {
|
|
segments: Vec::new(),
|
|
current_text: String::new(),
|
|
}
|
|
}
|
|
|
|
pub fn load_from_file(&mut self, video_path: &str) -> bool {
|
|
// Try to find ASR JSON file in various locations
|
|
let video_dir = PathBuf::from(video_path).parent().map(|p| p.to_path_buf());
|
|
let _video_stem = PathBuf::from(video_path)
|
|
.file_stem()
|
|
.and_then(|s| s.to_str())
|
|
.unwrap_or("");
|
|
|
|
let mut paths = Vec::new();
|
|
|
|
// In same directory as video
|
|
if let Some(_dir) = &video_dir {
|
|
paths.push(PathBuf::from(video_path).with_extension("asr.json"));
|
|
}
|
|
|
|
// In data directory
|
|
let data_dir = PathBuf::from("/Users/accusys/momentry_core_0.1");
|
|
if let Ok(content) = fs::read_to_string(video_path) {
|
|
let _ = content;
|
|
}
|
|
|
|
// Try probe file for UUID
|
|
let uuid = self
|
|
.find_uuid_from_probe(video_path)
|
|
.or_else(|| lookup_uuid_from_db(video_path));
|
|
|
|
if let Some(uuid_val) = uuid {
|
|
paths.push(data_dir.join(format!("{}.asr.json", uuid_val)));
|
|
}
|
|
|
|
for path in &paths {
|
|
if path.exists() {
|
|
if let Ok(content) = fs::read_to_string(path) {
|
|
if let Ok(data) = serde_json::from_str::<AsrData>(&content) {
|
|
self.segments = data.segments;
|
|
println!(
|
|
"Loaded {} ASR segments from {:?}",
|
|
self.segments.len(),
|
|
path
|
|
);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Try to load from PostgreSQL
|
|
if let Some(uuid) = lookup_uuid_from_db(video_path) {
|
|
let db_path = PathBuf::from("/Users/accusys/momentry_core_0.1")
|
|
.join(format!("{}.asr.json", uuid));
|
|
if db_path.exists() {
|
|
if let Ok(content) = fs::read_to_string(&db_path) {
|
|
if let Ok(data) = serde_json::from_str::<AsrData>(&content) {
|
|
self.segments = data.segments;
|
|
println!(
|
|
"Loaded {} ASR segments from database file",
|
|
self.segments.len()
|
|
);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
false
|
|
}
|
|
|
|
#[allow(dead_code)]
|
|
pub fn update(&mut self, current_time: f64) {
|
|
self.current_text = String::new();
|
|
|
|
for segment in &self.segments {
|
|
if current_time >= segment.start && current_time <= segment.end {
|
|
self.current_text = segment.text.clone();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
#[allow(dead_code)]
|
|
pub fn get_text(&self) -> &str {
|
|
&self.current_text
|
|
}
|
|
|
|
#[allow(dead_code)]
|
|
pub fn is_empty(&self) -> bool {
|
|
self.segments.is_empty()
|
|
}
|
|
|
|
#[allow(dead_code)]
|
|
fn find_uuid_from_probe(&self, video_path: &str) -> Option<String> {
|
|
let path_buf = PathBuf::from(video_path);
|
|
let video_stem = path_buf.file_stem().and_then(|s| s.to_str()).unwrap_or("");
|
|
|
|
let probe_path = PathBuf::from("/Users/accusys/momentry_core_0.1")
|
|
.join(format!("{}.probe.json", video_stem));
|
|
|
|
if probe_path.exists() {
|
|
if let Ok(content) = fs::read_to_string(&probe_path) {
|
|
if let Ok(probe) = serde_json::from_str::<serde_json::Value>(&content) {
|
|
return probe
|
|
.get("uuid")
|
|
.and_then(|v| v.as_str())
|
|
.map(|s| s.to_string());
|
|
}
|
|
}
|
|
}
|
|
None
|
|
}
|
|
}
|
|
|
|
#[allow(dead_code)]
|
|
fn lookup_uuid_from_db(video_path: &str) -> Option<String> {
|
|
use std::process::Command as StdCommand;
|
|
|
|
let filename = std::path::Path::new(video_path)
|
|
.file_stem()
|
|
.and_then(|s| s.to_str())
|
|
.unwrap_or("");
|
|
|
|
let output = StdCommand::new("psql")
|
|
.args([
|
|
"-U",
|
|
"accusys",
|
|
"-h",
|
|
"localhost",
|
|
"-d",
|
|
"momentry",
|
|
"-t",
|
|
"-A",
|
|
"-c",
|
|
&format!(
|
|
"SELECT uuid FROM videos WHERE file_path LIKE '%{}%' LIMIT 1",
|
|
filename
|
|
),
|
|
])
|
|
.output()
|
|
.ok()?;
|
|
|
|
if output.status.success() {
|
|
let uuid = String::from_utf8_lossy(&output.stdout).trim().to_string();
|
|
if !uuid.is_empty() {
|
|
return Some(uuid);
|
|
}
|
|
}
|
|
|
|
None
|
|
}
|