mirror of
https://github.com/osmarks/meme-search-engine.git
synced 2025-03-12 14:38:13 +00:00
misc fixes
- thumbnails/OCR off was broken - problematic video files caused segfaults (I blame ffmpeg for this)
This commit is contained in:
parent
3257521068
commit
747058e254
@ -140,7 +140,7 @@
|
|||||||
<div class="result">
|
<div class="result">
|
||||||
<a href={util.getURL(result)}>
|
<a href={util.getURL(result)}>
|
||||||
{#if util.hasFormat(results, result, "VIDEO")}
|
{#if util.hasFormat(results, result, "VIDEO")}
|
||||||
<video controls poster={util.thumbnailURL(results, result, "jpegh")} preload="metadata" on:loadstart={updateCounter} on:loadedmetadata={redrawGrid}>
|
<video controls poster={util.hasFormat("jpegh") ? util.thumbnailURL(results, result, "jpegh") : null} preload="metadata" on:loadstart={updateCounter} on:loadedmetadata={redrawGrid} on:loadeddata={redrawGrid}>
|
||||||
<source src={util.getURL(result)} />
|
<source src={util.getURL(result)} />
|
||||||
</video>
|
</video>
|
||||||
{:else}
|
{:else}
|
||||||
|
@ -7,7 +7,7 @@ esbuild
|
|||||||
.build({
|
.build({
|
||||||
entryPoints: [path.join(__dirname, "app.js")],
|
entryPoints: [path.join(__dirname, "app.js")],
|
||||||
bundle: true,
|
bundle: true,
|
||||||
minify: false,
|
minify: true,
|
||||||
outfile: path.join(__dirname, "../static/app.js"),
|
outfile: path.join(__dirname, "../static/app.js"),
|
||||||
plugins: [sveltePlugin({
|
plugins: [sveltePlugin({
|
||||||
preprocess: {
|
preprocess: {
|
||||||
|
47
src/main.rs
47
src/main.rs
@ -14,7 +14,6 @@ use axum::{
|
|||||||
http::StatusCode
|
http::StatusCode
|
||||||
};
|
};
|
||||||
use common::resize_for_embed_sync;
|
use common::resize_for_embed_sync;
|
||||||
use ffmpeg_the_third::device::input::video;
|
|
||||||
use image::RgbImage;
|
use image::RgbImage;
|
||||||
use image::{imageops::FilterType, io::Reader as ImageReader, DynamicImage, ImageFormat};
|
use image::{imageops::FilterType, io::Reader as ImageReader, DynamicImage, ImageFormat};
|
||||||
use reqwest::Client;
|
use reqwest::Client;
|
||||||
@ -343,12 +342,14 @@ async fn ingest_files(config: Arc<WConfig>) -> Result<()> {
|
|||||||
image: embed_buf,
|
image: embed_buf,
|
||||||
filename: Filename::VideoFrame(filename.clone(), i)
|
filename: Filename::VideoFrame(filename.clone(), i)
|
||||||
})?;
|
})?;
|
||||||
to_thumbnail_tx.blocking_send(LoadedImage {
|
if config.service.enable_thumbs {
|
||||||
image: frame.clone(),
|
to_thumbnail_tx.blocking_send(LoadedImage {
|
||||||
filename: Filename::VideoFrame(filename.clone(), i),
|
image: frame.clone(),
|
||||||
original_size: None,
|
filename: Filename::VideoFrame(filename.clone(), i),
|
||||||
fast_thumbnails_only: true
|
original_size: None,
|
||||||
})?;
|
fast_thumbnails_only: true
|
||||||
|
})?;
|
||||||
|
}
|
||||||
i += 1;
|
i += 1;
|
||||||
Ok(())
|
Ok(())
|
||||||
};
|
};
|
||||||
@ -378,23 +379,23 @@ async fn ingest_files(config: Arc<WConfig>) -> Result<()> {
|
|||||||
}
|
}
|
||||||
if record.needs_thumbnail {
|
if record.needs_thumbnail {
|
||||||
to_thumbnail_tx
|
to_thumbnail_tx
|
||||||
.send(LoadedImage {
|
.send(LoadedImage {
|
||||||
image: image.clone(),
|
image: image.clone(),
|
||||||
filename: Filename::Actual(record.filename.clone()),
|
filename: Filename::Actual(record.filename.clone()),
|
||||||
original_size: Some(std::fs::metadata(&path)?.len() as usize),
|
original_size: Some(std::fs::metadata(&path)?.len() as usize),
|
||||||
fast_thumbnails_only: false
|
fast_thumbnails_only: false
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
if record.needs_ocr {
|
if record.needs_ocr {
|
||||||
to_ocr_tx
|
to_ocr_tx
|
||||||
.send(LoadedImage {
|
.send(LoadedImage {
|
||||||
image,
|
image,
|
||||||
filename: Filename::Actual(record.filename.clone()),
|
filename: Filename::Actual(record.filename.clone()),
|
||||||
original_size: None,
|
original_size: None,
|
||||||
fast_thumbnails_only: true
|
fast_thumbnails_only: true
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -634,8 +635,8 @@ async fn ingest_files(config: Arc<WConfig>) -> Result<()> {
|
|||||||
None => Some(FileRecord {
|
None => Some(FileRecord {
|
||||||
filename: filename.clone(),
|
filename: filename.clone(),
|
||||||
needs_embed: true,
|
needs_embed: true,
|
||||||
needs_ocr: true,
|
needs_ocr: config.service.enable_ocr,
|
||||||
needs_thumbnail: true
|
needs_thumbnail: config.service.enable_thumbs
|
||||||
}),
|
}),
|
||||||
Some(r) => {
|
Some(r) => {
|
||||||
let needs_embed = modtime > r.embedding_time.unwrap_or(i64::MIN);
|
let needs_embed = modtime > r.embedding_time.unwrap_or(i64::MIN);
|
||||||
|
@ -2,7 +2,7 @@ extern crate ffmpeg_the_third as ffmpeg;
|
|||||||
use anyhow::{Result, Context};
|
use anyhow::{Result, Context};
|
||||||
use image::RgbImage;
|
use image::RgbImage;
|
||||||
use std::env;
|
use std::env;
|
||||||
use ffmpeg::{codec, filter, format::{self, Pixel}, media::Type, util::frame::video::Video};
|
use ffmpeg::{codec, filter, format::{self, Pixel}, media::Type, util::frame::video::Video, software::scaling};
|
||||||
|
|
||||||
const BYTES_PER_PIXEL: usize = 3;
|
const BYTES_PER_PIXEL: usize = 3;
|
||||||
|
|
||||||
@ -20,7 +20,11 @@ pub fn run<P: AsRef<std::path::Path>, F: FnMut(RgbImage) -> Result<()>>(path: P,
|
|||||||
graph.add(&filter::find("buffer").unwrap(), "in",
|
graph.add(&filter::find("buffer").unwrap(), "in",
|
||||||
&format!("video_size={}x{}:pix_fmt={}:time_base={}/{}:pixel_aspect={}/{}", decoder.width(), decoder.height(), decoder.format().descriptor().unwrap().name(), video.time_base().0, video.time_base().1, decoder.aspect_ratio().0, decoder.aspect_ratio().1))?;
|
&format!("video_size={}x{}:pix_fmt={}:time_base={}/{}:pixel_aspect={}/{}", decoder.width(), decoder.height(), decoder.format().descriptor().unwrap().name(), video.time_base().0, video.time_base().1, decoder.aspect_ratio().0, decoder.aspect_ratio().1))?;
|
||||||
graph.add(&filter::find("buffersink").unwrap(), "out", "")?;
|
graph.add(&filter::find("buffersink").unwrap(), "out", "")?;
|
||||||
graph.output("in", 0)?.input("out", 0)?.parse(&format!("[in] thumbnail=n={}:log=verbose [thumbs]; [thumbs] select='gt(scene,0.05)+eq(n,0)' [out]", afr)).context("filtergraph parse failed")?;
|
// I don't know exactly where, but some of my videos apparently have the size vary throughout them.
|
||||||
|
// This causes horrible segfaults somewhere.
|
||||||
|
// Rescale to initial width to fix this. We could do this with a separate swscaler but this is easier.
|
||||||
|
let filterspec = format!("[in] scale={}:{} [scaled]; [scaled] thumbnail=n={}:log=verbose [thumbs]; [thumbs] select='gt(scene,0.05)+eq(n,0)' [out]", decoder.width(), decoder.height(), afr);
|
||||||
|
graph.output("in", 0)?.input("out", 0)?.parse(&filterspec).context("filtergraph parse failed")?;
|
||||||
let mut out = graph.get("out").unwrap();
|
let mut out = graph.get("out").unwrap();
|
||||||
out.set_pixel_format(Pixel::RGB24);
|
out.set_pixel_format(Pixel::RGB24);
|
||||||
|
|
||||||
@ -33,6 +37,7 @@ pub fn run<P: AsRef<std::path::Path>, F: FnMut(RgbImage) -> Result<()>>(path: P,
|
|||||||
if !decoder.receive_frame(&mut decoded).is_ok() { break }
|
if !decoder.receive_frame(&mut decoded).is_ok() { break }
|
||||||
|
|
||||||
let mut in_ctx = filter_graph.get("in").unwrap();
|
let mut in_ctx = filter_graph.get("in").unwrap();
|
||||||
|
// The filters really do not like
|
||||||
let mut src = in_ctx.source();
|
let mut src = in_ctx.source();
|
||||||
src.add(&decoded).context("add frame")?;
|
src.add(&decoded).context("add frame")?;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user