Skip to content

Commit a60bb5c

Browse files
authored
release(v3.0.2): ffmpeg-backed video thumbnails (Docker) + new thumbnail API (closes #79)
- Docker: ship ffmpeg so video thumbnails work out-of-the-box in container installs - add /api/file/thumbnail.php endpoint to generate + cache JPEG thumbnails for video files - UI: use ffmpeg-backed thumbnails for hover previews + gallery cards (fallback to movie icon) - harden query param parsing for file endpoints (avoid array/querystring edge cases) - docs: add FFmpeg + archive tools to THIRD_PARTY notices Closes #79
1 parent 7942167 commit a60bb5c

6 files changed

Lines changed: 613 additions & 181 deletions

File tree

CHANGELOG.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,58 @@
11
# Changelog
22

3+
## Changes 01/15/2026 (v3.0.2)
4+
5+
`release(v3.0.2): ffmpeg-backed video thumbnails (Docker) + new thumbnail API (closes #79)`
6+
7+
**Commit message**
8+
9+
```text
10+
release(v3.0.2): ffmpeg-backed video thumbnails (Docker) + new thumbnail API (closes #79)
11+
12+
- Docker: ship ffmpeg so video thumbnails work out-of-the-box in container installs
13+
- add /api/file/thumbnail.php endpoint to generate + cache JPEG thumbnails for video files
14+
- UI: use ffmpeg-backed thumbnails for hover previews + gallery cards (fallback to movie icon)
15+
- harden query param parsing for file endpoints (avoid array/querystring edge cases)
16+
- docs: add FFmpeg + archive tools to THIRD_PARTY notices
17+
18+
Closes #79
19+
```
20+
21+
**Added**
22+
23+
- **Video thumbnail API endpoint:** `GET /api/file/thumbnail.php?folder=...&file=...`
24+
Returns a cached **JPEG** thumbnail for supported video files.
25+
- **Server-side thumbnail generator** (local sources only):
26+
- Uses `ffmpeg` to extract a frame and writes it into a meta-root cache (`thumb_cache/`).
27+
- Cache key includes file path + mtime + size + thumb dimensions for stable reuse.
28+
- Optional env tuning:
29+
- `FR_FFMPEG_PATH` (override ffmpeg path)
30+
- `FR_VIDEO_THUMB_MAX_W`, `FR_VIDEO_THUMB_MAX_H` (thumbnail max size)
31+
- **Docker image now installs `ffmpeg`** so thumbnails work in Docker/Unraid without extra setup.
32+
33+
**Changed**
34+
35+
- **Hover preview video thumbs** now use the thumbnail API instead of `<video preload="metadata">` seeking.
36+
- **Gallery view video cards** now render an `<img>` thumbnail with a play overlay; falls back to the movie icon on error.
37+
- **Thumbnail generation respects your existing “max video preview size (MB)” setting**:
38+
- If a video exceeds the configured cap, the thumbnail endpoint returns “too large”.
39+
- **Source-aware behavior (when Sources is enabled):**
40+
41+
**Security / Hardening**
42+
43+
- Thumbnails are only generated for authenticated users and still enforce:
44+
- ACL read rules (and read_own ownership checks where applicable)
45+
- no thumbnails for encrypted files
46+
- Cache responses include `X-Content-Type-Options: nosniff` and a private cache policy.
47+
48+
**Docs / Compliance**
49+
50+
- Updated `THIRD_PARTY.md` to mention Docker-bundled system packages:
51+
- FFmpeg (LGPL-2.1+; builds may include GPL components)
52+
- p7zip / unar (for archive handling)
53+
54+
---
55+
356
## Changes 01/14/2026 (v3.0.1 Archive update + login focus)
457

558
`release(v3.0.1): archive create/extract upgrades (7z + RAR via unar) + login focus fix (closes #82)`

Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ RUN if [ -f /etc/apt/sources.list.d/ubuntu.sources ]; then \
4141
apt-get install -y --no-install-recommends \
4242
apache2 \
4343
php php-json php-curl php-zip php-mbstring php-gd php-xml \
44+
ffmpeg \
4445
ca-certificates curl git openssl \
4546
smbclient \
4647
7zip \

THIRD_PARTY.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,21 @@ Used optionally for virus scanning of uploads (via the `clamscan` command).
5656
- **Source:** Available via your Linux distribution’s package repositories or from the ClamAV website.
5757
- **Note:** ClamAV runs as a separate executable and is not part of the FileRise application code.
5858

59+
Additional system packages bundled in the Docker image:
60+
61+
- **FFmpeg** — LGPL-2.1+ (some builds include GPL components)
62+
**Home:** <https://ffmpeg.org/>
63+
**Source:** Linux distribution package repositories.
64+
**Note:** Installed for video thumbnail generation.
65+
66+
- **7-Zip (p7zip)** — LGPL-2.1+ with unRAR restriction
67+
**Home:** <https://www.7-zip.org/>
68+
**Source:** Linux distribution package repositories.
69+
70+
- **unar (The Unarchiver)** — LGPL-2.1+
71+
**Home:** <https://theunarchiver.com/>
72+
**Source:** Linux distribution package repositories.
73+
5974
### Base image and system packages
6075

6176
The official Docker image is built on **Ubuntu 24.04** and includes common

public/api/file/thumbnail.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
// public/api/file/thumbnail.php
3+
4+
/**
5+
* @OA\Get(
6+
* path="/api/file/thumbnail.php",
7+
* summary="Get a video thumbnail image",
8+
* description="Returns a cached JPEG thumbnail for supported video files.",
9+
* operationId="getVideoThumbnail",
10+
* tags={"Files"},
11+
* security={{"cookieAuth": {}}},
12+
* @OA\Parameter(name="folder", in="query", required=true, @OA\Schema(type="string"), example="root"),
13+
* @OA\Parameter(name="file", in="query", required=true, @OA\Schema(type="string"), example="clip.mp4"),
14+
* @OA\Response(
15+
* response=200,
16+
* description="Thumbnail image",
17+
* content={
18+
* "image/jpeg": @OA\MediaType(
19+
* mediaType="image/jpeg",
20+
* @OA\Schema(type="string", format="binary")
21+
* )
22+
* }
23+
* ),
24+
* @OA\Response(response=400, description="Invalid folder/file"),
25+
* @OA\Response(response=401, description="Unauthorized"),
26+
* @OA\Response(response=403, description="Forbidden"),
27+
* @OA\Response(response=404, description="Not found")
28+
* )
29+
*/
30+
31+
require_once __DIR__ . '/../../../config/config.php';
32+
require_once PROJECT_ROOT . '/src/controllers/FileController.php';
33+
34+
$fileController = new FileController();
35+
$fileController->videoThumbnail();

0 commit comments

Comments
 (0)