Improves Synology Photos intermediate video quality with hardware-accelerated transcoding
7.6K
Fix the videos Synology Photos ruins.
Automatic re-transcoding of Synology Photos intermediate videos — H.264 High Profile or H.265/HEVC, hardware-accelerated, running on your NAS.
See the project site →
How it works, features, screenshots, codec reference and setup guide
Synology Photos, like YouTube and other streaming platforms, automatically generates lower-quality versions of uploaded videos. These intermediate videos are used for adaptive playback when the connection is not sufficient for the original file, or when the device does not support the original video's codec or resolution (for example, browsers without native HEVC support or devices such as Chromecast V1 that do not support 4K).
The problem is that Synology Photos generates these intermediate videos with very poor quality, especially when videos are uploaded via the web interface. The transcodes are created using H.264 baseline profile and a framerate of only 15 fps. The result is files that take up more space than necessary, look noticeably bad, and can even cause playback issues. Imagine trying to play your videos on a Chromecast and seeing them stutter because of the 15 fps limitation — it's simply not acceptable.
This tool solves that problem by automatically improving the quality of those intermediate videos. It retranscodes them into more efficient and modern formats (H.264 High Profile or H.265/HEVC), using hardware acceleration when available. The result is a significant improvement in visual quality while keeping file sizes efficient.
Synology Photos creates very low-quality intermediate videos (15 fps, H.264 baseline). This tool automatically re-transcodes them to modern formats with hardware acceleration, fixing playback issues and improving visual quality.
/volume1/docker/photo/photo-video-enhancer/)docker-compose.yml and edit volume mounts to point to your photo directories.env from env.example and set the required dashboard credentials (WEB_PASSWORD, WEB_SECRET_KEY). Transcoding settings (codec, resolution, bitrate, etc.) are configured via the dashboard at runtime.docker compose up -dFor step-by-step instructions and the full environment variables reference, see the Configuration Guide.
/media for video filesSYNOINDEX_MEDIA_INFO files@eaDir/[video_name]/SYNOPHOTO_FILM_H.mp4 in the same directory as the original videoAfter each execution, the application logs a summary:
2025-01-04T12:01:35+0000 (video-enhancer) INFO | Processing results:
2025-01-04T12:01:35+0000 (video-enhancer) INFO | - Total processed: 514
2025-01-04T12:01:35+0000 (video-enhancer) INFO | - Already transcoded: 239
2025-01-04T12:01:35+0000 (video-enhancer) INFO | - Transcoded: 275
2025-01-04T12:01:35+0000 (video-enhancer) INFO | - Errors: 0
View logs with docker logs synology-photos-video-enhancer or via Container Manager in DSM.
The container ships with a built-in, server-rendered dashboard that runs alongside the scheduler in the same process — no extra container, no JavaScript, no external service.
http://<NAS-ip>:${WEB_PORT:-9200}/. Recommended setup: put it behind DSM's reverse proxy with TLS termination.failed and left untouched, rather than transcoded with guessed settings. Its path and the reason appear in the error list. Videos Synology never generated a transcoded version for are recorded as not_required, which is not a failure.Endpoints:
| Method | Path | Auth | Purpose |
|---|---|---|---|
GET | / | required | HTML dashboard |
GET | /api/stats | required | JSON payload (same data as the HTML view) |
GET | /healthz | none | {"status":"ok"} — used by the Docker healthcheck: |
GET | /login | none | Login form |
POST | /login | none | Submit credentials |
GET | /logout | required | Clear the session and redirect to /login |
Authentication. Single user. Username is WEB_USER (defaults to admin); password is WEB_PASSWORD and is required — the app refuses to start if it is unset or empty. The session cookie is HMAC-signed with WEB_SECRET_KEY (also required). Generate the secret with:
python -c "import secrets; print(secrets.token_urlsafe(32))"
For the full list of dashboard env vars (port, cookie flags, etc.) see the Configuration Guide.
Coming from an older version? The Upgrading Guide covers what needs your attention, each entry starting from something you can observe:
44100x2 or 2x1280 in the dashboard — databases written by 4.2.2 or earlier, and how to repair them.make dev # Development mode (hot reload)
make debug # Debug mode (with breakpoints)
make test # Run all tests
For detailed development instructions, see the Development Guide.
src/
├── application/ # Application logic (use cases)
├── controllers/ # Controllers (entry-point orchestration)
├── domain/ # Domain models and business logic
│ ├── constants/ # Enums and constants
│ ├── models/ # Domain models
│ └── ports/ # Ports (interfaces)
└── infrastructure/ # Infrastructure adapters
├── config/ # Configuration management
├── db/ # Database adapters
├── filesystem/ # Filesystem operations
├── hardware/ # Hardware detection
├── transcoder/ # FFmpeg transcoding
└── logger.py # Logging system
For architecture details, see the Architecture Documentation. For tests, see the Testing Guide.
| Document | Description |
|---|---|
| Configuration Guide | Directory setup, docker-compose, environment variables |
| Upgrading Guide | What needs attention when moving from an older version |
| Supported Formats | Video/audio codecs, hardware acceleration, resolutions |
| SQLite Schema | Database schema documentation |
| Synology Metadata | SYNOINDEX_MEDIA_INFO on-disk format and how it is read |
| Docker Build | Multi-architecture Docker build guide |
| Architecture | Hexagonal architecture and data flow |
| Development Guide | Local development, debugging, Docker dev setup |
| Testing Guide | Test structure, fixtures, coverage |
Use this table to pick the right output settings in the dashboard.
| Codec | Efficiency | CPU cost | Web | Android | iOS | TV | Notes |
|---|---|---|---|---|---|---|---|
| MPEG-4 | ↓ | ×1 | ✗ | ✗ | ✗ | ✓ | Legacy (DivX/Xvid) |
| H.264 / AVC ⭐ | = | ×0.2 * | ✓ | ✓ | ✓ | ✓ | Recommended — maximum compatibility |
| H.265 / HEVC | ↑ | ×0.4 * | ✗ | ✓ | ✓ | ✓ | Chrome/Firefox don't support it; check NAS CPU for HW encoding |
| AV1 | ↑↑ | ×22 | ✓ | ✗ | ✗ | ✓ | Requires NAS CPU with HW AV1 encoding support |
* CPU cost with hardware acceleration (QSV/VAAPI). Without HW: H.264 ×5, H.265 ×22.
| Codec | Efficiency | Quality † | Web | Android | iOS | TV | Notes |
|---|---|---|---|---|---|---|---|
| AC-3 / Dolby Digital | ↓ | 82 | ✗ | ✗ | ✗ | ✓ | Home theater only. Needs ≥192 kbps |
| MP3 | = | 75 | ✓ | ✓ | ✓ | ✓ | Legacy; lower quality than AAC at same bitrate |
| E-AC-3 / Dolby Digital Plus | = | 91 | ✗ | ✗ | ✗ | ✓ | Home theater only. Possible royalty restrictions |
| AAC LC ⭐ | ↑ | 88 | ✓ | ✓ | ✓ | ✓ | Recommended — maximum compatibility |
| AAC HE | ↑↑ | 82 | ✓ | ✓ | ✓ | ✓ | Ideal for low bitrates (≥48 kbps) |
| AAC HE v2 | ↑↑↑ | 70 | ✓ | ~ | ~ | ✓ | Stereo only; best at ≤48 kbps |
† MUSHRA perceptual quality score at 128 kbps (0–100). ~ = partial support depending on device.
Uses Hexagonal Architecture (Ports and Adapters) pattern to ensure:
This project would not be possible without the following open-source projects:
Licensed under the MIT License. See LICENSE for details.
Note on Dependencies:
Content type
Image
Digest
sha256:7960416ff…
Size
178.2 MB
Last updated
about 2 months ago
docker pull cibrandocampo/synology-photos-video-enhancer