Simplify sermon converter for backend metadata handling
- Remove NFO file creation (backend now handles metadata) - Simplify filename handling to preserve original names - Remove complex parsing logic (no longer needed) - Clean up configuration and dependencies - Backend parses "Title - Speaker Date.mp4" format directly
This commit is contained in:
parent
18bddf4e6f
commit
a5c9cc0cda
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -812,6 +812,7 @@ checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65"
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "video_processing"
|
name = "video_processing"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
source = "git+https://git.rockvilletollandsda.church/RTSDA/video-processing-support.git?branch=main#734c7296641ed1954b3054679e04f2a286d7f321"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
|
|
|
@ -1,69 +1,27 @@
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use anyhow::{Result, anyhow};
|
use anyhow::{Result, anyhow};
|
||||||
use chrono::NaiveDate;
|
|
||||||
use regex::Regex;
|
|
||||||
use video_processing::{
|
use video_processing::{
|
||||||
VideoProcessingConfig, VideoConverter as SharedVideoConverter, NfoGenerator, FileProcessor
|
VideoProcessingConfig, VideoConverter as SharedVideoConverter, FileProcessor
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct VideoConverter {
|
pub struct VideoConverter {
|
||||||
output_path: PathBuf,
|
output_path: PathBuf,
|
||||||
config: VideoProcessingConfig,
|
config: VideoProcessingConfig,
|
||||||
video_converter: SharedVideoConverter,
|
video_converter: SharedVideoConverter,
|
||||||
nfo_generator: NfoGenerator,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VideoConverter {
|
impl VideoConverter {
|
||||||
pub fn new(output_path: PathBuf) -> Self {
|
pub fn new(output_path: PathBuf) -> Self {
|
||||||
let config = VideoProcessingConfig::from_env();
|
let config = VideoProcessingConfig::from_env();
|
||||||
let video_converter = SharedVideoConverter::new(config.clone());
|
let video_converter = SharedVideoConverter::new(config.clone());
|
||||||
let nfo_generator = NfoGenerator::new(config.clone());
|
|
||||||
|
|
||||||
VideoConverter {
|
VideoConverter {
|
||||||
output_path,
|
output_path,
|
||||||
config,
|
config,
|
||||||
video_converter,
|
video_converter,
|
||||||
nfo_generator,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: File stability checking is now handled by the caller using the shared crate
|
|
||||||
|
|
||||||
pub async fn extract_date_from_filename(&self, filename: &str) -> Result<NaiveDate> {
|
|
||||||
// Example filename: "Sermon Title - Speaker (December 4th 2024).mp4"
|
|
||||||
if let Some(date_part) = filename.split('(').nth(1).and_then(|part| part.split(')').next()) {
|
|
||||||
let re = Regex::new(r"(?i)(January|February|March|April|May|June|July|August|September|October|November|December)\s+(\d+)(?:st|nd|rd|th)?\s+(\d{4})")?;
|
|
||||||
|
|
||||||
if let Some(caps) = re.captures(date_part) {
|
|
||||||
let month = caps.get(1).unwrap().as_str();
|
|
||||||
let day = caps.get(2).unwrap().as_str();
|
|
||||||
let year = caps.get(3).unwrap().as_str();
|
|
||||||
|
|
||||||
let date_str = format!("{} {} {}", day, month, year);
|
|
||||||
let date = NaiveDate::parse_from_str(&date_str, "%d %B %Y")?;
|
|
||||||
Ok(date)
|
|
||||||
} else {
|
|
||||||
Err(anyhow!("Could not extract date from filename part within parentheses"))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Err(anyhow!("No date found in parentheses in filename"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn extract_title_and_speaker(&self, filename: &str) -> Result<(String, String)> {
|
|
||||||
// Example: "God's People in the Time of the End - Pastor Joseph Piresson (December 28th 2024).mp4"
|
|
||||||
if let Some(main_part) = filename.split('(').next() {
|
|
||||||
if let Some((title, speaker)) = main_part.split_once('-') {
|
|
||||||
return Ok((
|
|
||||||
title.trim().to_string(),
|
|
||||||
speaker.trim().to_string()
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(anyhow!("Could not extract title and speaker from filename"))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pub async fn process_file(&self, path: PathBuf) -> Result<()> {
|
pub async fn process_file(&self, path: PathBuf) -> Result<()> {
|
||||||
// Early checks
|
// Early checks
|
||||||
if path.to_string_lossy().contains(".syncthing.") {
|
if path.to_string_lossy().contains(".syncthing.") {
|
||||||
|
@ -78,43 +36,21 @@ impl VideoConverter {
|
||||||
return Err(anyhow!("File no longer exists: {}", path.display()));
|
return Err(anyhow!("File no longer exists: {}", path.display()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: File stability is now handled by the caller
|
|
||||||
|
|
||||||
println!("Processing sermon: {}", path.display());
|
println!("Processing sermon: {}", path.display());
|
||||||
|
|
||||||
// Get the filename
|
// Get the filename and keep it exactly the same
|
||||||
let filename = path.file_name()
|
let filename = path.file_name()
|
||||||
.ok_or_else(|| anyhow!("Invalid filename"))?
|
.ok_or_else(|| anyhow!("Invalid filename"))?;
|
||||||
.to_str()
|
|
||||||
.ok_or_else(|| anyhow!("Invalid UTF-8 in filename"))?;
|
|
||||||
|
|
||||||
// Extract date, title, and speaker from filename
|
// Output file has same name as input
|
||||||
let date = self.extract_date_from_filename(filename).await?;
|
let output_file = self.output_path.join(filename);
|
||||||
let (title, speaker) = self.extract_title_and_speaker(filename).await?;
|
|
||||||
|
|
||||||
// Create date-based directory structure
|
|
||||||
let year_dir = self.output_path.join(date.format("%Y").to_string());
|
|
||||||
let month_dir = year_dir.join(format!("{}-{}",
|
|
||||||
date.format("%m"), // numeric month (12)
|
|
||||||
date.format("%B") // full month name (December)
|
|
||||||
));
|
|
||||||
|
|
||||||
// Create directories if they don't exist
|
|
||||||
tokio::fs::create_dir_all(&month_dir).await?;
|
|
||||||
|
|
||||||
// Keep original filename but ensure .mp4 extension
|
|
||||||
let output_file = month_dir.join(filename);
|
|
||||||
|
|
||||||
println!("Converting to AV1 and saving to: {}", output_file.display());
|
println!("Converting to AV1 and saving to: {}", output_file.display());
|
||||||
|
|
||||||
// Convert video using shared crate
|
// Convert video using shared crate
|
||||||
self.video_converter.convert_video(&path, &output_file).await?;
|
self.video_converter.convert_video(&path, &output_file).await?;
|
||||||
|
|
||||||
// Create NFO file using shared crate
|
println!("Successfully converted {} to AV1", path.display());
|
||||||
let full_title = format!("{} - {}", title, speaker);
|
|
||||||
self.nfo_generator.create_nfo_file(&output_file, &full_title, &date, None).await?;
|
|
||||||
|
|
||||||
println!("Successfully converted {} to AV1 and created NFO", path.display());
|
|
||||||
|
|
||||||
// Handle original file based on configuration
|
// Handle original file based on configuration
|
||||||
if !self.config.preserve_original_files {
|
if !self.config.preserve_original_files {
|
||||||
|
|
Loading…
Reference in a new issue