6. Beets
Having local audio files well organised in a directory tree has the advantage that it can be mounted via Remote file access with nfs. to a plethora of applications with a consistent navigation.
LMS
Kodi
Ampache
Subsonic
UPnP / DLNA
Mopidy / MPD
Yamaha Musicast
The best way to achieve this is the commandline tool beets
6.1. My Most Common Commands
Here are the most useful commands i figured out over the years.
6.1.1. Move Album to Grouping Dir
I started out to organize my music by genre. The result was some overcrowded genres and a lot of obscure genre directories with just a few songs in there. I tried setting up a genre tree with subgenres etc, yet this proved to be to complicated as genres are more like a matrix than a tree. ( a specific subgenre often has more than one parent) Finally i came up with the idea to organize the top level by the field album_grouping.
In the config.yaml i have:
paths:
default: %if{%ifdef{album_grouping},_${album_grouping}%if{%ifdef{subgroup},/-${subgroup}},$genre}/%asciify{%if{$albumartist_sort,$albumartist_sort,$albumartist}}/%if{$original_year,${original_year}-,%if{$year,${year}-}}%asciify{$album}/%if{$disc,$disc-}%if{$track,${track}_-_}%asciify{${artist}_-_${album}_-_$title}
Now albums are sorted to groupings like so
beet import -A /data/music/music_data/beets/1/101_Strings --set album_grouping=World
To reorganize your existing collection
beet modify -a albumartist::^CAN$ album_grouping=Rock subgroup=Krautrock
Two things are noteworthy here. When you query in the album context (-a) it is albumartist not artist to query for. And second, if i would use the query albumartist:CAN i would also reorganize Laura Cantrell, Dead Can Dance and Boards of Canada.
6.1.2. No Album
Some albums i have only 1 or 2 songs of or dont know the name of the album. For this songs i use a no-album configuration
album:no-album: %if{%ifdef{album_grouping},_${album_grouping}%if{%ifdef{subgroup},/-${subgroup}},$genre}/%asciify{$albumartist}/%asciify{${artist}_-_$title}
6.1.3. Move a Singleton to Grouping Dir
It is important to note that beet by default works o whole albums. Yet when you want to work on a single song (-s) the name of the field is grouping.
beet import -As /data/music/music_data/beets/1/17_trouser_press_\(saturday_cl/11_-_17_trouser_press_.mp3 --set grouping=Rock
Some artists i have just 1 or 2 songs of. Having this songs organised under the artists name would result i a very cluttered directory tree. I organise these songs in a directory 00_Singletons under their grouping (and optionally subgroup) directory.
singleton: %if{${grouping},_${grouping}/%if{%ifdef{subgroup},-${subgroup}/}00_Singletons,00_Singletons/-${genre}}/%asciify{${artist}_-_$title}
Note, there is a difference between the genre of a song and the genre of an album. Easy to get confused when writing path configurations.
6.1.4. Radioplays
I have special path configuration for radio plays that i record with tvheadend.
genre:"Radio Play": 00_HOERSPIELE/%if{${grouping},${grouping},%if{${album},${album},Hoerspiel}}/%asciify{${title}%if{${artist},_-_${artist}}}%if{$original_year,-${original_year},%if{$year,-${year}}}%if{$track,-Teil_$track}%if{$tracktotal,_von_$tracktotal}
When changing the path definition in config.yaml you can reimport the files
beet import -As $PWD/Hungern_un_Freten-2023.mp3
6.1.5. Alternatives
With the alternatives Plugin you can create additional Directory Trees linked to your Colection. Say you want the highres files of your collection accessible through an alternative navigation tree.
alternatives:
HighRes:
directory: /data/music/music_data/alternatives/highres
query: bitdepth:16..
paths:
default: '%if{%ifdef{album_grouping},_${album_grouping},NO_GROUP}/%asciify{%if{$albumartist_sort,$albumartist_sort,$albumartist}}/%if{$original_year,${original_year}_,%if{$year,${year}-}}%asciify{$album}/%if{$disc,$disc-}%if{$track,${track}_-_}%asciify{${artist}_-_${album}_-_$title}'
comp: '%if{%ifdef{album_grouping},_${album_grouping},NO_GROUP}/00_Compilations/%asciify{$album}/%if{$disc,${disc}-}%if{$track,${track}_-_}%asciify{${artist}_-_$title}'
formats: link
6.1.7. Modify album fields
modify by default works on single files. To work on album use -a
beet modify -a genre:balkan genre='Balkan Pop'
Note: In the context of album the artist field is albumartist. The advantage of using modify vs import -A and –set is the Overview of changes which can be cancelled. On the other hand a path does not work well in the album context.
6.1.8. Edit
Another great way change some tags is the edit command
beet edit $PWD/Seker_is_seker-Teil_04_von_04.mp3
Even better you can edit multiple files in one go
beet edit $PWD
Also you can edit all songs of an Album. You can specify field you want to edit with -f.
beet edit -a -f albumartist_sort -f genre -f album_grouping albumartist:A.R.E
6.1.9. Delete File
By default beet removes files only from its library, leaving the file on disk. to also remove from disk, use the -d option. With -f you will not be asked for confirmation.
beet remove -d /data/music/music_data/beets/2/20_humanoid_boogie_\(radio_1_c/11_-_20_humanoid_boogie_.mp3
Sometimes i find it easier to delete files on disk first and update beets library later.
ls *.[1-9].mp3 #better save than sorry
rm *.[1-9].mp3
beet update $PWD
6.1.10. Find exact expression
By default beet queries look for anything that contains your searchstring. ( like %search% in sql) Sometimes you want to narrow it down.
beet ls -a genre::^ambient$
this excludes genres like ‘Dark Ambient’ which would otherwise be in the resultset
6.1.10.1. Merge 2 or more albums
Different values for original_year, year, genre etc can cause beet to distribute files in separate albums. These albums can have the same name yet have diferent ids.
Remove Files from existing albums
beet remove album_id:5797
Move Files to same Dir. Delete Duplicates
Write consistent Tags
mid3v2 -A "Peel Session" -a "cLOUDDEAD" -y 2002 /path/*
Import Album
beet import -A /data/music/music_data/beets/-Indie/cLOUDDEAD/2002-Peel_Session --set album_grouping=Indie --set genre='Hip Hop' --set original_year=2002
6.1.10.2. Using beets and mopidy
6.1.11. Play Songs from the commandline
You can add the result of a beets query to mopidy tracklist like so:
beet ls -f 'file://$path' artist:Brian Eno album:Before And After Science | mpc add
6.1.12. Play Contents of a Dir
mpc clear
find $1 -type f -exec mpc add file://{} \;
mpc play
6.2. Cleanup Filesystem with find
Delete empty Dirs .. code:
find . -type d -empty -delete
Delete hidden files
find . -type f -name ".*" -delete
Delete @eaDir .. code:
find . -type d -name "@eaDir" -exec rm -rf {} \;
list Dirs and No. of files comtained .. code:
find . -type 'f' -printf '%h\n' | sort | uniq -c | sort -g
Script to import as album when Dir has more than 3 files (using parent dir) .. code-block:: bash
#!/bin/bash find “$PWD/$1” -type ‘f’ -printf ‘%hn’ | sort | uniq -c | sort -g | awk -F ” ” ‘$1>3{ print $NF “/..”}’ | xargs -n 1 beet import -A
Need to use absolute path otherwise beets creates duplicate entries.
import as Singleton when Dir contains only 1 file .. code-block:: bash
#!/bin/bash find “$PWD/$1” -type ‘f’ -printf ‘%hn’ | sort | uniq -c | sort -g | awk -F ” ” ‘$1<2{ print $NF }’ | xargs -n 1 beet import -As