diff --git a/Cargo.toml b/Cargo.toml index a0203cb7..e45a2f1e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -155,6 +155,13 @@ name = "bench_thumbnails_mem" path = "examples/bench_thumbnails_mem.rs" required-features = ["bench"] +# Video thumbnail benchmark — Option B (server-side ffmpeg frame → WebP). Needs +# `ffmpeg` on PATH (libx264/libx265/libvpx-vp9 to synthesize the test corpus). +[[example]] +name = "bench_video_thumbnails" +path = "examples/bench_video_thumbnails.rs" +required-features = ["bench"] + # DB connection-pool tail-latency benchmark (needs the dev Postgres up). [[example]] name = "bench_db_pool" diff --git a/Dockerfile b/Dockerfile index 347f01cb..e05fcd3e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -67,9 +67,11 @@ LABEL org.opencontainers.image.title="OxiCloud" \ # Install only necessary runtime dependencies and update packages # su-exec is needed by the entrypoint to drop privileges after fixing volume permissions. +# ffmpeg powers server-side video thumbnail extraction (one frame → WebP pipeline); +# without it videos simply have no thumbnail (OXICLOUD_ENABLE_VIDEO_THUMBNAILS). # No libpq: the pure-Rust sqlx postgres driver never links it. RUN apk --no-cache upgrade && \ - apk add --no-cache libgcc ca-certificates tzdata su-exec && \ + apk add --no-cache libgcc ca-certificates tzdata su-exec ffmpeg && \ addgroup -g 1001 -S oxicloud && \ adduser -u 1001 -S oxicloud -G oxicloud diff --git a/benches/VIDEO-THUMB.md b/benches/VIDEO-THUMB.md new file mode 100644 index 00000000..9aae02e5 --- /dev/null +++ b/benches/VIDEO-THUMB.md @@ -0,0 +1,88 @@ +# Video thumbnails — server-side ffmpeg (Option B) + +Video thumbnails are now generated **server-side on upload**: a lifecycle hook +streams the (decrypted) blob to a temp file, `ffmpeg` extracts one representative +frame, and that frame goes through the **same WebP pipeline as photos** — so +video thumbnails are WebP, blob-hash keyed (dedup'd), and content-negotiated, +exactly like images. + +This replaces the old browser path, which only generated a thumbnail when the +Photos grid first rendered a video tile, the `` 404'd, and the browser +**re-downloaded the video** to seek a frame and PUT 3 JPEGs back. + +## What it buys + +1. **Coverage incl. HEVC/iPhone.** The browser `