pict-rs/src/generate.rs

118 lines
3.3 KiB
Rust
Raw Normal View History

use crate::{
concurrent_processor::CancelSafeProcessor,
details::Details,
error::{Error, UploadError},
ffmpeg::ThumbnailFormat,
formats::{InputProcessableFormat, InternalVideoFormat},
repo::{Alias, FullRepo},
store::Store,
};
use actix_web::web::Bytes;
use std::path::PathBuf;
use tokio::io::AsyncReadExt;
2022-04-07 17:56:40 +00:00
use tracing::Instrument;
2022-10-01 01:02:46 +00:00
#[allow(clippy::too_many_arguments)]
#[tracing::instrument(skip(repo, store, hash))]
pub(crate) async fn generate<R: FullRepo, S: Store + 'static>(
repo: &R,
store: &S,
format: InputProcessableFormat,
alias: Alias,
thumbnail_path: PathBuf,
thumbnail_args: Vec<String>,
input_format: Option<InternalVideoFormat>,
thumbnail_format: Option<ThumbnailFormat>,
hash: R::Bytes,
) -> Result<(Details, Bytes), Error> {
let process_fut = process(
repo,
store,
format,
alias,
thumbnail_path.clone(),
thumbnail_args,
input_format,
thumbnail_format,
hash.clone(),
);
let (details, bytes) =
CancelSafeProcessor::new(hash.as_ref(), thumbnail_path, process_fut).await?;
Ok((details, bytes))
}
2022-10-01 01:02:46 +00:00
#[allow(clippy::too_many_arguments)]
#[tracing::instrument(skip(repo, store, hash))]
async fn process<R: FullRepo, S: Store + 'static>(
repo: &R,
store: &S,
format: InputProcessableFormat,
alias: Alias,
thumbnail_path: PathBuf,
thumbnail_args: Vec<String>,
input_format: Option<InternalVideoFormat>,
thumbnail_format: Option<ThumbnailFormat>,
hash: R::Bytes,
) -> Result<(Details, Bytes), Error> {
2022-04-07 17:56:40 +00:00
let permit = crate::PROCESS_SEMAPHORE.acquire().await;
let identifier = if let Some(identifier) = repo
.still_identifier_from_alias::<S::Identifier>(&alias)
.await?
{
identifier
} else {
let Some(identifier) = repo.identifier(hash.clone()).await? else {
return Err(UploadError::MissingIdentifier.into());
};
2022-09-24 22:18:53 +00:00
let reader = crate::ffmpeg::thumbnail(
store.clone(),
identifier,
input_format.unwrap_or(InternalVideoFormat::Mp4),
thumbnail_format.unwrap_or(ThumbnailFormat::Jpeg),
)
.await?;
2022-09-24 22:18:53 +00:00
let motion_identifier = store.save_async_read(reader).await?;
repo.relate_motion_identifier(hash.clone(), &motion_identifier)
.await?;
motion_identifier
};
let mut processed_reader =
crate::magick::process_image_store_read(store.clone(), identifier, thumbnail_args, format)?;
let mut vec = Vec::new();
2022-04-07 17:56:40 +00:00
processed_reader
.read_to_end(&mut vec)
.instrument(tracing::info_span!("Reading processed image to vec"))
.await?;
let bytes = Bytes::from(vec);
drop(permit);
let discovery = crate::discover::discover_bytes(bytes.clone()).await?;
let details = Details::from_parts(
discovery.input.internal_format(),
discovery.width,
discovery.height,
discovery.frames,
);
let identifier = store.save_bytes(bytes.clone()).await?;
repo.relate_details(&identifier, &details).await?;
repo.relate_variant_identifier(
hash,
thumbnail_path.to_string_lossy().to_string(),
&identifier,
)
.await?;
Ok((details, bytes)) as Result<(Details, Bytes), Error>
}