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

6.6 KiB
Raw Permalink Blame History

beets_music_videos

A beets 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 Items 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 (for ffprobe) — optional; used only for resolution probing. Without it, resolution fields are left unset.
  2. Install the plugin (from this repo):

    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:

    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.

Example

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::

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.