Files
beets_music_video/README.md
David Freitag ea7d420975 Add beets_music_videos plugin for managing music videos
- Implemented a new beets plugin to import and manage music videos, supporting various video formats and providing metadata from IMVDB and MusicBrainz for autotagging.
- Added installation instructions and configuration options in README.md.
- Created IMVDBApi client for interacting with the IMVDB API.
- Defined typing for various API responses and utility functions for mapping MusicBrainz data to beets TrackInfo.
- Included desktop entry and JSON info files for a video titled "[SAST] The Evolution of Search-based Software Testing".
- Added utility functions for handling artist credits and related metadata.
- Introduced a grabbed.txt file for tracking video sources.
2026-03-18 18:51:27 -04:00

138 lines
6.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# beets_music_videos
A [beets](https://beets.io/) plugin that lets you import and manage **music videos** (and other non-audio media) in your library. Beets normally only handles audio formats supported by its `mediafile` layer; this plugin treats selected video extensions as importable items, creates library entries for them, and provides metadata from IMVDB and MusicBrainz for autotagging.
---
## Features
- **Import video files** — Treats configured video extensions (e.g. `.mp4`, `.mkv`, `.webm`) as importable media. Files are added as beets `Item`s without going through `MediaFile`, so formats like MKV and WebM that beets doesnt natively support can still be imported.
- **Autotagging** — Supplies track-level candidates from:
- **IMVDB** (Internet Music Video Database), via API search by artist + title.
- **MusicBrainz** — video recordings search (`video: true`) for artist and title, with rich metadata (artist credits, release date, work/composer/lyricist, ISRC, etc.).
- **Resolution probing** — Uses `ffprobe` to read video width/height and exposes them as flexible attributes (`video_width`, `video_height`, `video_resolution`) for path formats and queries.
- **Safe tagging** — Writes embedded metadata only for formats that `mediafile` supports (MP4/M4V). For other formats (WebM, MKV, AVI), tags are not written to avoid corruption.
- **Import behavior** — When a music video is already inside the library directory, the importer skips deleting the “original” after copy/move so you dont lose the file.
---
## Installation
1. **Requirements**
- Python ≥ 3.12
- beets ≥ 2.6.0, < 3.0.0
- [FFmpeg](https://ffmpeg.org/) (for `ffprobe`) — optional; used only for resolution probing. Without it, resolution fields are left unset.
2. **Install the plugin** (from this repo):
```bash
cd beets_music_videos
pip install -e .
```
Or add the project as a path dependency in your environment so beets can load `beetsplug.beets_music_videos`.
3. **Enable it** in `config.yaml`:
```yaml
plugins: beets_music_videos
```
---
## Configuration
Configure the plugin under the `beets_music_videos:` key in your beets config.
| Option | Type | Default | Description |
|-------------------|----------|----------------------------------------------|-------------|
| `extensions` | list | `[".mp4", ".m4v", ".mkv", ".avi", ".webm"]` | File extensions to treat as importable video. Values are normalized to lowercase with a leading dot (e.g. `mp4` → `.mp4`). |
| `imvdb_api_key` | string | `""` | IMVDB API key for video search. If empty, IMVDB search is skipped; MusicBrainz video search still runs. Get a key at [IMVDB](https://imvdb.com/). |
### Example
```yaml
plugins: beets_music_videos
beets_music_videos:
extensions: [".mp4", ".m4v", ".mkv", ".webm"]
imvdb_api_key: YOUR_IMVDB_API_KEY
```
---
## How it works
### Import flow
1. **Discovery** — Beets import task factory reads each path. The plugin patches `ImportTaskFactory.read_item` so that when the file extension is in `extensions`, it builds an `Item` directly instead of using `Item.from_path()` / `MediaFile`. That allows unsupported video formats to become library items.
2. **Item creation** — For those paths, the plugin:
- Sets `path`, `mtime`, and a default `title` from the filename stem.
- Runs `ffprobe` to get video width/height and sets `video_width`, `video_height`, and `video_resolution`.
- Sets `media_type` to `"music_video"` so you can query e.g. `media_type:music_video`.
- For **MP4/M4V** only, reads embedded tags (title, artist, album, albumartist, length) via `MediaFile` so autotag has better initial metadata.
3. **Autotag** — For each such item, beets calls the plugins `item_candidates(item, artist, title)`. The plugin:
- Queries **IMVDB** (if `imvdb_api_key` is set) with artist + title.
- Queries **MusicBrainz** for video recordings with artist and title.
- Returns combined `TrackInfo` candidates; beets then picks the best match and applies metadata.
4. **File operations** — The plugin patches `ImportTask.manipulate_files` so that when writing tags it only calls `item.try_write()` for music videos whose extension is supported by `MediaFile` (MP4/M4V). Other video formats are not written to avoid corruption. It also adjusts behavior when the “original” is already inside the library directory so the file isnt deleted after move.
### Metadata sources
- **IMVDB** — Used only for track-level search. Returns candidates with `data_source="IMVDB"` (song title, artists, year, etc.). Requires `imvdb_api_key`.
- **MusicBrainz** — Video recording search with `video: true`. Returns candidates with `data_source="MusicBrainz"` and full track metadata (artist credits, date, work, composer, lyricist, remixer, arranger, ISRC, length, etc.). No API key required.
---
## Item attributes (music videos)
Library items created for video files have standard beets fields plus these flexible attributes:
| Attribute | Type | Description |
|--------------------|--------|-------------|
| `media_type` | string | Set to `"music_video"` for all items created by this plugin. Use in queries: `beet list media_type:music_video`. |
| `video_width` | int | Video width in pixels (from `ffprobe`). |
| `video_height` | int | Video height in pixels (from `ffprobe`). |
| `video_resolution` | string | e.g. `"1920x1080"` (from `ffprobe`). |
For **MP4/M4V**, initial `title`, `artist`, `album`, `albumartist`, and `length` are filled from embedded tags when available; otherwise title defaults to the filename stem.
---
## Path formats
You can use the extra attributes in `paths:` and `path_format:`:
```yaml
paths:
default: '$albumartist/$album [$year]/$track. $title'
singleton: '$artist - $title - $year'
```
Flexible attributes are available as `$video_width`, `$video_height`, `$video_resolution`, and `$media_type` in path formats.
---
## Query examples
- List all music videos:
`beet list media_type:music_video`
- 1080p only:
`beet list video_height:1080`
- By resolution string:
`beet list video_resolution:1920x1080`
---
## Dependencies
- **beets** (≥ 2.6.0, < 3.0.0)
- **lapidary** (≥ 0.12.3) — used for the IMVDB API client
- **typing-extensions** (≥ 4.15.0)
- **FFmpeg** — optional; provides `ffprobe` for resolution. If missing, resolution fields are not set.
The plugin uses beets built-in MusicBrainz integration (`MusicBrainzAPIMixin`) for MusicBrainz video search; no extra MusicBrainz package is required beyond what beets uses.
---
## License
Apache 2.0.