Media Hub
Browse, library, favorites, history management
The Media Hub is the central browsing and library interface for all your media. Access it from the sidebar — it combines a file browser, an indexed media library, favorites, and playback history into a single panel.
Home
Browse
Library
Favorites
Recent
History
File Browser
The FileBrowserModel provides a virtual filesystem tree that lists drives at the root level and navigates into directories recursively. Only media files (determined by MediaUtils::isMediaFile()) and directories are shown — non-media files are filtered out.
Features
- Drive enumeration on Windows (
A:\,C:\, etc.) as root items - Directory traversal with
QDirIteratorfor efficient large-directory listing - Column sorting: name, file type, size, date modified
- Drag-and-drop support for adding to playlist or opening in player
- Context menu with Play, Add to Playlist, Favorite, and Show in Explorer
Media Library
The library is backed by a SQLite database managed through LibraryDatabase and MediaLibraryService. It tracks every file that has been played or indexed.
Database Schema
The library consists of four core tables:
| Table | Purpose |
|---|---|
media_items |
Master table: locator, title, duration, position, play count, timestamps, thumbnail path, missing flag |
library_roots |
Registered folder roots for scanning |
library_entries |
Many-to-many join between roots and media items |
playback_visits |
Per-session playback records: opened at, position, watched duration, completed status, end reason |
Scanning
When you add a library root, MediaLibraryService launches a background scan on a worker thread via QtConcurrent::run. It walks all subdirectories using QDirIterator with Subdirectories flag, identifies media files, and inserts them into the database. Scanning is non-blocking — the UI remains responsive throughout.
Incremental Only new and modified files are processed on subsequent scans.
Missing detection Files that no longer exist on disk are flagged with missing=1 but their metadata is preserved.
Statistics
The library tracks aggregate statistics:
- Unique media: Count of distinct files played at least once
- Total play count: Sum of all playback sessions
- Watched time: Cumulative milliseconds across all visits
- Completions: Number of sessions where playback reached at least 92% of duration
Favorites
Toggle favorites from the Media Hub, context menu, or via the toggleFavorite() method. Favorites are stored in a dedicated favorites table keyed by locator_key (a normalized, case-insensitive path key).
Sorting & Filtering
- Sort by date added (newest first), title, or media type
- Filter by kind: video, audio, playlist, folder, or URL
- Search within favorites by title or filename
History & Recent
Recent shows the last 100 played items ordered by last_played_at_ms descending. Each entry displays the resume progress bar, duration, and completion badge.
History provides a complete chronological log of every playback session:
Grouping
History entries are grouped by time period for easier navigation:
| Group | Range |
|---|---|
| Today | Current calendar day |
| Yesterday | Previous calendar day |
| This Week | Current week (Monday–Sunday) |
| This Month | Current month |
| Older | Everything before the current month |
Sorting & Filtering
- Sort by played date, title, or duration
- Filter by completion status (completed / partial)
- Filter by media type
Actions
- Play — open the file at the position it was last watched
- Remove from history — deletes the visit record
- Clear All — removes all playback history and resets play counts
- Add to Favorites — mark as favorite directly from history
Thumbnail Service
The MediaThumbnailService generates video thumbnails asynchronously using ffmpeg.
How It Works
- A thumbnail is requested with
requestThumbnail(path) - The service checks a SHA-256 keyed cache in
PathUtils::thumbnailCacheDir() - On cache miss, an
ffmpegprocess captures frame at 5 seconds, scaled to 480px wide - Up to
MaxWorkers(4) concurrent processes run; remaining requests queue - On completion, the
thumbnailReady(path, url)signal fires - Failed thumbnails emit
thumbnailFailed(path)— the UI shows a placeholder
The cache can be cleared from Preferences > Advanced > Clear Thumbnail Cache.