remove wrapup video rendering (ffmpeg)
All checks were successful
CI / Check / Test (push) Successful in 15m34s
All checks were successful
CI / Check / Test (push) Successful in 15m34s
SPA handles wrapup visuals client-side; server-side renderer was dead code pulling in ffmpeg + image crates.
This commit is contained in:
@@ -2,7 +2,6 @@ use domain::errors::DomainError;
|
||||
use domain::value_objects::WrapUpId;
|
||||
|
||||
use crate::context::AppContext;
|
||||
use crate::wrapup::storage::WrapUpStorage;
|
||||
|
||||
pub async fn execute(ctx: &AppContext, id: WrapUpId) -> Result<(), DomainError> {
|
||||
ctx.repos
|
||||
@@ -11,8 +10,5 @@ pub async fn execute(ctx: &AppContext, id: WrapUpId) -> Result<(), DomainError>
|
||||
.await?
|
||||
.ok_or_else(|| DomainError::NotFound("wrap-up not found".into()))?;
|
||||
|
||||
let storage = WrapUpStorage::new(ctx.services.object_storage.clone());
|
||||
let _ = storage.delete_video(&id).await;
|
||||
|
||||
ctx.repos.wrapup_repo.delete(&id).await
|
||||
}
|
||||
|
||||
@@ -15,10 +15,9 @@ pub struct WrapUpEventHandler {
|
||||
|
||||
impl WrapUpEventHandler {
|
||||
pub fn new(ctx: AppContext) -> Self {
|
||||
let max = ctx.config.wrapup.max_concurrent_renders;
|
||||
Self {
|
||||
ctx,
|
||||
semaphore: Arc::new(Semaphore::new(max)),
|
||||
semaphore: Arc::new(Semaphore::new(2)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
use crate::context::AppContext;
|
||||
use crate::wrapup::{compute, queries::ComputeWrapUpQuery, storage::WrapUpStorage};
|
||||
use crate::wrapup::{compute, queries::ComputeWrapUpQuery};
|
||||
use domain::errors::DomainError;
|
||||
use domain::events::DomainEvent;
|
||||
use domain::models::wrapup::{DateRange, WrapUpScope, WrapUpStatus};
|
||||
use domain::ports::VideoRenderAssets;
|
||||
use domain::value_objects::WrapUpId;
|
||||
|
||||
pub async fn execute(
|
||||
@@ -45,30 +44,6 @@ pub async fn execute(
|
||||
.set_complete(&wrapup_id, &report)
|
||||
.await?;
|
||||
|
||||
if let Some(ref renderer) = ctx.services.video_renderer {
|
||||
let asset_storage = WrapUpStorage::new(ctx.services.object_storage.clone());
|
||||
let poster_images = asset_storage
|
||||
.resolve_poster_images(&report.poster_paths)
|
||||
.await;
|
||||
let cast_images = asset_storage
|
||||
.resolve_cast_images(&report.top_cast_profile_paths)
|
||||
.await;
|
||||
let assets = VideoRenderAssets {
|
||||
poster_images,
|
||||
cast_images,
|
||||
};
|
||||
match renderer.render(&report, assets).await {
|
||||
Ok(video_bytes) => {
|
||||
if let Err(e) = asset_storage.store_video(&wrapup_id, &video_bytes).await {
|
||||
tracing::warn!("failed to store wrapup video: {e}");
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::warn!("video render failed (non-fatal): {e}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ctx.services
|
||||
.event_publisher
|
||||
.publish(&DomainEvent::WrapUpCompleted { wrapup_id })
|
||||
|
||||
@@ -7,4 +7,3 @@ pub mod get_wrapup;
|
||||
pub mod handle_requested;
|
||||
pub mod list_wrapups;
|
||||
pub mod queries;
|
||||
pub mod storage;
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
use domain::errors::DomainError;
|
||||
use domain::ports::ObjectStorage;
|
||||
use domain::value_objects::WrapUpId;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub struct WrapUpStorage {
|
||||
inner: Arc<dyn ObjectStorage>,
|
||||
}
|
||||
|
||||
impl WrapUpStorage {
|
||||
pub fn new(storage: Arc<dyn ObjectStorage>) -> Self {
|
||||
Self { inner: storage }
|
||||
}
|
||||
|
||||
pub async fn store_video(&self, id: &WrapUpId, bytes: &[u8]) -> Result<(), DomainError> {
|
||||
let key = format!("wrapups/{}/video.mp4", id.value());
|
||||
self.inner.store(&key, bytes).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn delete_video(&self, id: &WrapUpId) -> Result<(), DomainError> {
|
||||
let key = format!("wrapups/{}/video.mp4", id.value());
|
||||
self.inner.delete(&key).await
|
||||
}
|
||||
|
||||
pub fn cast_image_key(profile_path: &str) -> String {
|
||||
format!("cast{profile_path}")
|
||||
}
|
||||
|
||||
pub async fn resolve_cast_images(&self, profile_paths: &[String]) -> Vec<(String, Vec<u8>)> {
|
||||
let mut images = Vec::new();
|
||||
for path in profile_paths.iter().take(20) {
|
||||
let key = Self::cast_image_key(path);
|
||||
match self.inner.get(&key).await {
|
||||
Ok(bytes) => images.push((key, bytes)),
|
||||
Err(e) => tracing::debug!("cast fetch skipped for {key}: {e}"),
|
||||
}
|
||||
}
|
||||
tracing::info!(
|
||||
"resolved {}/{} cast images",
|
||||
images.len(),
|
||||
profile_paths.len()
|
||||
);
|
||||
images
|
||||
}
|
||||
|
||||
pub async fn resolve_poster_images(&self, paths: &[String]) -> Vec<(String, Vec<u8>)> {
|
||||
let mut images = Vec::new();
|
||||
for path in paths.iter().take(20) {
|
||||
match self.inner.get(path).await {
|
||||
Ok(bytes) => images.push((path.clone(), bytes)),
|
||||
Err(e) => tracing::debug!("poster fetch skipped for {path}: {e}"),
|
||||
}
|
||||
}
|
||||
tracing::info!("resolved {}/{} poster images", images.len(), paths.len());
|
||||
images
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user