- 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.
138 lines
6.6 KiB
Markdown
138 lines
6.6 KiB
Markdown
# 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 doesn’t 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 don’t 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 plugin’s `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 isn’t 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.
|