KID3(1)

๐Ÿ’ฟ kid3, kid3-qt, kid3-cli โ€” the Kid3 ID3 Tagger

okay bestie so this is The Kid3 Handbook, section one of like twenty-two, and it's literally the manual page for kid3, kid3-qt and kid3-cli. grab a boba, we're tagging files ๐Ÿ’…


โœจ NAME โœจ

kid3, kid3-qt, kid3-cli โ€” Kid3 ID3 Tagger. that's it, that's the name, she's iconic ๐Ÿ‘‘


๐Ÿฆ‹ SYNOPSIS ๐Ÿฆ‹

            kid3
             [
             | --help
             | --author
             | --version
             | --license
             | --desktopfile FILE ]
             [FILE...]

               kid3-qt
                [--portable]
                [Qt-options]
                [FILE...]

                kid3-cli
                 [--portable]
                 [--dbus]
                 [
                 | -h
                 | --help ]
                 [-c COMMAND1]
                 [-c COMMAND2...]
                 [FILE...]

๐ŸŽ€ OPTIONS ๐ŸŽ€

  • --portable โ€” stores your config in a file called kid3.ini right inside the application folder. very "everything in one place" of it ๐Ÿซถ
  • FILE โ€” if FILE is the path to a folder, that folder gets opened. if you hand it one or more file paths, their common folder gets opened and those files get selected. slay.

๐Ÿ’œ kid3

  • --help โ€” shows help about options.
  • --author โ€” shows author information.
  • --version โ€” shows version information.
  • --license โ€” shows license information.
  • --desktopfile FILE โ€” the base file name of the desktop entry for this application. (yes, FILE is a placeholder, don't type the word "file" fr)

๐ŸŒธ kid3-qt

  • Qt-options โ€” see qt5options(7). that's the whole vibe, go read that one.

๐Ÿ’… kid3-cli

  • --dbus โ€” activates the D-Bus interface.
  • -c โ€” executes a command. you can stack multiple -c options and they run in sequence, one after another. for what commands actually exist, see the section about kid3-cli later in this handbook ๐Ÿ‘€
  • -h|--help โ€” shows help about options and commands. both. she's thorough.

๐ŸŒˆ INTRODUCTION ๐ŸŒˆ

so. Kid3 is an application for editing the ID3v1 and ID3v2 tags in MP3 files, and it does it efficiently โ€” no cap. most MP3 players can edit these tags but not in a very comfortable and efficient way, which is honestly so rude of them. on top of that, tags in Ogg/Vorbis, Opus, DSF, FLAC, MPC, APE, MP4/AAC, MP2, Matroska/WebM, Speex, TrueAudio, WavPack, WMA, WAV, AIFF files and tracker modules (MOD, S3M, IT, XM) are supported too. the range?? unmatched ๐Ÿ”ฅ

kid3 does not grab nor encode MP3 files โ€” she's not that kind of app โ€” she's targeted at editing the ID3 tags of all files of an album in an efficient way, i.e. with as few mouse clicks and key strokes as possible. where most other programs can edit either ID3v1 or ID3v2 tags, Kid3 has full control over both versions, can convert tags between the two formats, and has access to all ID3v2 tags. main character energy tbh ๐Ÿ‘‘

tags of multiple files can be set to the same value โ€” like, the artist, album, year and genre of all files of an album typically have the same values, and you can set them together, together-together. ๐Ÿ’– if the information for the tags is contained in the file name, the tags can be automatically set from the file name. and yes, the reverse works too: it's also possible to set the file name according to the tags found in the file, in arbitrary formats. versatility queen.

the editing task is further supported by automatic replacement of characters or substrings, for instance to remove illegal characters from filenames. automatic control of upper and lower case characters makes it easy to use a consistent naming scheme in all tags. chef's kiss ๐Ÿงš

the tag information for full albums can be taken from gnudb.org[1], MusicBrainz[2], Discogs[3], Amazon[4] or other sources of track lists. the import format is freely configurable by regular expressions โ€” regex girlies rise ๐Ÿ™ˆ

please report any problems or feature requests to the author. she wants to hear it, fr fr.


๐Ÿ“ USING KID3 ๐Ÿ“

๐Ÿ’– Kid3 features ๐Ÿ’–

  • Edit ID3v1.1 tags
  • Edit all ID3v2.3 and ID3v2.4 frames
  • Edit tags of multiple files
  • Convert between ID3v1 and ID3v2 tags
  • Edit MP3, Ogg/Vorbis, Opus, DSF, FLAC, MPC, APE, MP4/AAC, MP2, Matroska/WebM, Speex, TrueAudio, WavPack, WMA, WAV and AIFF tags
  • Generate tags from filename
  • Generate tags from the contents of tag fields
  • Generate filename from tags
  • Generate and change folder names from tags
  • Generate playlist file
  • Automatic case conversion and string translation
  • Import from gnudb.org[1], MusicBrainz[2], Discogs[3], Amazon[4] and other data sources
  • Export as CSV, HTML, playlist, Kover XML and other formats. Exported CSV files can be imported again.

like, the range is giving "she does it all" ๐Ÿ’…โœจ

๐ŸŒธ Example Usage ๐ŸŒธ

this section walks you through a typical session with Kid3, so let's go. imagine we have a folder containing MP3 files with the tracks from the album "Let's Tag" from the band "One Hit Wonder". the folder is named in the "artist - album" format, so in our case One Hit Wonder - Let's Tag. the folder contains the tracks in the "track title.mp3" format, which, honestly, I think is useful because:

  • the filenames are short โ€” important when using mobile MP3 players with small displays
  • they're in the correct order when sorted alphabetically โ€” important when using hardware MP3 players which play the tracks in alphabetical order or in the order in which they are burnt on CD, and that order is alphabetical when using mkisofs

besides this, the artist and album information is already in the folder name and does not have to be repeated in the filename. smart, right? anyway, back to our example โ€” the folder listing looks like this:

01 Intro.mp3
02 We Only Got This One.mp3
03 Outro.mp3

these files have no tags yet and we want to generate them using Kid3. we use the File โ†’ Open menu item (or toolbar button) and select one of the files in this folder. all files will be displayed in the file listbox. lazy as we are, we want to use the information in the folder and file names to generate tags. therefore we select all files, then click the To: Tag 1 button in the File section. this will set the title, artist, album and track values in all files. to set the year and genre values of all files, we keep all files selected and type in "2002" for the Date and select "Pop" from the Genre combobox. to set only these two values, their check boxes are automatically checked and all other check boxes are left unchecked. ๐Ÿ™Œ

now we change the selection by only selecting the first file, and we see that all tags contain the correct values. the tags of the other files can be verified too by selecting them one by one. when we are satisfied with the tags, we use the File โ†’ Save menu item (or toolbar button). selecting the File โ†’ Create Playlist menu item (or toolbar button) will generate a file One Hit Wonder - Let's Tag.m3u in the folder. and that's the whole flow, no thoughts head empty, tags done ๐ŸŽ€


๐Ÿ‘‘ COMMAND REFERENCE ๐Ÿ‘‘

๐Ÿฆ‹ The GUI Elements ๐Ÿฆ‹

the Kid3 GUI is separated into six sections (yes, six): at the left are the file and folder listboxes, and the right side contains the File, Tag 1, Tag 2 and Tag 3 sections. balanced. symmetrical. gorgeous.

to navigate between the different sections using the keyboard, several keyboard shortcuts are supported. in the tag sections, the shortcuts are active while not editing text or when being in the first column. little detail, big difference.

  • Alt+Left: go to previous section (Command+[ on macOSยฎ)
  • Alt+Right: go to next section (Command+] on macOSยฎ)
  • Ctrl+Shift+V: From other tag
  • Ctrl+C: Copy
  • Ctrl+V: Paste
  • Shift+Delete: Remove
  • F2: Edit
  • Insert: Add
  • Delete: Delete

๐Ÿ’œ File List ๐Ÿ’œ

the file list contains the names of all the files in the opened folder which match the selected file name filter. and what's the typical filter, you ask? bestie, it's this whole thing:

*.3g2 *.aac *.afc *.aif *.aifc *.aiff *.ape *.asf *.dff *.dsdiff *.dff *.flac
*.it *.m4a *.m4b *.m4p *.m4r *.m4v *.mka *.mkv *.mod *.module *.mp2 *.mp3
*.mp4 *.mp4v *.mpc *.nst *.oga *.ogg *.opus *.s3n *.shn *.spx *.tta *.wav
*.webm *.wma *.wmv *.wow *.wv *.xm

a single or multiple files can be selected. to select no file, click into the empty area after the listbox entries. the selection determines the files which are affected by the operations which are available by using the buttons described below. selection = power, periodt.

besides Name, also other columns Size, Type, Date Modified with file details can be displayed. columns can be hidden by unchecking their name in the context menu of the list header. the order of the columns can be changed by drag and drop, and the sort order can be toggled by clicking on the column header. ๐Ÿ’…

the values of the standard tags can also be displayed and edited in columns of the file list. yes, in the columns. live your best spreadsheet life.

at the left of the names an icon can be displayed: a disc to show that the file has been modified, or information about which tags are present โ€” V1, V2, V1V2 or NO TAG. no icon is displayed if the file has not been read in yet. iykyk ๐ŸŒธ

folders are displayed with a folder icon. if a folder is opened, its files are displayed in a hierarchical tree. by selecting files from subfolders, operations can be executed on files in different folders, which is useful if the music collection is organized with a folder for each artist containing folders for albums of this artist. organized girlies, this one's for you ๐Ÿซถ

clicking the right mouse button inside the file list opens a context menu with the following commands:

  • Expand all: expands all folder trees (only the current tree if the Shift key is pressed)
  • Collapse all: collapses all folder trees
  • Rename: changes the name of a file
  • Move to Trash: moves a file to the trash
  • Play: plays a file, see Play. if the selected file is a playlist, the files of the playlist will be played.
  • Edit: edit a playlist, see Edit Playlist.
  • the subsequent entries are user commands, which can be defined in the User Actions tab of Configure Kid3. the playback on double click can also be activated there.
when Select file on play is activated, the currently played track is automatically selected in the file list. cute little follow-along feature ๐Ÿ’–

๐ŸŽ€ Edit Playlist ๐ŸŽ€

a playlist can be created empty or containing the tracks of a folder โ€” see Create Playlist. the playlist file created in such a way can be edited by double click or using Edit from the file list context menu. a dialog with the entries of the playlist is shown. it is possible to open multiple playlists simultaneously. multitasking icon ๐Ÿ’…

new entries can be added by drag and drop from the file list, a file manager or another playlist. if an entry is dragged from another playlist, it will be moved or copied depending on the system. to invoke the other operation, respectively, the Shift, Ctrl or Alt (to copy instead of move on macOSยฎ) key has to be pressed. reordering entries within the playlist is also possible via drag and drop. alternatively, entries can be moved using the keyboard shortcuts Ctrl+Shift+Up and Ctrl+Shift+Down (on macOSยฎ Command has to be pressed instead of Ctrl). an entry can be removed using the Delete key. drag, drop, delete, repeat ๐Ÿ”

please note the following: to drag entries from the file list, they have to be held at the left side (near the icons). the same gesture at the right side will perform a multi selection โ€” such an action is hereby still easily possible. so left = drag, right = multi-select, and honestly that's such a mood ๐Ÿ™ˆ

(and that's only part one bestie โ€” more manual incoming ๐Ÿ’–)

Like, if your playlist got modified (you icon), you can lock those changes in with Save or yeet them with Cancel. And if you try to close the window while there's still unsaved stuff hanging around? ๐Ÿ’€ It hits you with a confirmation prompt. No sneaky accidental loss, bestie.

Tracks you select inside a playlist get automatically selected in the file list too, which is honestly so clutch โ€” it means you can go straight in and edit their tags. ๐ŸŽ€

To run actions on a playlist, its file has to be selected in the file list. Edit from the context menu pops open the dialog we're literally describing in this section, and Play fires up the media player with that playlist's tracks. User actions can act on playlists too โ€” for example Export Playlist Folder, which copies the files from a playlist into a folder. Obsessed. โœจ

๐Ÿ—‚๏ธ Folder List ๐Ÿ—‚๏ธ

The folder list shows you the names of the folders inside the opened folder, plus the current folder (.) and the parent folder (..). It's the fast lane to switching folders without touching the Open command or doing the whole drag-and-drop thing. iykyk. ๐Ÿฆ‹

Column visibility, order and sorting are all configurable exactly like we described in the file list section. Periodt.

๐Ÿ“„ File ๐Ÿ“„

Here's where it spills all the tea about the encoding โ€” MP3, Ogg, Opus, DSF, DFF, FLAC, MPC, APE, Matroska, Webm, MP2, MP4, AAC, Speex, TrueAudio, WavPack, ASF, WAV, AIFF, IT, Mod, S3M, XM, SHN โ€” plus bit rate, sample rate, channels and how long the file is. ๐Ÿ’…

The Name line edit holds the name of the file (only when a single file is selected, bestie). Change that name and the file gets renamed when you use the Save command. ๐Ÿซถ

The Format combo box and line edit hold the format used when generating the filename from the first or the second tag. These special codes are what you use to shove tag values into the filename:

  • %s %{title} โ€” Title (Song)
  • %a %{artist} โ€” Artist
  • %l %{album} โ€” Album
  • %c %{comment} โ€” Comment
  • %y %{year} โ€” Year
  • %t %{track} โ€” Track (e.g. 01)
  • %t %{track.n} โ€” Track with field width n (e.g. 001 for %{track.3})
  • %T %{tracknumber} โ€” Track (without leading zeros, e.g. 1)
  • %g %{genre} โ€” Genre
  • %{ignore} โ€” Ignored when generating tags from the file name

The format codes are not restricted to the examples above, jsyk. Any frame name works โ€” unified frame names like %{albumartist}, %{discnumber.1}, %{bpm}, or format-specific names like %{popm}. ๐ŸŒˆ

You can also prepend and append strings to whatever a format code gets replaced with by adding them in double quotes inside the curly braces of a format code. Those strings only land in the resulting string if the format code yields a nonempty value. So like, say you want the filename to contain both the title and the subtitle โ€” you'd reach for %{title} [%{subtitle}] in the format string. But then you'd end up with a string ending in [] when a file has no subtitle frame, which is giving broken. ๐Ÿ˜ญ To dodge the brackets when there's no subtitle, use %{title}%{" ["subtitle"]"} instead. That omits the brackets, the leading space and the subtitle if no subtitle exists. Chef's kiss.

The list of available formats can be edited in the dialog that shows up when you click the Filename from tag button in the File tab of the settings. ๐ŸŽ€

A second Format combo box (with the arrow down) is for generating the tags from the filename. If the filename's format doesn't match that pattern, it tries a few other commonly used formats. Ngl, it's lowkey a little psychic.

Some commonly used filename formats already live in the combo box, but you can absolutely type your own special format straight into the line edit. Main character energy. ๐Ÿ‘‘

The list of available formats can be edited in the dialog that appears when you click the Tag from filename button in the File tab of the settings.

Internally, a regular expression gets built from the format codes. If you need advanced regular expressions, the format for generating tags from filenames can be given as a complete regular expression with captures preceded by the format codes. Like, to extract track numbers without removing the leading zeros, you could use a format like /%{track}(\d+) %{title}(.*). ๐Ÿ”ฅ

From: Tag 1, Tag 2: sets the filename using the selected format and the first tag or the second tag, respectively.

To: Tag 1, Tag 2: the tags are set from the filename. First, the format specified in Format is used. If the existing filename doesn't match that format, these formats get tried:

  • Artist - Album/Track Song
  • Album/Track - Artist - Song
  • /Artist - Album - Track - Song
  • Album/Artist - Track - Song
  • Album/Artist - Song
  • Artist/Album/Track Song

If a single file is selected, the GUI controls get filled with the values extracted from the filename. If multiple files are selected, the tags of the files are directly set according to the filenames. Slay. ๐Ÿ’ซ

๐Ÿท๏ธ Tag 1 ๐Ÿท๏ธ

The line edit widgets for Title, Artist, Album, Comment, Date, Track Number and Genre edit the corresponding value in the first tag of the selected files. That value changes when the file selection is altered, or before operations like Save and Quit, and when the matching check box to the left of the field name is checked. Super handy when you only want to change some values and leave everything else untouched. ๐Ÿซถ

With a single file selected, all check boxes are checked and the line edit widgets contain the values found in that file's tags. If a tag isn't found in the file, you get the corresponding empty value displayed โ€” an empty string for the Title, Artist, Album and Comment line edits, 0 for the numerical Date and Track Number edits, and an empty selected value for the Genre combo box. You can change the values, and if the matching check box is checked they'll be set for the selected file once the selection changes. The file then gets marked as modified with a disk symbol in the file listbox, but it stays unchanged until you use the Save command. ๐Ÿ’พ

With multiple files selected, only the values that are identical across all selected files are displayed. Everything else shows the empty values described above. All check boxes are unchecked, so no unwanted changes sneak in ๐Ÿ™ˆ. If a value needs to be set for all selected files, edit it and set the check box. The values get set for all selected files when the selection changes, and you can save them with the Save command.

The check boxes also control how most commands affecting tags behave โ€” copy, paste, transfer between tag 1 and tag 2. And to make life easier with multiple files where all check boxes are unchecked, these commands behave exactly the same when all check boxes are checked and when all check boxes are unchecked. ๐Ÿ’…

From Tag 2: the tag 1 fields are set from the corresponding values in tag 2. Single file selected โ†’ the GUI controls get filled with the values from tag 2. Multiple files selected โ†’ the tags of the files are directly set.

Copy: the copy buffer gets filled with the Tag 1 values. Only values with a checked check box get used in subsequent Paste commands.

Paste: pastes the values from the copy buffer into the GUI controls.

Remove: sets all GUI controls to their empty values, which results in removing all values. The saved file will then contain no tag 1. ๐Ÿ’€

๐Ÿท๏ธ๐Ÿท๏ธ Tag 2 ๐Ÿท๏ธ๐Ÿท๏ธ

The GUI controls work the same way as described in the Tag 1 section, but the size of the strings is not limited. No cap. โœจ

For the tag 2 Genre you can also use your own names besides the genres listed in the combo box โ€” just type the name into the line edit. ๐ŸŽ€

Tag 2 can't only hold the same values as tag 1, jsyk: the format is built flexibly from several frames, which are themselves composed of several fields. The tag 2 table shows all the frames available in the selected file.

Edit: opens a window that lets you edit all fields of the selected frame. If multiple files are selected, the edited fields are applied to all selected files that contain such a frame.

Add: a requester to select the frame type appears, and a frame of the selected type can be edited and added to the file. This also works for adding a frame to multiple selected files at once. ๐Ÿ’ซ

Delete: deletes the selected frame in the selected files.

Drag album artwork here shows up if the file doesn't contain embedded cover art. You can add a picture by dragging and dropping from a browser or file manager โ€” it'll show up right there. Picture frames can be edited or added by double clicking on this control. ๐Ÿ–ผ๏ธ

๐Ÿท๏ธ๐Ÿท๏ธ๐Ÿท๏ธ Tag 3 ๐Ÿท๏ธ๐Ÿท๏ธ๐Ÿท๏ธ

Some files can have more than two tags, and then a third tag section is visible. These file types can have such a Tag 3 section:

  • MP3 files can have an ID3v1.1 tag, an ID3v2 (2.3.0 or 2.4.0) tag, and in the third section an APE tag. Such APE tags are used for replay gain information. In the Tag 3 section that info is visible, and the APE tag can be removed with the Remove button.
  • The RIFF INFO chunk of WAV files is available in the Tag 3 section, because the Tag 1 section is dedicated to ID3v1.1 tags and handles their restrictions. Tag 2 is still used for ID3v2.4.0 tags, which are also supported for WAV files, but RIFF INFO chunks seem to be supported better. ๐Ÿฆ‹
  • FLAC files normally use a Vorbis comment for their meta data. However, there are FLAC files that have ID3v1 and ID3v2 tags, which you'll find in the Tag 1 and Tag 3 sections. ID3 tags in FLAC files are only supported by TagLib, so the OggFlacMetadata plugin has to be disabled in the Plugins tab of the settings.

The GUI controls work the same way as in the Tag 2 section. ๐Ÿ’œ

๐ŸŽค Synchronized Lyrics and Event Timing Codes ๐ŸŽค

For information that's synced with the actual audio data, there's a whole dedicated editor โ€” because of course there is ๐Ÿ’…. These frames are supported for ID3v2.3.0 and ID3v2.4.0 tags only. To add one, you pick the specific frame name from the list that pops up when you hit Add โ€” Synchronized Lyrics or Event Timing Codes, respectively. It's literally the same editor for both types, except for event timing codes you only get a predefined set of events to choose from, whereas for synchronized lyrics you have to type the text in. Down below, we're explaining the synchronized lyrics one, bestie.

So: a file with an ID3v2 tag is selected, you get into the lyrics editor via Add and picking Synchronized Lyrics. If a Synchronized Lyrics frame already exists, you select it and click Edit. The player opens up automatically with the current file so you can play and pause the track to sync the lyrics up. ๐ŸŽง

The settings at the top of the SYLT editor normally don't need to be touched, lowkey leave them alone. But if the lyrics contain characters that aren't in the Latin 1 character set, then yeah โ€” change the text encoding to UTF16 (or UTF8 for ID3v2.4.0), that's advisable. For English lyrics and maximum compatibility, ISO-8859-1 is the move. โœจ

The Lyrics section has five buttons up top. Add adds a new time event in the table โ€” the time comes from the player position, so adding an entry while the track is playing will add a line for wherever you're at right now. The events in the table have to be in chronological order, so the row gets inserted in the right place accordingly. Entries with an invalid time are treated specially: if the currently selected row has an invalid time, its time stamp gets replaced by the current time instead of a new row being added. If the current time isn't invalid, the first row with an invalid time gets used if there is one. This behavior is meant to make adding time stamps easier when the lyrics text is already sitting in the table but the time stamps are missing (which is exactly what happens when you import unsynchronized lyrics). Heads up though: the invalid time is represented as 00:00.00, i.e. the same as the time at the absolute beginning of the track, which is not invalid. To make a time invalid, press Delete, or use Clear from the context menu. New rows inserted via Insert row from the context menu, or created when importing unsynchronized lyrics with From Clipboard or Import, also come with invalid time stamps. Rows in the table can be deleted by clicking the Delete button or using Delete rows from the context menu.

Synchronized lyrics can be imported from a file using Import. The expected format is simple or enhanced LRC. If the selected file doesn't contain a square bracket in the first line, it's supposed to be a simple text file with unsynchronized lyrics โ€” the lines from that file then get imported with invalid time stamps. You can add the time info with the Add button or by manual entry. You can also import lyrics via copy-paste using From Clipboard. And synchronized lyrics can be written out to LRC files using Export. โš ๏ธ Note that only entries with valid time stamps get exported, and the entries get sorted by time. Entries with invalid time won't be stored in the SYLT frame either, so make sure you include all the timing info before you leave the dialog โ€” no cap.

The ID3 specification[5] suggests a time stamp for each syllable. But most players only support the granularity of a line or sentence, so to support both use cases, Kid3 follows the same conventions as SYLT Editor[6]. Text entered into the table is assumed to start a new line unless it starts with a space or a hyphen. Exceptions to this rule are possible by starting a line with an underscore ('_') to force continuation, or a hash mark ('#') to force a new line. These escape characters are not stored inside the SYLT frame. Inside the SYLT frame, new lines start with a line feed character (hex 0A) whereas continuations don't. When reading SYLT frames, Kid3 checks whether the first entry starts with a line feed. If it doesn't, it's assumed that all entries are new lines and that no syllable continuations are used.

While the track is playing, the row associated with the current playing position is highlighted, so you can verify the correctness of the synchronization info. ๐Ÿ‘€ If an offset has to be added to one or more time stamps, you can do that with the Add offset context menu. Negative values work too โ€” use them to reduce the time. And with Seek to position in the context menu, you can set the playing position to the time of the selected row. ๐Ÿฆ‹

  • Get the unsynchronized lyrics, e.g. using Lyrics โ†’ Embed Lyrics from the file list context menu.
  • Copy the unsynchronized lyrics to the clipboard โ€” just go to the Lyrics row in the frame table and press Ctrl+C.
  • Add a synchronized lyrics frame (Add..., Synchronized Lyrics, OK), click From Clipboard.
  • Now all the lines from the unsynchronized lyrics are in the table, and all time stamps are invalid (0:0:0.00). You can delete empty entries beforehand.
  • Start playing the song by clicking the play button โ–บ in the play toolbar at the bottom of the main window.
  • When the next lyrics line with an invalid timestamp comes around, click Add or press Alt+A โ€” the timestamp gets updated. โญ
  • Continue like this until all timestamps are set. If you missed something, stop playback and clear the timestamps using the Delete key, or by selecting them and using Clear from the context menu. To restart playback from a given timestamp, use Seek to position from the context menu.

๐Ÿ“– Chapters in MP4 Files

MP4 audiobooks typically have a .m4b extension and are honestly kind of huge, because they contain all chapters in a single file. So you can navigate around in them, they can contain chapter marks โ€” and those can be edited in Kid3 in a pseudo "Chapters" frame using the same editor that's used for synchronized lyrics. There are two types of chapters in MP4 files: "Nero" and "QuickTime (QT)".

The chapter information in MP3 audiobooks is stored in multiple "Chapter" (CHAP) frames which are referenced by a "Table of Contents" (CTOC) frame, and these frames have embedded subframes. To edit this info in a single place, a pseudo "Chapters" frame can also be used for ID3v2 tags. Its contents are used to create the real chapter, table of contents and embedded frames: the Description is used as the table of contents title, the Text column contains the chapter titles, and the corresponding Time value will be the chapter start time and the end time of the preceding chapter. The end time of the last chapter is determined by the Time of the last row if its Text is empty. ๐Ÿ‘‘


๐Ÿ’พ The File Menu

File โ†’ Open... ( Ctrl+O )

Opens a folder. All files matching the selected file name filter get displayed in the file listbox, and the chosen file is selected. ๐ŸŽ€

File โ†’ Open Recent

Opens a recently opened folder. That's it, that's the whole thing.

File โ†’ Open Folder... ( Ctrl+D )

Opens a folder. All files matching the selected file name filter get displayed in the file listbox.

File โ†’ Reload ( F5 )

Reload folder. Modified files have to be saved before โ€” no skipping that. Expanded subfolders get collapsed.

File โ†’ Save ( Ctrl+S )

Saves all changed files in the folder. Changed files are marked with a disk symbol in the file listbox. ๐Ÿ’พ If any file names have been changed, those files get renamed.

File โ†’ Revert

Reverts the changes of one or multiple files. If no files are selected in the file listbox, the changes of all files get reverted; otherwise only the changes of the selected files get reverted. ๐Ÿ™ˆ

File โ†’ Import...

The Import dialog can be used to import data directly from a freedb.org server, from a MusicBrainz server, from Discogs, Amazon, or other sources of album track lists in textual format.

Import from a freedb.org server is possible using a dialog that appears when From Server: gnudb.org is selected. You enter the artist and album name you're searching for in the two topmost fields, the albums matching the query get displayed when Find is clicked and the results from www.gnudb.org[7] come in. Importing the track data for an album is done by double-clicking the album in the list. The freedb.org server to import from can be selected as well as the CGI path. The imported data gets displayed in the preview table of the import dialog. When you're happy with the displayed tracks, you can import them by closing the import dialog with OK.

If you already have a search result open in the web browser, you can enter the URL into the first search field. The result then appears in the album list and can be imported straight into Kid3. ๐Ÿฆ‹

An e-mail address registered at gnudb.org[8] can be entered into the Token field.

A search on the Discogs server can be performed using Discogs. Same as in the gnudb.org dialog, you enter artist and album and then choose from a list of releases. A Token can be entered to use the RESTful Discogs API instead of their web interface, which is often changed โ€” thereby breaking the import parser, fun. You have to register for an account on Discogs[9] and then generate a token on their web site (Settings/Developers, Generate new token). Don't forget to Save Settings after entering the token so it gets used in subsequent requests too. If Standard Tags is marked, the standard info gets imported, e.g. artist, album, and title. If Additional Tags is marked, more info gets imported if available, e.g. performers, arrangers, or the publisher. If Cover Art is marked, cover art gets downloaded if available. ๐ŸŽจ

A search on Amazon can be performed using Amazon. Same as in the gnudb.org dialog, you enter artist and album and then choose from a list of releases. If Additional Tags is marked, more info gets imported if available, e.g. performers, arrangers, or the publisher. If Cover Art is marked, cover art gets downloaded if available.

You can search in the same way in the release database of MusicBrainz using From MusicBrainz Release. The workflow is the same as described for From gnudb.org. โœจ

MusicBrainz import (๐Ÿ’œ hi, this is the fingerprint one) happens through the dialog that pops up when you select From MusicBrainz Fingerprint. The server gets picked the same way it does in the freedb import dialog, no new lore there. Underneath is a table showing the imported track data, and the rightmost column is basically the vibe check on your MusicBrainz query โ€” it kicks off as "Pending" the second the dialog opens. Then the fingerprint gets looked up, and if that comes back with nothing, it tries another lookup using the tags in the file. So bestie, if you want your MusicBrainz query to actually hit, it genuinely helps to stash known info (like the artist and album) in the tags before you import โœจ. If a result lands, the search wraps up in the state "Recognized". If not? Either nothing was found, or there were multiple ambiguous results and you have to pick one yourself. OK and Apply use the imported data, Cancel closes the dialog โ€” but ngl, closing can take a hot minute, because the entire MusicBrainz machinery has to shut down ๐Ÿ˜ญ.

For textual data, From File/Clipboard opens a subdialog stuffed with preconfigured import formats. The first two, "CSV unquoted" and "CSV quoted", are for importing data that was exported by the Export dialog. You can edit that CSV data with a spreadsheet, and it should be written using tabs as delimiters. Import should then work with "CSV quoted", which is more flexible than "CSV unquoted" โ€” except its fields can't contain any double quotes ๐Ÿ™ˆ. If you're only ever exporting from Kid3 and importing later, "CSV unquoted" is a perfectly simple format for that. Also, heads up: there are "Export CSV" and "Import CSV" commands in the context menu of the file list too, and those use scripts to export and import CSV data in a much more complete, powerful and flexible way ๐Ÿ‘‘

The next format, "freedb HTML text", is for copying info off an HTML page of freedb.org[10]. Search an album in freedb, and if the info you want shows up in your web browser, copy the contents to the clipboard. Then hit the From Clipboard button and the imported tracks appear in the preview table at the top of the dialog. If you're happy with them, close the dialog with OK and it'll insert the data into the tags of the current folder. Destination (Tag 1, Tag 2 or Tag 1 and Tag 2) is picked with a combo box. The files in the current folder should be in the correct track order so they get their tags assigned properly โ€” which is the case if they're numbered ๐Ÿ”ฅ.

Next preconfigured format: "freedb HTML source", for when the data exists as an HTML document. You import with the From File button (opens a file selector) or by copying its contents from an editor and then importing from the clipboard. This one's great for offline import, even though you could just open that HTML document in a browser and import it in the first format via the clipboard. Both roads slay ๐Ÿซถ.

There are more preconfigured formats too, e.g. "Track Title Time". You can create an empty custom format with Add and then set it up yourself. Two lines below the format name can be set with a regular expression to capture fields from the import text:

  1. The first regular expression gets parsed once per document to gather per-album data like artist, album, year and genre.
  2. The second line is tried against the document from start to end to get the track data, usually number and title.

Those regular expressions include every feature Qt(TM) offers, which is basically most of what Perl offers ๐Ÿ’…. Bracketing constructs "(..)" create capture buffers for the fields to import, and they're preceded by Kid3-specific codes telling it which field to capture. The codes are the same ones used for the filename format โ€” and besides the codes listed below, any frame name is possible:

  • %s %{title} โ€” Title (Song)
  • %a %{artist} โ€” Artist
  • %l %{album} โ€” Album
  • %c %{comment} โ€” Comment
  • %y %{year} โ€” Year
  • %t %{track} โ€” Track
  • %g %{genre} โ€” Genre
  • %d %{duration} โ€” Duration

For example, a track regular expression (the second line, remember) to import from an .m3u playlist could be:

"%{track}(\d+)\s+%{title}(\S[^\r\n]*)\.mp3[\r\n]"

All formats can be changed by editing the regular expressions and the name, then clicking Save Settings. They get stored in the kid3rc file in the configuration folder ๐Ÿ“. You can edit that file directly to get even more import formats, or delete it to revert to the default formats. Formats can be deleted using Remove.

Accuracy shows an estimation of how well the imported info matches the given tracks โ€” it uses track durations or file names to calculate a similarity level in percent. Cover Art shows the URL of the album cover image that will be downloaded ๐ŸŽ€.

Want to check whether the imported tracks actually match your current set of files? Compare the duration of the imported tracks with the duration of the files. Turn this on with the check box Check maximum allowable time difference (sec): and set the maximum tolerated difference in time, in seconds. If a mismatch in a length gets detected, that length is displayed with a red background in the preview table ๐Ÿ”ฅ.

If your files are ordered differently than the imported tracks, their assigned tracks have to be changed. Make that easier with the Match with option plus the buttons Length, Track, and Title, which reorder the tracks according to the corresponding field. To fix assignments by hand, drag a track with the left mouse button while holding down Ctrl, then drop it at the new location ๐Ÿ–ฑ๏ธ.

Got more imported tracks than files? Say your current folder has only the second disc of a two-disc album but you imported the tracks of both discs. You can delete the first disc's tracks by selecting them: click the row label of the first track, then click the row label of the last track of the first disc while holding down Shift, and finally remove them by pressing Delete ๐Ÿ’€.

When the import dialog opens, it holds the actual contents of the tags. The tag type (Tag 1, Tag 2, Tag 1 and Tag 2) is selected with the Destination combo box. The button to the right of that combo box reverts the table back to the current contents of the tags. The check boxes in the first table column pick which tracks get imported โ€” which is super useful if a folder contains the tracks of both CDs of a double CD and you only want the tracks of the second CD โœจ.

To identify which tracks are imported, you can display the file names or the full paths to the files via the context menu of the table header. The values in the import table can be edited. And that revert-button to the right of the Destination combo box? It restores the contents of the tags, which is also handy after you've changed the Destination ๐Ÿ™ˆ.

Almost all dialogs feature a Save Settings button, which stores the dialog-specific settings and the window size persistently. Iconic behaviour, honestly ๐Ÿ‘‘.

From Tags leads to a subdialog for setting tag frames from the contents of other tag frames. Use it to simply copy info between tags, or to extract a part from one frame and insert it in another ๐Ÿงš.

Like in the import from file/clipboard dialog, there are freely configurable formats to perform different operations. Already preconfigured: formats that copy the Album value to Album Artist, Composer or Conductor, and formats that extract the Track Number from Title fields containing a number. There's also a format to extract a Subtitle from a Title field ๐ŸŒธ.

Here's the example for adding a custom format that also sticks the info from the Subtitle field into the Comment field. Create a new format with the Add button, give it a new name, e.g. "Subtitle to Comment". Then enter "%{subtitle}" in Source and "%{comment}(.*)" for Extraction, and click Save Settings ๐Ÿ’–.

The expression in Source can contain format codes for arbitrary tag frames, and multiple codes can be used to combine the contents from different frames. For each track, a text is generated from its tags using the Source format, and the regular expression from Extraction is applied to this text to set new values for the tags. Format codes go before the capturing parentheses to specify the tag frame where the captured text shall be stored โ€” works exactly the same way as for the import from file/clipboard ๐ŸŒˆ.

Import from Tags... is also directly available from the File menu. The difference between these two: the import dialog subdialog operates on all files of the current folder, whereas the menu function operates on the selected files (which can be in different folders). The menu function also supports an extra code "%{__return}" to return the extracted value, which is useful with the CLI and QML interfaces ๐Ÿ‘‘

  • File โ†’ Import from gnudb.org... โ€” import from a freedb.org server using gnudb.org album search. Opens the same import dialog as Import..., but goes straight to the gnudb.org dialog ๐ŸŒ
  • File โ†’ Import from Discogs... โ€” import from the Discogs server. Opens the same import dialog as Import..., but goes straight to the From Discogs dialog
  • File โ†’ Import from Amazon... โ€” import from Amazon. Opens the same import dialog as Import..., but goes straight to the From Amazon dialog
  • File โ†’ Import from MusicBrainz Release... โ€” import from the MusicBrainz release database. Opens the same import dialog as Import..., but goes straight to the From MusicBrainz Release dialog
  • File โ†’ Import from MusicBrainz Fingerprint... โ€” import from a MusicBrainz server. Opens the same import dialog as Import..., but goes straight to the From MusicBrainz Fingerprint dialog ๐Ÿ’œ
  • File โ†’ Import from Tags... โ€” like From Tags, but the import is applied to the selected files
  • File โ†’ Automatic Import...

Automatic Import is your little batch-bestie ๐Ÿ’– โ€” it pulls info for multiple albums from various web services in one go. If folders are selected in the file list, track data for the selected folders will be imported. If no folder is selected, all folders in the file list will be imported. Easy.

The tag type (Tag 1, Tag 2, Tag 1 and Tag 2) can be selected using the Destination combo box.

Profiles determine which servers get contacted to fetch album information. Some profiles are predefined (All, MusicBrainz, Discogs, Cover Art), and custom profiles can be added using the Add button at the right of the Profile combo box. Customization slay โœจ.

The table below shows the servers which will be used when importing album information using the selected profile. The import process for an album is finished if all required information has been found, so the order of the rows in the table is important โ€” no cap, order actually matters here ๐Ÿ‘‘. It can be changed using the Move Up and Move Down buttons. Edit can be used to change an existing entry. The Server selection offers the same servers as can be used in the import functions. Standard Tags, Additional Tags, Cover Art determine the information which shall be fetched from the server. Finally, Accuracy is the minimum accuracy which must be achieved to accept the imported data. If the accuracy is insufficient, the next server in the list will be tried. The same dialog containing the server properties appears when Add is clicked to add a new server entry. Existing entries can be deleted using Remove.

To launch an automatic batch import with the selected profile, click Start. Details about the running import are displayed at the top of the dialog. The process can be aborted with the Abort button. ๐Ÿ›‘


๐ŸŽ€ File โ†’ Browse Cover Art... ๐ŸŽ€

The Browse Cover Art dialog helps to find album cover art. Artist/Album is filled from the tags if possible. Source offers a variety of websites with album cover art. The URL with artist and album as parameters can be found beneath the name. URL-encoded values for artist and album can be inserted using "%u{artist}" and "%u{album}", other values from the tags are possible too, as described in Configure Kid3, User Actions. More sources can be entered after the entry "Custom Source" by replacing "Custom Source" with the source's name, pressing Enter, then inserting the URL and finally pressing Save Settings. The resulting browser command is displayed at the top of the dialog and can be started by clicking Browse. The browser, which can be configured in the settings, is started with the selected source. A cover image can then be dragged from the browser into the Kid3 window and will be set in the picture frame of the selected files. Drag-and-drop cover art is genuinely main character energy ๐Ÿฆ‹.

Because not all browsers support drag and drop of images and the pictures on websites often have a URL, in such cases Kid3 will receive the URL and not the picture. If the URL points to a picture, it will be downloaded. However, if the URL refers to some other web resource, it has to be translated to the corresponding picture. Such mappings are defined in the table URL extraction. The left column Match contains a regular expression which is compared with the URL. If it matches, the captured expressions in parentheses are inserted into the pattern of the right Picture URL column (at the positions marked with \1 etc.). The replaced regular expression contains the URL of the picture. By this means cover art can be imported from Amazon, Google Images, etc. using drag and drop. It is also possible to define your own mappings. ๐Ÿ’…


๐ŸŒธ File โ†’ Export... ๐ŸŒธ

The Export Dialog is used to store data from the tags in a file or the clipboard. The editor at the top shows a preview of the data to export. If the export data contain tabulator characters, the export is displayed in a table. The data will be generated from the tags in the current folder according to the configured format.

The format settings are similar as in the Import dialog: The topmost field contains the title (e.g. "CSV unquoted"), followed by the header, which will be generated at the begin of the file. The track data follows; it is used for every track. Finally, the trailer can be used to generate some finishing text.

The format fields do not contain regular expressions as in the Import dialog, but only output format expressions with special %-expressions, which will be replaced by values from the tags. The whole thing works like the file name format, and the same codes are used plus some additional codes. Not only the codes listed below but all tag frame names can be used. Respect the codes, they're iconic ๐Ÿ‘‘

  • %s %{title} โ€” Title (Song)
  • %a %{artist} โ€” Artist
  • %l %{album} โ€” Album
  • %c %{comment} โ€” Comment
  • %y %{year} โ€” Year
  • %t %{track} โ€” Track (e.g. 01)
  • %t %{track.n} โ€” Track with field width n (e.g. 001 for %{track.3})
  • %T %{tracknumber} โ€” Track (without leading zeros, e.g. 1)
  • %g %{genre} โ€” Genre
  • %f %{file} โ€” File name
  • %p %{filepath} โ€” Path
  • %{modificationdate} โ€” Modification date
  • %{creationdate} โ€” Creation date
  • %u %{url} โ€” URL
  • %{dirname} โ€” Folder name
  • %d %{duration} โ€” Duration in minutes:seconds
  • %D %{seconds} โ€” Duration in seconds
  • %n %{tracks} โ€” Number of tracks of the album
  • %e %{extension} โ€” File extension
  • %O %{tag1} โ€” The format of tag 1 (ID3v1.1 or empty if not existing)
  • %o %{tag2} โ€” The format of tag 2 (ID3v2.3.0, ID3v2.4.0, ID3v2.2.0, ID3v2.2.1, Vorbis, APE, MP4, ASF, or empty if not existing)
  • %b %{bitrate} โ€” Bit rate in kbit/s
  • %r %{samplerate} โ€” Sample rate in Hz
  • %m %{mode} โ€” Channel mode (Stereo or Joint Stereo)
  • %h %{channels} โ€” Number of channels (1 or 2)
  • %k %{codec} โ€” Codec (e.g. MPEG 1 Layer 3, MP4, Ogg Vorbis, FLAC, MPC, APE, ASF, AIFF, WAV)

A few formats are predefined. "CSV unquoted" separates the fields by tabs. Data in this format can be imported again into Kid3 using the import format with the same name. "CSV quoted" additionally encloses the fields by double quotes, which eases the import into spreadsheet applications. However, the fields shall not contain any double quotes when this format is used. "Extended M3U" and "Extended PLS" generate playlists with extended attributes and absolute path names. "HTML" can be used to generate an HTML page with hyperlinks to the tracks. "Kover XML" creates a file which can be imported by the cover printing program Kover. "Technical Details" provides information about bit rate, sample rate, channels, etc. Finally, "Custom Format" is left empty for definition of a custom format. You can define more formats of your own by adding lines in the file kid3rc in the configuration folder. The other formats can be adapted to your needs. ๐Ÿงš

The Source of the tags to generate the export data (Tag 1 or Tag 2) can be selected with a combo box. Pushing To File or To Clipboard stores the data in a file or on the clipboard. OK and Cancel close the dialog, whereas OK accepts the current dialog settings.


๐Ÿ’œ File โ†’ Create Playlist... ๐Ÿ’œ

Creates a playlist. The format and contents of the playlist can be set by various options. Ok so this one has options options, let's go ๐ŸŽ€

The name of the playlist can be the Same as folder name or use a Format with values from the tags, e.g. "%{artist} - %{album}" to have the artist and album name in the playlist file name. The format codes are the same as for Export. The list of available formats can be edited in the Format section of the Files tab in the settings. Create new empty playlist will make an empty playlist with the given name. The extension depends on the playlist format.

The location of the generated playlist is determined by the selection of the Create in combo box.

  • Current folder โ€” The playlist is created in the current folder and contains only files of the current folder. The current folder is the folder where the current file is located. If multiple files are selected, the current file is probably the last selected file.
  • Every folder โ€” A playlist is created in every folder which contains listed files, and each playlist contains the files of that folder.
  • Top-level folder โ€” Only one playlist is created in the top-level folder (i.e. the folder of the file list) and it contains the listed files of the top-level folder and all of its sub-folders.

The Format of the playlist can be M3U, PLS or XSPF.

If Include only the selected files is checked, only the selected files will be included in the playlist. If a folder is selected, all of its files are selected. If this check box is not activated, all audio files are included in the playlist.

Sort by file name selects the usual case where the files are ordered by file name. With Sort by tag field, it is possible to sort by a format string with values from tag fields. For instance, "%{track.3}" can be used to sort by track number (the ".3" is used to get three digits with leading zeros because strings are used for sorting). It is also possible to use multiple fields, e.g. "%{genre}%{year}" to sort using a string composed of genre and year. Sorting by vibes, but make it string-based โœจ

The playlist entries will have relative or absolute file paths depending on whether Use relative path for files in playlist or Use full path for files in playlist is set.

When Write only list of files is set, the playlist will only contain the paths to the files. To generate an extended playlist with additional information, a format string can be set using the Write info using control.


๐Ÿซถ File โ†’ Quit ( Ctrl+Q ) ๐Ÿซถ

Quits the application. Bye bestie, see you tomorrow ๐Ÿ˜ญ๐Ÿ’–


๐ŸŒˆ The Edit Menu ๐ŸŒˆ

โญ Edit โ†’ Select All ( Alt+A ) โญ

Selects all files. All of them. Every single one ๐Ÿ‘‘

๐ŸŽ€ Edit โ†’ Deselect ( Ctrl+Shift+A ) ๐ŸŽ€

Deselects all files. Undoing your selection era.

๐Ÿฆ‹ Edit โ†’ Select All in Folder ๐Ÿฆ‹

Selects all files of the current folder. Just that folder, bestie โ€” not the whole world.

๐ŸŒธ Edit โ†’ Previous File ( Alt+Up ) ๐ŸŒธ

Selects the previous file.

๐Ÿ’… Edit โ†’ Next File ( Alt+Down ) ๐Ÿ’…

Selects the next file. Back and forth, back and forth, iconic navigation ๐ŸŽ€

๐Ÿ”ฅ Edit โ†’ Find... ( Ctrl+F ) ๐Ÿ”ฅ

Find strings in the file names and the tags. The Find dialog is a subset of the Replace dialog, which is described below.

๐Ÿ’€ Edit โ†’ Replace... ( Ctrl+R ) ๐Ÿ’€

This function opens a whole dialog for finding and replacing strings in your file names and in the tags โœจ. You don't have to search everything either โ€” the set of frames where the search happens can be restricted by deactivating the Select all check box and then hand-picking the frames you actually want searched. There are also search options to search backwards, to search case sensitively, and to use regular expressions ๐ŸŽ€.

Heads up bestie: depending on how many files you've got, the search might take a little while โ€” so it can be aborted at any time by just closing the dialog ๐Ÿ’….

โœจ The Tools Menu โœจ

Tools โ†’ Apply Filename Format

When Automatically apply format is switched off for the filename format in the configuration dialog, this menu item is your girl โ€” it applies the configured format to the names of the selected files ๐Ÿซถ.

You can also use it as a vibe check on whether your file names actually conform with the configured format: apply the format to all saved files, then look and see if any files got changed (and therefore got marked with a disk symbol in the file listbox) ๐Ÿ‘€.

Tools โ†’ Apply Tag Format

Same energy, but for tags ๐ŸŒธ. When Automatically apply format is switched off for the tag format in the configuration dialog, this menu item applies the configured format to the tags of the selected files.

And again, you can use it to check whether the tags conform with the configured format: apply the format to all saved files and then check if any files were changed (and therefore marked with a disk symbol in the file listbox) ๐Ÿ”ฅ.

Tools โ†’ Apply Text Encoding

Sets the Text encoding selected in Settings โ†’ Configure Kid3... โ†’ Tags section โ†’ Tag 2 tab for all selected files โœจ.

Little lore drop: if UTF8 is selected, UTF16 will be used for ID3v2.3.0 tags, because UTF8 is not supported for this format ๐Ÿซ .

Tools โ†’ Rename Folder...

This dialog offers the possibility to automatically rename the currently open folder according to the tags in the files ๐Ÿ‘‘. Several formats are preconfigured to include information about artist, album and year in the folder name. It is also possible to set a custom format and Edit the list of available formats ๐Ÿ’–.

The following special codes are used to insert tag values into the folder name:

  • %s %{title} โ€” Title (Song)
  • %a %{artist} โ€” Artist
  • %l %{album} โ€” Album
  • %c %{comment} โ€” Comment
  • %y %{year} โ€” Year
  • %t %{track} โ€” Track (e.g. 01)
  • %t %{track.n} โ€” Track with field width n (e.g. 001 for %{track.3})
  • %T %{tracknumber} โ€” Track (without leading zeros, e.g. 1)
  • %g %{genre} โ€” Genre
  • %{dirname} โ€” Folder name (e.g. %{year" "}%{dirname} will prepend the year to the current folder name)
  • %{max-year} โ€” The maximum year value found for this folder, can also be used with other codes than "year"
  • %{min-year} โ€” The minimum year value found for this folder
  • %{unq-year} โ€” The unique year value found for this folder or empty if not unique

If a folder separator / is found in the format, multiple folders are created ๐Ÿฆ‹. If you want to create a new folder instead of renaming the current folder, in the Action combo box select Create Folder instead of Rename Folder. The Source of the tag information can be chosen between Tag 1 and Tag 2, Tag 1 and Tag 2.

A preview for the rename operation performed on the first file can be seen in the From and To sections of the dialog ๐Ÿ‘€.

Multiple folders can be renamed by selecting them ๐Ÿ’….

Tools โ†’ Number Tracks...

If the track numbers in the tags are not set, or are just straight-up wrong, this function can number the tracks automatically in ascending order ๐Ÿ”ข. The start number can be set in the dialog. If only part of the tracks have to be numbered, they must be selected first.

When Total number of tracks is checked, the number of tracks will also be set in the tags โœจ.

It is possible to number the tracks over multiple folders โ€” the folders just have to be expanded and selected ๐ŸŒˆ.

If Reset counter for each folder is checked, track numbering is restarted with the given number for each folder when multiple folders are selected.

Iconic bonus feature: the number tracks dialog can also be used to format existing track numbers without changing the values, when the check box left to Start number is deactivated ๐Ÿ™ˆ. The total number of tracks will be added if the corresponding check box is active, which can be used to set the total for all selected tracks. If only formatting of the existing numbers is desired, this check box has to be deactivated too.

Tools โ†’ Filter...

The filter can be used to display only those files which match certain criteria ๐ŸŽ€. This is helpful if you want to organize a large collection and only edit those files which are not in the desired scheme. The expression defining which files to display uses the same format codes which are used in the file name format, import and export ๐Ÿ‘‘

  • %s %{title} โ€” Title (Song)
  • %a %{artist} โ€” Artist
  • %l %{album} โ€” Album
  • %c %{comment} โ€” Comment
  • %y %{year} โ€” Year
  • %t %{track} โ€” Track (e.g. 01)
  • %t %{track.n} โ€” Track with field width n (e.g. 001 for %{track.3})
  • %T %{tracknumber} โ€” Track (without leading zeros, e.g. 1)
  • %g %{genre} โ€” Genre
  • %f %{file} โ€” File name
  • %p %{filepath} โ€” Absolute path to file
  • %e %{extension} โ€” File extension
  • %O %{tag1} โ€” The format of tag 1 (ID3v1.1 or empty if not existing)
  • %o %{tag2} โ€” The format of tag 2 (ID3v2.3.0, ID3v2.4.0, ID3v2.2.0, ID3v2.2.1, Vorbis, APE, MP4, ASF, or empty if not existing)
  • %b %{bitrate} โ€” Bit rate in kbit/s
  • %r %{samplerate} โ€” Sample rate in Hz
  • %m %{mode} โ€” Channel mode (Stereo or Joint Stereo)
  • %h %{channels} โ€” Number of channels (1 or 2)
  • %k %{codec} โ€” Codec (e.g. MPEG 1 Layer 3, MP4, Ogg Vorbis, FLAC, MPC, APE, ASF, AIFF, WAV)
  • %w %{marked} โ€” Marked, is 1 if the file is marked (e.g. because of truncation or standard violation), empty otherwise
  • %1a %1{artist}, ... โ€” Use the prefix 1 to get values of tag 1
  • %2a %2{artist}, ... โ€” Use the prefix 2 to get values of tag 2

These codes are replaced with the values for the file, and the resulting strings can be compared with the following operations ๐Ÿงš:

  • s1 equals s2 โ€” true if s1 and s2 are equal.
  • s1 contains s2 โ€” true if s1 contains s2, i.e. s2 is a substring of s1.
  • s matches re โ€” true if s matches the regular expression re.

True expressions are replaced by 1, false by 0. True values are represented by 1, true, on and yes; false values by 0, false, off and no ๐Ÿ’–. Boolean operations are not, and, or (in this order of precedence) and can be grouped by parentheses.

Some filter rules are predefined and can serve as examples for your own expressions ๐Ÿ‘€:

All

When the file list is filtered โ€” this is shown by "[filtered]" in the window title โ€” and all files shall be displayed again, the filtering can be reverted using this filter. It uses an empty expression, but a true value would have the same effect.

Filename Tag Mismatch

not (%{filepath} contains "%{artist} - %{album}/%{track} %{title}")

Tests if the file path conforms with the file name format. This rule is automatically adapted if the file name format changes.

No Tag 1

%{tag1} equals ""

Displays only files which do not have a tag 1.

No Tag 2

%{tag2} equals ""

Displays only files which do not have a tag 2.

ID3v2.3.0 Tag

%{tag2} equals "ID3v2.3.0"

Displays only files which have an ID3v2.3.0 tag.

ID3v2.4.0 Tag

%{tag2} equals "ID3v2.4.0"

Displays only files which have an ID3v2.4.0 tag.

Tag 1 != Tag 2

not (%1{title} equals %2{title} and %1{album} equals %2{album} and %1{artist} equals %2{artist} and %1{comment} equals %2{comment} and %1{year} equals %2{year} and %1{track} equals %2{track} and %1{genre} equals %2{genre})

Displays files with differences between tag 1 and tag2.

Tag 1 == Tag 2

%1{title} equals %2{title} and %1{album} equals %2{album} and %1{artist} equals %2{artist} and %1{comment} equals %2{comment} and %1{year} equals %2{year} and %1{track} equals %2{track} and %1{genre} equals %2{genre}

Displays files with identical tag 1 and tag 2.

Incomplete

%{title} equals "" or %{artist} equals "" or %{album} equals "" or %{year} equals "" or %{tracknumber} equals "" or %{genre} equals ""

Displays files with empty values in the standard tags (title, artist, album, date, track number, genre).

No Picture

%{picture} equals ""

Displays only files which do not have a picture.

Marked

not (%{marked} equals "")

Displays only files which are marked because they violate the ID3 standard, are truncated or the picture is too large.

Custom Filter

To add your own filter, select this entry โœจ. For instance, if you want to have a filter for artists starting with "The", replace "Custom Filter" with the name "The Bands" and press Enter. Then insert the following expression into the line edit:

%{artist} matches "The.*"

Then click Save Settings. Click Apply to filter the files. All files processed are displayed in the text view, with a "+" for those who match the filter and a "-" for the others ๐Ÿ’…. When finished, only the files with an artist starting with "The" are displayed, and the window title is marked with "[filtered]" ๐Ÿ‘‘

Tools โ†’ Convert ID3v2.3 to ID3v2.4

If there are any ID3v2.3 tags in the selected files, they will be converted to ID3v2.4 tags ๐Ÿ”ฅ.

No cap: frames which are not supported by TagLib will be discarded ๐Ÿ’€. And only files without unsaved changes will be converted.

Tools โ†’ Convert ID3v2.4 to ID3v2.3

If there are any ID3v2.4 tags in the selected files, they will be converted to ID3v2.3 tags. Only files without unsaved changes will be converted ๐Ÿซถ.

Tools โ†’ Play

Okay so this opens a simple toolbar to play audio files. Itโ€™s got buttons for the basic operations (Play/Pause, Stop playback, Previous Track, Next Track, Close), sliders for position and volume, and a display of the current position. If multiple files are selected, the selected tracks are played; otherwise all files will be played. ๐Ÿ’–

The time displayed can be toggled between elapsed and remaining time by clicking on the display.

โœจ The Settings Menu โœจ

  • Settings โ†’ Show Toolbar โ€” toggles displaying of the toolbar.
  • Settings โ†’ Show Statusbar โ€” toggles displaying of the statusbar, which displays longer actions such as opening or saving a folder.
  • Settings โ†’ Show Picture โ€” toggles displaying of the album cover art preview picture.
  • Settings โ†’ Auto Hide Tags โ€” empty tags are automatically hidden if this option is active. The File, Tag 1 and Tag 2 sections can be manually collapsed and expanded by clicking on the corresponding -/+ buttons.
  • Settings โ†’ Configure Shortcut keys... โ€” opens a dialog to assign keyboard shortcuts for most of the program functions. There are even functions without corresponding menu or button available, e.g. next file, previous file, select all.
  • Settings โ†’ Configure Kid3... โ€” opens the configuration dialog, which consists of pages for tags, files, user actions, and network settings.

Tag specific options can be found on the Tags page, which is itself separated into four tabs for Tag 1, Tag 2, Tag 3, and All Tags.

  • Mark truncated fields โ€” if checked, truncated ID3v1.1 fields will be marked red. The text fields of ID3v1.1 tags can only have 30 characters, the comment only 28 characters. Also the genre and track numbers are restricted, so fields can be truncated when imported or transferred from ID3v2. Truncated fields and the file will be marked red, and the mark will be removed after the field has been edited.
  • Text encoding for ID3v1 โ€” makes it possible to set the character set used in ID3v1 tags. This encoding is supposed to be ISO-8859-1, so it is recommended to keep this default value. However, there are tags around with different encoding, so it can be set here and the ID3v1 tags can then be copied to ID3v2 which supports Unicode.
  • Use track/total number of tracks format โ€” this check box controls whether the track number field of ID3v2 tags contains simply the track number or additionally the total number of tracks in the folder.
  • Genre as text instead of numeric string โ€” when checked, all ID3v2 genres will be stored as a text string even if there is a corresponding code for ID3v1 genres. If this option is not set, genres for which an ID3v1 code exists are stored as the number of the genre code (in parentheses for ID3v2.3). Thus the genre Metal is stored as "Metal" or "(9)" depending on this option. Genres which are not in the list of ID3v1 genres are always stored as a text string. The purpose of this option is improved compatibility with devices which do not correctly interpret genre codes.
  • WAV files with lowercase id3 chunk โ€” when checked, the RIFF chunk used to store ID3v2 tags in WAV files will be named "id3 " instead of "ID3 ". By default, Kid3 and other applications using TagLib accept both the lowercase and the uppercase variant when reading WAV files, but they use "ID3 " when writing ID3v2 tags to WAV files. As there exist other applications which only accept "id3 " (e.g. JRiver Media Center and foobar2000), this option can be used to create tags which can be read by such applications.
  • Mark standard violations โ€” when checked, ID3v2 fields which violate the standard will be marked red. Details about the violation are shown in a tooltip:
    • Must be unique
    • New line is forbidden
    • Carriage return is forbidden
    • Owner must be non-empty
    • Must be numeric
    • Must be numeric or number/total
    • Format is DDMM
    • Format is HHMM
    • Format is YYYY
    • Must begin with a year and a space character
    • Must be ISO 8601 date/time
    • Must be musical key, 3 characters, A-G, b, #, m, o
    • Must have ISO 639-2 language code, 3 lowercase characters
    • Must be ISRC code, 12 characters
    • Must be list of strings separated by '|'
    • Has excess white space

The ID3 standard documents are available online:

  • ID3 tag version 2.3.0[11]
  • ID3 tag version 2.4.0 - Main Structure[12]
  • ID3 tag version 2.4.0 - Native Frames[5]
  • Text encoding โ€” defines the default encoding used for ID3v2 frames and can be set to ISO-8859-1, UTF16, or UTF8. UTF8 is not valid for ID3v2.3.0 frames; if it is set, UTF16 will be used instead. For ID3v2.4.0 frames, all three encodings are possible.
  • Version used for new tags โ€” determines whether new ID3v2 tags are created as version 2.3.0 or 2.4.0.
  • Track number digits โ€” this is the number of digits in Track Number fields. Leading zeros are used to pad. For instance, with a value of 2 the track number 5 is set as "05".
  • Comment field name โ€” this combo box is only relevant for Ogg/Vorbis and FLAC files and sets the name of the field used for comments. Different applications seem to use different names, "COMMENT" for instance is used by XMMS, whereas Amarok uses "DESCRIPTION".
  • Picture field name โ€” the format of pictures in Ogg/Vorbis files is determined by this, which can be "METADATA_BLOCK_PICTURE" or "COVERART". The first is the official standard and uses the same format as pictures in FLAC tags. "COVERART" is an earlier unofficial way to include pictures in Vorbis comments. It can be used for compatibility with legacy players.
  • Write mode โ€” the mode used when saving Matroska files can be selected here. It controls the trade-off between file size and write speed when saving tags, attachments and chapters to the file. For very large files and/or slow (network) filesystems, using Avoid insert will reduce write time significantly. There are three possible modes:
    • Compact: Write tags, attachments and chapters as compact as possible. This is the default mode.
    • Do not shrink: Do not shrink blocks when writing, add padding when content gets smaller. Allow inserts when content gets larger.
    • Avoid insert: Like Do not shrink but also avoid inserts for blocks which are not at the end of the file: Replace a growing non-last block with padding of the old size and append a new block at the end of the file.
  • Mark if larger than (bytes) โ€” if this check box is activated, files containing embedded album cover art exceeding the given size in bytes are marked red. This can be used to find files containing oversized pictures which are not accepted by some applications and players. The default value is 131072 bytes (128 KB).
  • Custom Genres โ€” can be used to define genres which are not available in the standard genre list, e.g. "Gothic Metal". Such custom genres will appear in the Genre combo box of Tag 2. For ID3v1.1 tags, only the predefined genres can be used.

The list of custom genres can also be used to reduce the number of genres available in the Genre combo box to those typically used. If your collection mostly contains music in the genres Metal, Gothic Metal, Ancient and Hard Rock, you can enter those genres and mark Show only custom genres. The Tag 2 Genre combo box will then only contain those four genres and you will not have to search through the complete genres list for them. In this example, only Metal and Hard Rock will be listed in the tag 1 genres list, because those two custom genres entries are standard genres. If Show only custom genres is not active, the custom genres can be found at the end of the genres list.

  • Custom Frames โ€” up to eight custom frame names can be defined here, which can then be used like the unified frames, for example as quick access frames.
  • Quick Access Frames โ€” defines which frame types are always shown in the Tag 2 section. Such frames can then be added without first using the Add button. The order of these quick access frames can be changed by dragging and dropping items.
  • Track number field name โ€” this combo box is only relevant for RIFF INFO and sets the name of the field used for track numbers. Track numbers are not specified in the original RIFF standard, there are applications which use "ITRK", others use "IPRT".
  • Tag Format โ€” contains options for the format of the tags. When Automatically apply format is checked, the format configuration is automatically used while editing text in the line edits. Validation enables validators in the controls with track/total and date/time values. The Case conversion can be set to No changes, All lowercase, All uppercase, First letter uppercase or All first letters uppercase. To use locale-aware conversion between lowercase and uppercase characters, a locale can be selected in the combobox below. The string replacement list can be set to arbitrary string mappings. To add a new mapping, select the From cell of a row and insert the text to replace, then go to the To column and enter the replacement text. When the text to replace starts and ends with a slash ("/"), a regular expression is used. For regular expressions containing capturing groups, occurrences of \1, \2, ... in To are replaced with the string captured by the corresponding capturing group. To remove a mapping set the From cell to an empty value (e.g. by first typing space and then backspace). Inserting and deleting rows is also possible using a context menu which appears when the right mouse button is clicked. Replacement is only active, if the String replacement check box is checked.

Okay so the table in Rating is literally the mapping between star ratings and the effective values stored in the tag. The frames with rating info are listed in the Rating row of the frame list. For those frames, you set the rating by giving a number of stars out of five. Different tag formats and different apps use different values to map the star rating to the value stored in the tag, so Kid3 looks up a map in this table to display the correct number of stars. The key for the lookup is the frame name โ€” for example "RATING" as used for Vorbis comments, or "IRTD" for RIFF INFO. For ID3v2 tags, the key is combined: the frame ID "POPM" of the Popularimeter frame plus its "Email" field, separated by a dot. That means different keys for ID3v2 exist, e.g. "POPM.Windows Media Player 9 Series" for the mapping used by Windows Media Player and Explorer, and simply "POPM" for POPM frames with an empty "Email" field. Since multiple entries for "POPM" can exist, their order is important. When Kid3 adds a new Popularimeter frame, it uses the first "POPM" entry to determine the value to be written into the "Email" field. That value then specifies the mapping to be used for star ratings. The first entry is also used if no key was found, so itโ€™s the default entry. ๐Ÿ’…

Ngl, bestie: the order of those "POPM" entries is not a vibe-check suggestion โ€” it literally matters.

The table has a Name column with the keys, plus columns 1 to 5 for the values stored when you give the corresponding number of stars. Flip it around and those values determine the number of stars displayed for the value stored in the frame. For instance, the row in the table below contains the values 1, 64, 128, 196, 255. The thresholds for the number of stars to be displayed sit between these values and are compatible with what the Windowsยฎ Explorer uses.

Table 1. Entry in Rating Table

  • POPM โ€” 1 โ†’ 1, 2 โ†’ 64, 3 โ†’ 128, 4 โ†’ 196, 5 โ†’ 255
  • Range โ€” 1 โ†’ 1-31, 2 โ†’ 32-95, 3 โ†’ 96-159, 4 โ†’ 160-223, 5 โ†’ 224-255

On the page Files, the check box Load last-opened files can be marked so that Kid3 will open and select the last selected file when it is started the next time. Preserve file timestamp can be checked to preserve the file modification time stamp. Filename for cover sets the name which is suggested when an embedded image is exported to a file. With Text encoding (Export, Playlist), the encoding used when writing files can be set. The default System can be changed, for example if playlists have to be used on a different device.

If Mark changes is active, changed fields are marked with a light gray label background. โœจ

The section File List determines which files are displayed in the file list. A Filter can be used to restrict the items in this list to files with supported extensions. To explicitly specify which folders to display in the file list, or exclude certain folders, use Include folders and Exclude folders. They can contain wildcard expressions, for instance */Music/* to include only the Music folder, or */iTunes/* to exclude the iTunes folder from the file list. If multiple such expressions have to be used, they can be separated by spaces or semicolons.

The buttons Filename from tag and Tag from filename in section Format open dialogs to edit the formats which are available in the Format combo boxes (with arrows up and down), which can be found in the File section of the main window.

The Playlist button can be used to edit the file name formats available in the Create Playlist dialog.

Filename Format contains options for the format of the filenames. The same options as in Tag Format are available.

Additionally, the Maximum length allowed for file names can be set. Most modern file systems have a limit of 255 characters, but if you want to burn the files to CD, you should set the limit to 64. If Use for playlist and folder names is checked, the file name format is also used when creating playlists and renaming folders. ๐ŸŽ€

The User Actions page contains a table with the commands which are available in the context menu of the file list. For critical operations such as deleting files, it is advisable to mark Confirm to pop up a confirmation dialog before executing the command. Output can be marked to see the output written by console commands (standard output and standard error). Name is the name displayed in the context menu. Command is the command line to be executed. Arguments can be passed using the following codes:

  • %F %{files} โ€” File paths (a list if multiple files selected)
  • %f %{file} โ€” File path to single file
  • %uF %{urls} โ€” URLs (a list if multiple files selected)
  • %uf %{url} โ€” URL to single file
  • %d %{directory} โ€” Folder
  • %s %{title} โ€” Title (Song)
  • %a %{artist} โ€” Artist
  • %l %{album} โ€” Album
  • %c %{comment} โ€” Comment
  • %y %{year} โ€” Year
  • %t %{track} โ€” Track (e.g. 01)
  • %t %{track.n} โ€” Track with field width n (e.g. 001 for %{track.3})
  • %T %{tracknumber} โ€” Track (without leading zeros, e.g. 1)
  • %g %{genre} โ€” Genre
  • %b %{browser} โ€” Command to start the web browser
  • %q %{qmlpath} โ€” Base folder of provided QML files

The special code @separator can be set as a command to insert a separator into the user actions context menu. Menu items can be put into a submenu by enclosing them with @beginmenu and @endmenu commands. The name of the submenu is determined by the Name column of the @beginmenu command.

To execute QML scripts, @qml is used as a command name. The path to the QML script is passed as a parameter. The provided scripts can be found in the folder %{qmlpath}/script/ (on Linuxยฎ typically /usr/share/kid3/qml/script/, on Windows qml/script/ inside the installation folder, and on macOSยฎ in the app folder kid3.app/Contents/Resources/qml/script/). Custom scripts can be stored in any folder. If the QML code uses GUI components, @qmlview shall be used instead of @qml. Additional parameters are passed to the QML script where they will be available via the getArguments() function. An overview of some functions and properties which are available in QML can be found in the appendix QML Interface. ๐Ÿฆ‹

The command which will be inserted with %{browser} can be defined in the Web browser line edit above. Commands starting with %{browser} can be used to fetch information about the audio files from the web, for instance

%{browser} http://lyricwiki.org/%u{artist}:%u{title}

will query the lyrics for the current song in LyricWiki[13]. The "u" in %u{artist} and %u{title} is used to URL-encode the artist %{artist} and song %{title} information. It is easy to define your own queries in the same way, e.g. an image search with Google[14]:

%{browser} http://images.google.com/images?q=%u{artist}%20%u{album}

To add album cover art to tag 2, you can search for images with Google or Amazon using the commands described above. The picture can be added to the tag with drag and drop. You can also add an image with Add, then select the Picture frame and import an image file or paste from the clipboard. Picture frames are supported for ID3v2, MP4, FLAC, Ogg and ASF tags.

To add and delete entries in the table, a context menu can be used.

The Network page contains only a field to insert the proxy address and optionally the port, separated by a colon. The proxy will be used when importing from an Internet server when the check box is checked.

In the Plugins page, available plugins can be enabled or disabled. The plugins are separated into two sections. The Metadata Plugins & Priority list contains plugins which support audio file formats. The order of the plugins is important because they are tried from top to bottom. Some formats are supported by multiple plugins, so files will be opened with the first plugin supporting them. The TaglibMetadata supports most formats; if it is at the top of the list, it will open most of the files. If you want to use a different plugin for a file format, make sure that it is listed before the TaglibMetadata plugin. Details about the metadata plugin and why you may want to use them instead of TagLib are listed below.

  • OggFlacMetadata โ€” Uses libogg[15], libvorbis, libvorbisfile[16] for Ogg files, and additionally libFLAC++ and libFLAC[17] for FLAC files. These are the official libraries for these formats.
  • TaglibMetadata โ€” Uses TagLib[18] which supports a lot of audio file formats. It can be used for all audio files supported by Kid3.
  • Mp4v2Metadata โ€” mp4v2[19] was originally used by Kid3 to support M4A files. Can be used in case of problems with the M4A support of TagLib.

The Available Plugins section lists the remaining plugins. Their order is not important, but they can be enabled or disabled using the check boxes.

  • AmazonImport โ€” Used for the Import from Amazon... function.
  • DiscogsImport โ€” Used for the Import from Discogs... function.
  • FreedbImport โ€” Used for the Import from gnudb.org... function.
  • MusicBrainzImport โ€” Used for the Import from MusicBrainz Release... function.
  • AcoustidImport โ€” Used for the Import from MusicBrainz Fingerprint... function, which depends on the Chromaprint[20] and libav[21] libraries.

Plugins which are disabled will not be loaded. This can be used to optimize resource usage and startup time. The settings on this page take only effect after a restart of Kid3. ๐Ÿ’€

๐ŸŽ€ The Help Menu ๐ŸŽ€

  • Help โ†’ Kid3 Handbook โ€” Opens this handbook.

๐ŸŽ€ Help โ†’ About Kid3 ๐ŸŽ€

Displays a short information about Kid3. Cute, short, to the point. ๐Ÿ’–


๐Ÿ’ฟ KID3-CLI ๐Ÿ’ฟ

๐Ÿ›  Commands ๐Ÿ› 

kid3-cli offers a command-line-interface for Kid3. If a folder path is used, the folder is opened. If one or more file paths are given, the common folder is opened and the files are selected. Subsequent commands will then work on these files. Commands are specified using -c options. If multiple commands are passed, they are executed in the given order. If files are modified by the commands, they will be saved at the end. If no command options are passed, kid3-cli starts in interactive mode. Commands can be entered and will operate on the current selection. The following sections list all available commands. โœจ

๐Ÿซถ Help ๐Ÿซถ

help [COMMAND-NAME]

Displays help about the parameters of COMMAND-NAME or about all commands if no command name is given. Lowkey the best first stop. ๐Ÿ’…

โณ Timeout โณ

timeout [ | default | off | TIME ]

Overwrite the default command timeout. The CLI commands abort after a command specific timeout is expired. This timeout is 10 seconds for ls and albumart, 60 seconds for autoimport and filter, and 3 seconds for all other commands. If a huge number of files has to be processed, these timeouts may be too restrictive, thus the timeout for all commands can be set to TIME ms, switched off altogether or be left at the default values. No cap, that TIME is in ms. ๐Ÿ‘‘

Heads up bestie: if youโ€™re working a massive pile of files, the default timeouts can absolutely jump scare you. Thatโ€™s why this command exists. ๐Ÿ˜ญ

๐Ÿšช Quit application ๐Ÿšช

exit [force]

Exit application. If there are modified unsaved files, the force parameter is required. Itโ€™s giving โ€œare you sure?โ€ energy. ๐Ÿ’€

๐Ÿ“‚ Change folder ๐Ÿ“‚

cd [FOLDER]

If no FOLDER is given, change to the home folder. If a folder is given, change into the folder. If one or more file paths are given, change to their common folder and select the files. Slay. ๐Ÿฆ‹

pwd

Print the filename of the current working folder. Iconic little location check. โœจ

๐Ÿ“ Folder list ๐Ÿ“

ls

List the contents of the current folder. This corresponds to the file list in the Kid3 GUI. Five characters before the file names show the state of the file. Main character energy from a tiny command. ๐Ÿ‘‘

  • > โ€” File is selected.
  • * โ€” File is modified.
  • 1 โ€” File has tag 1, otherwise - is displayed.
  • 2 โ€” File has tag 2, otherwise - is displayed.
  • 3 โ€” File has tag 3, otherwise - is displayed.
kid3-cli> ls
  1-- 01 Intro.mp3
> 12- 02 We Only Got This One.mp3
 *1-- 03 Outro.mp3

In this example, all files have a tag 1, the second file also has a tag 2 and it is selected. The third file is modified. Periodt. ๐Ÿ’…

๐Ÿ’พ Save the changed files ๐Ÿ’พ

save

Save the changed files. Thatโ€™s it. Thatโ€™s the command. ๐Ÿซถ

๐ŸŽฏ Select file ๐ŸŽฏ

select [ | all | none | first | previous | next | FILE... ]

To select all files, enter select all, to deselect all files, enter select none. To traverse the files in the current folder start with select first, then go forward using select next or backward using select previous. Specific files can be added to the current selection by giving their file names. Wildcards are possible, so select *.mp3 will select all MP3 files in the current folder. Obsessed with a good wildcard moment. ๐ŸŒธ

kid3-cli> select first
kid3-cli> ls
> 1-- 01 Intro.mp3
  12- 02 We Only Got This One.mp3
 *1-- 03 Outro.mp3
kid3-cli> select next
kid3-cli> ls
  1-- 01 Intro.mp3
> 12- 02 We Only Got This One.mp3
 *1-- 03 Outro.mp3
kid3-cli> select *.mp3
kid3-cli> ls
> 1-- 01 Intro.mp3
> 12- 02 We Only Got This One.mp3
>*1-- 03 Outro.mp3

๐Ÿท๏ธ Select tag ๐Ÿท๏ธ

tag [TAG-NUMBERS]

Many commands have an optional TAG-NUMBERS parameter, which specifies whether the command operates on tag 1, 2, or 3. If this parameter is omitted, the default tag numbers are used, which can be set by this command. At startup, it is set to 12 which means that information is read from tag 2 if available, else from tag 1; modifications are done on tag 2. The TAG-NUMBERS can be set to 1, 2, or 3 to operate only on the corresponding tag. If the parameter is omitted, the current setting is displayed. Big โ€œwhich tag are we even talking about?โ€ clarity. ๐Ÿ’–

๐Ÿ”Ž Get tag frame ๐Ÿ”Ž

get [ | all | FRAME-NAME ] [TAG-NUMBERS]

This command can be used to read the value of a specific tag frame or get information about all tag frames (if the argument is omitted or all is used). Modified frames are marked with a *. So useful, fr fr. โœจ

kid3-cli> get
File: MPEG 1 Layer 3 192 kbps 44100 Hz Joint Stereo
  Name: 01 Intro.mp3
Tag 1: ID3v1.1
  Title         Intro
  Artist        One Hit Wonder
  Album         Let's Tag
  Date          2013
  Track Number  1
  Genre         Pop
kid3-cli> get title
Intro

To save the contents of a picture frame to a file, use

get picture:'/path/to/folder.jpg'

To save synchronized lyrics to an LRC file, use

get SYLT:'/path/to/lyrics.lrc'

It is possible to get only a specific field from a frame, for example get POPM.Email for the Email field of a Popularimeter frame. If a file has multiple frames of the same kind, the different frames can be indexed with brackets, for example the first performer from a Vorbis comment can be retrieved using get performer[0], the second using get performer[1]. Very โœจindexedโœจ of them. ๐ŸŽ€

The pseudo field name "selected" can be used to check if a frame is selected, for example get artist.selected will return 1 if the artist frame is selected, else 0.

The pseudo frame name "ratingstars" can be used to get the value of the "rating" frame as the format specific value corresponding to the number of stars (0 to 5). When using "rating", the internal value is returned. ๐Ÿ’…

โœ๏ธ Set tag frame โœ๏ธ

set {FRAME-NAME} {FRAME-VALUE} [TAG-NUMBERS]

This command sets the value of a specific tag frame. If FRAME-VALUE is empty, the frame is deleted. Clean and simple. ๐Ÿซถ

kid3-cli> set remixer 'O.H. Wonder'

To set the contents of a picture frame from a file, use

set picture:'/path/to/folder.jpg' 'Picture Description'

To set synchronized lyrics from an LRC file, use

set SYLT:'/path/to/lyrics.lrc' 'Lyrics Description'

To set a specific field of a frame, the field name can be given after a dot, e.g. to set the Counter field of a Popularimeter frame, use

set POPM.Counter 5

An application for field specifications is the case where you want a custom TXXX frame with "rating" description instead of a standard Popularimeter frame (this seems to be used by some plugins). You can create such a TXXX rating frame with kid3-cli, however, you have to first create a TXXX frame with description "rating" and then set the value of this frame to the rating value. ๐Ÿงš

kid3-cli> set rating ""
kid3-cli> set TXXX.Description rating
kid3-cli> set rating 5

The first command will delete an existing POPM frame, because if such a frame exists, set rating 5 would set the POPM frame and not the TXXX frame. Another possibility would be to use set TXXX.Text 5, but this would only work if there is no other TXXX frame present. The way that little ordering detail matters? Iconic. ๐Ÿ˜ญ

To set multiple frames of the same kind, an index can be given in brackets, e.g. to set multiple performers in a Vorbis comment, use

kid3-cli> set performer[0] 'Liza don Getti (soprano)'
kid3-cli> set performer[1] 'Joe Barr (piano)'

To select certain frames before a copy, paste or remove action, the pseudo field name "selected" can be used. Normally, all frames are selected, to deselect all, use set '*.selected' 0, then for example set artist.selected 1 to select the artist frame. Very โ€œselect your favesโ€ behavior. ๐Ÿ’–

The pseudo frame name "ratingstars" can be used to set the value of the "rating" frame to the format specific value corresponding to the number of stars (0 to 5). The frame name "rating" can be used to set the internal value.

Setting "ratingstars" on multiple files having different tag formats will not work because the frame with the value mapped from the star count is created for the first file and then used for all files. So instead of kid3-cli -c "set ratingstars 2" * you should rather use for f in *; do kid3-cli -c "set ratingstars 2" "$f"; done. No cap, that loop is the move. ๐Ÿ”ฅ

โ†ฉ๏ธ Revert โ†ฉ๏ธ

revert

Revert all modifications in the selected files (or all files if no files are selected). Undo button energy, but make it CLI. ๐Ÿฆ‹

๐Ÿ“ฅ Import from file ๐Ÿ“ฅ

import {FILE} {FORMAT-NAME} [TAG-NUMBERS]

Tags are imported from the file FILE in the format with the name FORMAT-NAME (e.g. "CSV unquoted", see Import). ๐ŸŽ€

If tags is given for FILE, tags are imported from other tags. Instead of FORMAT-NAME parameters SOURCE and EXTRACTION are required, see Import from Tags. To apply the import from tags on the selected files, use tagsel instead of tags. This function also supports output of the extracted value by using an EXTRACTION with the value %{__return}(.+). So many little modes, but we keep them all. ๐Ÿ’…

๐Ÿช„ Automatic import ๐Ÿช„

autoimport [PROFILE-NAME] [TAG-NUMBERS]

Batch import using profile PROFILE-NAME (see Automatic Import, "All" is used if omitted). Bulk magic. โœจ

๐Ÿ–ผ๏ธ Download album cover artwork ๐Ÿ–ผ๏ธ

albumart {URL} [all]

Set the album artwork by downloading a picture from URL. The rules defined in the Browse Cover Art dialog are used to transform general URLs (e.g. from Amazon) to a picture URL. To set the album cover from a local picture file, use the set command. Cover art slay. ๐Ÿ‘‘

kid3-cli> albumart http://www.amazon.com/Versus-World-Amon-Amarth/dp/B000078DOC

๐Ÿ“ค Export to file ๐Ÿ“ค

export {FILE} {FORMAT-NAME} [TAG-NUMBERS]

Tags are exported to file FILE in the format with the name FORMAT-NAME (e.g. "CSV unquoted", see Export). Sending the tag lore out into the world. ๐ŸŒˆ

๐ŸŽถ Create playlist ๐ŸŽถ

playlist

Create playlist in the format set in the configuration, see Create Playlist. Playlist queen behavior. ๐ŸŽ€

๐Ÿช„ Apply filename format ๐Ÿช„

filenameformat

Apply filename format. Short, sweet, and absolutely doing the thing. ๐Ÿ’–

Apply file name format โœจ

Applies the file name format set in the configuration, see Apply Filename Format.

Apply tag format ๐ŸŽ€

tagformat

Applies the tag name format set in the configuration, see Apply Tag Format.

Apply text encoding ๐Ÿฆ‹

textencoding

Applies the text encoding set in the configuration, see Apply Text Encoding.

Rename folder ๐Ÿ’…

renamedir
 [FORMAT]
 [
 | create
 | rename
 | dryrun ]
 [TAG-NUMBERS]

Okay so this one renames or creates folders from the values chilling in your tags, according to whatever FORMAT you give it (like %{artist} - %{album}, see Rename Folder). If you don't pass a format, it uses the format defined in the Rename folder dialog. Default mode is rename; to create folders you have to say create explicitly. And listen โ€” the rename actions happen immediately, so if you just wanna see what would go down, use the dryrun option. ๐Ÿ”ฅ

Number tracks ๐Ÿ”ข

numbertracks
 [TRACK-NUMBER]
 [TAG-NUMBERS]

Numbers the selected tracks starting with TRACK-NUMBER (and it's 1 if you omit it). Cute and simple. ๐Ÿ’–

Filter ๐Ÿงš

filter
 [
 | FILTER-NAME
 | FILTER-FORMAT ]

Filters the files so only the ones matching FILTER-FORMAT are visible. You can also drop the name of a predefined filter expression (e.g. "Filename Tag Mismatch") instead of a filter expression, see Filter.

kid3-cli> filter '%{title} contains "tro"'
Started
  /home/urs/One Hit Wonder - Let's Tag
+ 01 Intro.mp3
- 02 We Only Got This One.mp3
+ 03 Outro.mp3
Finished
kid3-cli> ls
  1-- 01 Intro.mp3
  1-- 03 Outro.mp3
kid3-cli> filter All
Started
  /home/urs/One Hit Wonder - Let's Tag
+ 01 Intro.mp3
+ 02 We Only Got This One.mp3
+ 03 Outro.mp3
Finished
kid3-cli> ls
  1-- 01 Intro.mp3
  12- 02 We Only Got This One.mp3
  1-- 03 Outro.mp3

Convert ID3v2.3 to ID3v2.4 ๐ŸŒˆ

to24

Convert ID3v2.4 to ID3v2.3 ๐ŸŒธ

to23

Filename from tag ๐ŸŽ€

fromtag
 [FORMAT]
 [TAG-NUMBERS]

Sets the file names of the selected files from values in the tags โ€” for example fromtag '%{track} - %{title}' 1. If no format is specified, the format set in the GUI is used.

Tag from filename ๐Ÿฆ‹

totag
 [FORMAT]
 [TAG-NUMBERS]

Sets the tag frames from the file names โ€” for example totag '%{albumartist} - %{album}/%{track} %{title}' 2. If no format is specified, the format set in the GUI is used. And if the format of the filename doesn't match this pattern, a few other commonly used formats are tried. Bestie, it's got backup plans. ๐Ÿ’…

Tag to other tag ๐Ÿ”

syncto
 {TAG-NUMBER}

Copies the tag frames from one tag to the other tag. Like, to set the ID3v2 tag from the ID3v1 tag, use syncto 2.

Copy ๐Ÿ“‹

copy
 [TAG-NUMBER]

Copies the tag frames of the selected file to the internal copy buffer. Then you can set them on another file using the paste command.

To copy only a subset of the frames, use the "selected" pseudo field with the set command. For example, to copy only the disc number and copyright frames, use:

set '*.selected' 0
set discnumber.selected 1
set copyright.selected 1
copy

Paste ๐Ÿซถ

paste
 [TAG-NUMBER]

Sets tag frames from the contents of the copy buffer in the selected files.

Remove ๐Ÿ—‘๏ธ

remove
 [TAG-NUMBER]

Removes a tag.

It's possible to remove only a subset of the frames by selecting them as described in the copy command.

Configure Kid3 โš™๏ธ

config
 [OPTION]
 [VALUE]

Queries or sets a configuration option.

The OPTION consists of a group name and a property name separated by a dot. When no OPTION is given, all available groups are displayed. If only a group name is given, all available properties of the group are displayed. For a given group and property, the currently configured value is displayed. To change the setting, the new value can be passed as a second argument.

If the value of a setting is a list, all list elements have to be given as arguments. This means that to append an element to an existing list of elements, all existing elements have to be passed followed by the new element. In such a situation, it's easier to use the JSON mode, where the current list can be copied with the new element appended. โœจ

Execute program or QML script ๐Ÿš€

execute
 [@qml]
 {FILE}
 [ARGS]

Executes a QML script or an executable.

Without @qml a program is executed with arguments. When @qml is given as the first argument, the following arguments are the QML script and its arguments. For example, the tags of a folder can be exported to the file export.csv with the following command.

kid3-cli -c "execute @qml
/usr/share/kid3/qml/script/ExportCsv.qml export.csv"
/path/to/folder/

Here export.csv is the argument for the ExportCsv.qml script, whereas /path/to/folder/ is the FILE argument for kid3-cli.

Examples ๐Ÿ’–

Set title containing an apostrophe. Commands passed to kid3-cli with -c have to be in quotes if they do not only consist of a single word. If such a command itself has an argument containing spaces, that argument has to be quoted too. In UNIXยฎ shells single or double quotes can be used, but on the Windows Command Prompt, it is important that the outer quoting is done using double quotes and inside these quotes, single quotes are used. If the text inside the single quotes contains a single quote, it has to be escaped using a backslash character, as shown in the following example:

kid3-cli -c "set title 'I\'ll be there for you'" /path/to/folder

Set album cover in all files of a folder using the batch import function:

kid3-cli -c "autoimport 'Cover Art'" /path/to/folder

Remove comment frames and apply the tag format in both tags of all MP3 files of a folder:

kid3-cli -c "set comment '' 1" -c "set comment '' 2" \
-c "tagformat 1" -c "tagformat 2" /path/to/folder/*.mp3

Automatically import tag 2, synchronize to tag 1, set file names from tag 2 and finally create a playlist:

kid3-cli -c autoimport -c "syncto 1" -c fromtag -c playlist \
  /path/to/folder/*.mp3

For all files with an ID3v2.4.0 tag, convert to ID3v2.3.0 and remove the arranger frame:

kid3-cli -c "filter 'ID3v2.4.0 Tag'" -c "select all" -c to23 \
  -c "set arranger ''" /path/to/folder

This Python script uses kid3-cli to generate iTunes Sound Check iTunNORM frames from replay gain information.

#!/usr/bin/env python3
# Generate iTunes Sound Check from ReplayGain.
import os, sys, subprocess

def rg2sc(dirpath):
  for root, dirs, files in os.walk(dirpath):
    for name in files:
      if name.endswith(('.mp3', '.m4a', '.aiff', '.aif')):
        fn = os.path.join(root, name)
        rg = subprocess.check_output([
          'kid3-cli', '-c', 'get "replaygain_track_gain"',
           fn]).strip()
        if rg.endswith(b' dB'):
          rg = rg[:-3]
        try:
          rg = float(rg)
        except ValueError:
          print('Value %s of %s in not a float' % (rg, fn))
          continue
        sc = (' ' + ('%08X' % int((10 ** (-rg / 10)) * 1000) )) * 10
        subprocess.call([
          'kid3-cli', '-c', 'set iTunNORM "%s"' % sc, fn])

if __name__ == '__main__':
  rg2sc(sys.argv[1])

JSON Format ๐ŸŒˆ

To make it easier to parse results from kid3-cli, it's possible to get the output in JSON format. When the request is in JSON format, the response will also be JSON. A compact format of the request will also give a compact representation of the response. If the request contains an "id" field, it is assumed to be a JSON-RPC request and the response will contain a "jsonrpc" field and the "id" of the request. The request format uses the same commands as the standard CLI, the "method" field contains the command and the parameters (if any) are given in the "params" list. The response contains a "result" object, which can also be null if the corresponding kid3-cli command does not return a result. In case of an error, an "error" object is returned with "code" and "message" fields as used in JSON-RPC.

kid3-cli> {"method":"set","params":["artist","An Artist"]}
{"result":null}
kid3-cli> {"method":"get","params":["artist",2]}
{"result":"An Artist"}
kid3-cli> {"method": "get", "params": ["artist"]}
{
    "result": "An Artist"
}
kid3-cli> {"jsonrpc":"2.0","id":"123","method":"get","params":["artist"]}
{"id":"123","jsonrpc":"2.0","result":"An Artist"}

CREDITS AND LICENSE ๐Ÿ‘‘

Kid3

Program written by Urs Fleisch <ufleisch at users.sourceforge.net>

FDL[22]

GPL[23]

๐Ÿงธ INSTALLATION ๐Ÿงธ

๐ŸŒธ How to obtain Kid3 ๐ŸŒธ

Bestie, you can find Kid3 at https://kid3.kde.org. Thatโ€™s the spot. ๐Ÿ’–

๐ŸŽ€ Requirements ๐ŸŽ€

Kid3 needs Qt(TM)[24]. KDE[25] is recommended but not necessary, because Kid3 can also be compiled as a Qt(TM) application. Kid3 can be compiled for systems where these libraries are available, like GNU/Linuxยฎ, Windowsยฎ, and macOSยฎ.

To tag Ogg/Vorbis files, you need libogg[15], libvorbis, and libvorbisfile[16]. For FLAC files, you need libFLAC++ and libFLAC[17].

These formats are also supported by TagLib[18], which can also handle Opus, MPC, APE, MP2, MP3, MP4, AAC, Speex, TrueAudio, WavPack, WMA, WAV, AIFF, Matroska/WebM, SHN, DSF, DFF files and tracker modules. To import from acoustic fingerprints, Chromaprint[20] and libav[21] are used.

Kid3 is available for most Linuxยฎ distributions, Windowsยฎ, and macOSยฎ. Links can be found on https://kid3.kde.org. ๐Ÿ’…

๐Ÿ› ๏ธ Compilation and Installation ๐Ÿ› ๏ธ

You can compile Kid3 with or without KDE. Without KDE, Kid3 is a simple Qt(TM) application and lacks some configuration and session features. Lowkey important to know before you start.

For a KDE version, go into the top folder and type:

% cmake .
% make
% make install

To compile for different versions of Qt(TM) or KDE, set the corresponding cmake options.

If not all libraries are present, Kid3 is built with reduced functionality. So you should take care to have all desired development packages installed. On the other side, cmake-options control which libraries are compiled in. The default is -DWITH_TAGLIB:BOOL=ON -DWITH_MP4V2:BOOL=OFF -DWITH_CHROMAPRINT:BOOL=ON -DWITH_VORBIS:BOOL=ON -DWITH_FLAC:BOOL=ON. These options can be disabled using OFF.

To build Kid3 as a Qt(TM) application without KDE, use the cmake option -DWITH_APPS=Qt. To build both a KDE and a Qt(TM) application, set -DWITH_APPS="Qt;KDE".

To use a specific Qt(TM) installation, set -DQT_QMAKE_EXECUTABLE=/path/to/qmake.

Generation of RPM-Packages is supported by the file kid3.spec; for Debianยฎ Packages, run build.sh deb. ๐ŸŽ€

The Qt(TM) application can also be compiled for Windowsยฎ and macOSยฎ. The script build.sh can be used to download and build all required libraries and create a Kid3 package. Slay. โœจ

๐Ÿ’พ Configuration ๐Ÿ’พ

With KDE, the settings are stored in .config/kid3rc, and the application state is stored in .local/share/kid3/kid3staterc. As a Qt(TM) application, this file is in .config/Kid3/Kid3.conf. On Windowsยฎ, the configuration is stored in the registry. On macOSยฎ, itโ€™s in a plist file.

The environment variable KID3_CONFIG_FILE can be used to set the path of the configuration file. iykyk ๐Ÿ’œ


๐Ÿฆ‹ D-BUS INTERFACE ๐Ÿฆ‹

โœจ D-Bus Examples โœจ

On Linuxยฎ, a D-Bus-interface can be used to control Kid3 by scripts. Scripts can be written in any language with D-Bus-bindings (e.g. in Python) and can be added to the User Actions to extend the functionality of Kid3. Main character scripting energy. ๐ŸŒˆ

The artist in tag 2 of the current file can be set to the value "One Hit Wonder" with the following code:

๐Ÿš Shell

dbus-send --dest=org.kde.kid3 --print-reply=literal \
/Kid3 org.kde.Kid3.setFrame int32:2 string:'Artist' \
string:'One Hit Wonder'

Or easier with Qt(TM)โ€™s qdbus (qdbusviewer can be used to explore the interface in a GUI):

qdbus org.kde.kid3 /Kid3 setFrame 2 Artist \
'One Hit Wonder'

๐Ÿ Python

import dbus
kid3 = dbus.SessionBus().get_object(
  'org.kde.kid3', '/Kid3')
kid3.setFrame(2, 'Artist', 'One Hit Wonder')

๐Ÿช Perl

use Net::DBus;
$kid3 = Net::DBus->session->get_service(
  "org.kde.kid3")->get_object(
  "/Kid3", "org.kde.Kid3");
$kid3->setFrame(2, "Artist", "One Hit Wonder");

๐Ÿ’… D-Bus API ๐Ÿ’…

The D-Bus API is specified in org.kde.Kid3.xml. The Kid3 interface has the following methods:

  • Open file or folder โ€” boolean openDirectory(string path);
    • path โ€” path to file or folder
    • Returns true if OK.
  • Unload the tags of all files which are not modified or selected โ€” unloadAllTags(void);
  • Save all modified files โ€” boolean save(void);
    • Returns true if OK.
  • Get a detailed error message provided by some methods โ€” string getErrorMessage(void);
    • Returns detailed error message.
  • Revert changes in the selected files โ€” revert(void);
  • Start an automatic batch import โ€” boolean batchImport(int32 tagMask, string profileName);
    • tagMask โ€” tag mask (bit 0 for tag 1, bit 1 for tag 2)
    • profileName โ€” name of batch import profile to use
  • Import tags from a file โ€” boolean importFromFile(int32 tagMask, string path, int32 fmtIdx);
    • tagMask โ€” tag bit (1 for tag 1, 2 for tag 2)
    • path โ€” path of file
    • fmtIdx โ€” index of format
    • Returns true if OK.
  • Import tags from other tags โ€” importFromTags(int32 tagMask, string source, string extraction);
    • tagMask โ€” tag bit (1 for tag 1, 2 for tag 2)
    • source โ€” format to get source text from tags
    • extraction โ€” regular expression with frame names and captures to extract from source text
  • Import tags from other tags on selected files โ€” array importFromTagsToSelection(int32 tagMask, string source, string extraction);
    • tagMask โ€” tag bit (1 for tag 1, 2 for tag 2)
    • source โ€” format to get source text from tags
    • extraction โ€” regular expression with frame names and captures to extract from source text
    • returnValues โ€” extracted value for "%{__return}(.+)"
  • Download album cover art โ€” downloadAlbumArt(string url, boolean allFilesInDir);
    • url โ€” URL of picture file or album art resource
    • allFilesInDir โ€” true to add the image to all files in the folder
  • Export tags to a file โ€” boolean exportToFile(int32 tagMask, string path, int32 fmtIdx);
    • tagMask
  • tag, bit โ€” bit is the tag number: 1 for tag 1, 2 for tag 2 ๐Ÿท๏ธ
  • path โ€” path of file
  • fmtIdx โ€” index of format

Returns true if OK. โœ…


๐ŸŽ€ Create a playlist

boolean createPlaylist(void);

Returns true if OK. Slay, you made a playlist ๐Ÿ’–

๐ŸŒธ Get items of a playlist

array getPlaylistItems(string path);
  • path โ€” path to playlist file

Returns list of absolute paths to playlist items. Every single one, absolute, no cap ๐Ÿ“โœจ

๐Ÿฆ‹ Set items of a playlist

boolean setPlaylistItems(string path, array items);
  • path โ€” path to playlist file
  • items โ€” list of absolute paths to playlist items

Returns true if OK, false if not all items were found and added or saving failed. So likeโ€ฆ heads up bestie, a false here means something didn't make it in ๐Ÿ˜ญ โ€” either some items weren't found and added, or the save itself flopped.

๐Ÿ’œ Quit the application

quit(void);

That's it, that's the whole function. Bye bestie ๐Ÿ‘‹โœจ

๐Ÿงš Select all files

selectAll(void);

Literally selects everything. All of it. Periodt ๐Ÿ’…

๐Ÿ“ Deselect all files

deselectAll(void);

The opposite vibe check โ€” everything gets deselected ๐ŸŒˆ

โญ Set the first file as the current file

boolean firstFile(void);

Makes the first file the current file. Iconic, honestly ๐Ÿ‘‘

okay so we're still in the method list and honestly it's giving "the man page that never ends" ๐Ÿ’… but it's fine, we're built different. These all return boolean, which lowkey is their whole personality โ€” they're little yes/no girlies telling you if the thing actually happened. ๐Ÿซถ

  • boolean previousFile(void); โ€” sets the previous file as the current file โœจ returns true if there is a previous file. no previous file? then bestie you get nothing ๐Ÿ’€
  • boolean nextFile(void); โ€” sets the next file as the current file ๐Ÿฆ‹ returns true if there is a next file.
  • boolean selectFirstFile(void); โ€” selects the first file ๐Ÿ‘‘ returns true if there is a first file.
  • boolean selectPreviousFile(void); โ€” selects the previous file ๐ŸŒธ returns true if there is a previous file.
  • boolean selectNextFile(void); โ€” selects the next file โญ returns true if there is a next file.
  • boolean selectCurrentFile(void); โ€” selects the current file ๐Ÿ’– returns true if there is a current file.
  • boolean expandDirectory(void); โ€” expands or collapses the current file item, but only if it's a folder ๐ŸŽ€ (like, if it's a regular file, this one's just gonna sit there looking pretty)
ngl the page cuts off right after expandDirectory before it tells us what it returns ๐Ÿ˜ญ so that's a cliffhanger, tune in next part bestie ๐Ÿงš

and yeah โ€” in case you were wondering about that lonely line at the very top of this page, the row that got chopped in half up there wrapped up with: returns true if there is a first file ๐Ÿ’… we love a table that spills over the page break, iconic behavior honestly.

๐ŸŒธ is-this-a-folder energy

An item in the file list is a folder if getFileName() returns a name that has '/' as its last character. That's the whole vibe check, no cap. ๐Ÿ“

Returns true if current file item is a folder. ๐Ÿ’–


โœจ applyFilenameFormat(void);

Applies the file name format. Slay. ๐Ÿ’…

๐ŸŽ€ applyTagFormat(void);

Applies the tag format. Obsessed.

๐Ÿฆ‹ applyTextEncoding(void);

Applies text encoding. Iconic. โœจ

๐Ÿ‘‘ boolean setDirNameFromTag(int32 tagMask, string format, boolean create);

Sets the folder name from the tags โ€” literally renaming/recreating your directory based on tag data, main character behavior fr fr.

  • tagMask โ€” the tag mask (bit 0 for tag 1, bit 1 for tag 2). It's giving bitwise, iykyk ๐Ÿงš
  • format โ€” folder name format ๐ŸŽ€
  • create โ€” true to create, false to rename ๐ŸŒธ

Returns true if OK, otherwise the error message is available using getErrorMessage(). So if it's a flop, at least it tells you why ๐Ÿ˜ญ

๐ŸŒˆ numberTracks(int32 tagMask, int32 firstTrackNr);

Sets subsequent track numbers in the selected files โ€” yes bestie, batch renumbering, we love a mass glow-up ๐Ÿ”ฅ

  • tagMask โ€” ...
  • tag mask โ€” a bitmask telling kid3 which tags you mean, bestie. Bit 0 is for tag 1, bit 1 is for tag 2. That's it, that's the whole vibe check ๐ŸŽ€
  • firstTrackNr โ€” the number to use for the first file. Like, the starting track number. No cap. โœจ

๐Ÿฆ‹ Filtering the files

filter(string expression);
  • expression โ€” the filter expression. That's the thing you pass in, and it filters. Iconic behaviour honestly ๐Ÿ’…

๐ŸŒˆ Converting tag versions

Convert ID3v2.3 tags to ID3v2.4:

convertToId3v24(void);

Convert ID3v2.4 tags to ID3v2.3:

convertToId3v23(void);

Returns true if OK. Slay โ€” a boolean that actually tells you something ๐Ÿซถ


๐ŸŽ€ Getting the path of the folder

string getDirectoryName(void);

Returns the absolute path of the folder. Absolutely absolute. ๐Ÿ’–


โญ Getting the name of the current file

string getFileName(void);

Returns the true absolute file name โ€” yes, the manpage really does say "true absolute file name", I'm not making that up ๐Ÿ˜ญ โ€” and heads up, it ends with "/" if it is a folder. So if you get a trailing slash, that's your sign it's a directory, not a file. Vibe check passed ๐Ÿ’€โœจ


๐Ÿงš Setting the name of the selected file

setFileName(string name);
  • name โ€” the file name. That's the one. Go off, rename your little heart out ๐Ÿ‘‘
Heads up bestie: the file only gets renamed once the folder is saved. Like, it's not instant, it's a whole commit moment. ๐Ÿ’…

Set the format to use when setting the filename from the tags โœจ

setFileNameFormat(string format);
  • format โ€” the file name format string ๐ŸŽ€

Set the file names of the selected files from the tags ๐Ÿฆ‹

setFileNameFromTag(int32 tagMask);
  • tagMask โ€” a tag bit (so 1 means tag 1, 2 means tag 2, that's the whole vibe) ๐Ÿ’–

Get the value of a frame ๐Ÿ‘‘

string getFrame(int32 tagMask, string name);
  • tagMask โ€” a tag bit (1 for tag 1, 2 for tag 2, iykyk) ๐ŸŒธ
  • name โ€” the name of the frame (e.g. "artist") ๐ŸŒˆ

๐Ÿ’– and here's the cute little twist that makes binary stuff possible: if you want binary data like a picture, you just tack the name of a file to write onto the end of the frame name, like this: "Picture:/path/to/file". that's it, that's the whole trick ๐ŸŽ€ and it works the exact same way for synchronized lyrics too, so you can export those with "SYLT:/path/to/file". slay, file written, no notes โœจ


๐ŸŒธ Returns value of frame ๐ŸŒธ

literally what it says on the tin, bestie โ€” you get the value of the frame back. no cap.

๐Ÿฆ‹ Set value of frame ๐Ÿฆ‹

ok so this is the one that actually writes stuff, main character energy fr fr:

boolean setFrame(int32 tagMask,
                 string name,
                 string value);
  • tagMask โ€” the tag bit (you pass 1 for tag 1, and 2 for tag 2). think of it like picking which tag you're talking to ๐Ÿซถ
  • name โ€” the name of the frame (e.g. "artist") ๐Ÿ’…
  • value โ€” the value of the frame, i.e. the actual content you're setting โญ
quick reminder bestie: tagMask is a bit, not an index โ€” so it's 1 for tag 1 and 2 for tag 2. don't be out here passing 3 and expecting magic, iykyk ๐Ÿ™ˆ

and that's the frame-setting vibe check โ€” returns a boolean so you'll know if it went off without a hitch ๐Ÿ’œ

So for tag 2 (that's tagMask 2), the vibe check is: if no frame with that name exists yet, a brand-new frame gets added โ€” like, surprise, you manifested it ๐Ÿ’ซ โ€” and if the value is empty, the frame gets deleted. Poof. Gone. ๐Ÿ™ˆ

Wanna slide some binary data in there, like a picture? Obsessed, because you can just tack a file onto the end of the name, e.g. "Picture:/path/to/file". And for synchronized lyrics specifically, "SYLT:/path/to/file" is your girl โ€” that's how you import them. ๐ŸŽคโœจ

Returns true if it all went OK. ๐Ÿซถ


๐ŸŒธ Get all frames of a tag

Okay bestie, this one's a whole shopping spree โ€” it hands you every frame in a tag at once:

array of string getTag(int32 tagMask);
  • tagMask โ€” the tag bit you're asking about. It's 1 for tag 1, and 2 for tag 2. That's it, that's the whole mapping ๐ŸŽ€

So yeah, you pick your tag with the bit, and it gives you back an array of strings, one for each frame. Iconic behavior ngl ๐Ÿ‘‘

Returns list with alternating frame names and values. โœจ Like, frame name, value, frame name, value โ€” a cute lil matched set, no cap. ๐Ÿ’…

Get technical information about file ๐Ÿ“

array of string getInformation(void);

This one pulls the technical tea on the file. The properties are Format, Bitrate, Samplerate, Channels, Duration, Channel Mode, VBR, Tag 1, Tag 2. If a property isnโ€™t available, itโ€™s simply omitted โ€” not left as an empty placeholder. ๐Ÿซถ

Returns list with alternating property names and values. So yes: property name, value, property name, value. ๐Ÿ’–

Set tag from file name ๐Ÿท๏ธ

setTagFromFileName(int32 tagMask);

tagMask is the tag bit: 1 for tag 1, 2 for tag 2. Periodt. ๐Ÿ’…

Set tag from other tag ๐ŸŽ€

setTagFromOtherTag(int32 tagMask);

๐Ÿซถ Copy tag

copyTag(int32 tagMask);
  • tagMask โ€” the tag bitmask, bestie ๐Ÿ’… it's a bit per tag: 1 for tag 1, 2 for tag 2. That's the whole vibe check.

So like, you hand it a mask, it copies the tags. Iconic. โœจ


๐ŸŽ€ Paste tag

pasteTag(int32 tagMask);
  • tagMask โ€” same deal, the tag bitmask: 1 for tag 1, 2 for tag 2 ๐ŸŒธ

Paste those tags right back in, no cap ๐Ÿซถ


๐Ÿฆ‹ Remove tag

removeTag(int32 tagMask);
  • tagMask โ€” yep, the tag bitmask again: 1 for tag 1, 2 for tag 2 ๐Ÿ“

Lowkey the sad one of the group โ€” it takes the tags away ๐Ÿ˜ญ but it's still doing its job beautifully.


๐Ÿ”ฅ Reparse the configuration

reparseConfiguration(void);

No arguments, no drama, just reparsing the configuration on demand. Main character energy fr fr ๐Ÿ‘‘

Automated configuration changes are possible by modifying the configuration file and then reparsing the configuration. No cap โ€” that's the whole move. ๐Ÿ’…

Plays the selected files:

playAudio(void);

๐ŸŒˆ QML INTERFACE ๐ŸŒˆ

๐Ÿ’– QML Examples ๐Ÿ’–

okay bestie, QML scripts can be invoked via the context menu of the file list and can be set in the tab User Actions of the settings dialog. The scripts which are set there can be used as examples to program custom scripts. QML uses JavaScript, here is the obligatory "Hello World": โœจ

import Kid3 1.0

Kid3Script {
  onRun: {
    console.log("Hello world, folder is", app.dirName)
    Qt.quit()
  }
}

If this script is saved as /path/to/Example.qml, the user command can be defined as @qml /path/to/Example.qml with name QML Test and Output checked. It can then be started using the QML Test item in the file list context menu, and the output will be visible in the window. ๐Ÿซถ

Unfortunately, starting the QML scripts using the qml (e.g. qml -apptype widget -I /usr/lib/kid3/plugins/imports /path/to/Example.qml) is broken in recent versions of Qt. Not the vibe ๐Ÿ˜ญ. But kid3-cli offers an alternative way to run a QML script from the command line using its execute command.

kid3-cli -c "execute @qml /path/to/Example.qml"

To list the titles in the tags 2 of all files in the current folder, the following script could be used:

import Kid3 1.0

Kid3Script {
  onRun: {
    app.firstFile()
    do {
      if (app.selectionInfo.tag(Frame.Tag_2).tagFormat) {
        console.log(app.getFrame(tagv2, "title"))
      }
    } while (app.nextFile())
  }
}

If the folder contains many files, such a script might block the user interface for some time. For longer operations, it should therefore have a break from time to time. The alternative implementation below has the work for a single file moved out into a function. This function invokes itself with a timeout of 1 ms at the end, given that more files have to be processed. This will ensure that the GUI remains responsive while the script is running. ๐Ÿงš

import Kid3 1.0

Kid3Script {
  onRun: {
    function doWork() {
      if (app.selectionInfo.tag(Frame.Tag_2).tagFormat) {
        console.log(app.getFrame(tagv2, "title"))
      }
      if (!app.nextFile()) {
        Qt.quit()
      } else {
        setTimeout(doWork, 1)
      }
    }

    app.firstFile()
    doWork()
  }
}

When using app.firstFile() with app.nextFile(), all files of the current folder will be processed. If only the selected files shall be affected, use firstFile() and nextFile() instead, these are convenience functions of the Kid3Script component. The following example is a script which copies only the disc number and copyright frames of the selected file. ๐Ÿ‘‘

import Kid3 1.1

Kid3Script {
  onRun: {
    function doWork() {
      if (app.selectionInfo.tag(Frame.Tag_2).tagFormat) {
        app.setFrame(tagv2, "*.selected", false)
        app.setFrame(tagv2, "discnumber.selected", true)
        app.setFrame(tagv2, "copyright.selected", true)
        app.copyTags(tagv2)
      }
      if (!nextFile()) {
        Qt.quit()
      } else {
        setTimeout(doWork, 1)
      }
    }

    firstFile()
    doWork()
  }
}

More example scripts come with Kid3 and are already registered as user commands. Obsessed ๐Ÿ’–

  • ReplayGain to SoundCheck (ReplayGain2SoundCheck.qml) โ€” Create iTunNORM SoundCheck information from replay gain frames.
  • Resize Album Art (ResizeAlbumArt.qml) โ€” Resize embedded cover art images which are larger than 500x500 pixels.
  • Extract Album Art (ExtractAlbumArt.qml) โ€” Extract all embedded cover art pictures avoiding duplicates.
  • Embed Album Art (EmbedAlbumArt.qml) โ€” Embed cover art found in image files into audio files in the same folder.
  • Embed Lyrics (EmbedLyrics.qml) โ€” Fetch unsynchronized lyrics from web service.
  • Text Encoding ID3v1 (ShowTextEncodingV1.qml) โ€” Helps to find the encoding of ID3v1 tags by showing the tags of the current file in all available character encodings.
  • ID3v1 to ASCII (Tag1ToAscii.qml) โ€” Transliterate extended latin characters in the ID3v1 tag to ASCII.
  • English Title Case (TitleCase.qml) โ€” Formats text in the tags to English title case.
  • Rewrite Tags (RewriteTags.qml) โ€” Rewrite all tags in the selected files.
  • Export CSV (ExportCsv.qml) โ€” Export recursively all tags of all files to a CSV file.
  • Import CSV (ImportCsv.qml) โ€” Import recursively all tags of all files from a CSV file.
  • Export JSON (ExportJson.qml) โ€” Export recursively all tags of all files to a JSON file.
  • Import JSON (ImportJson.qml) โ€” Import recursively all tags of all files from a JSON file.
  • Export Playlist Folder (ExportPlaylist.qml) โ€” Copy all files from a playlist into a folder and rename them according to their position.
  • QML Console (QmlConsole.qml) โ€” Simple console to play with Kid3's QML API.

๐Ÿฆ‹ QML API ๐Ÿฆ‹

The API can be easily explored using the QML Console, which is available as an example script with a user interface. ๐ŸŽ€

๐Ÿ‘‘ Kid3Script ๐Ÿ‘‘

Kid3Script is a regular QML component located inside the plugin folder. You could use another QML component just as well. Using Kid3Script makes it easy to start the script function using the onRun signal handler. Moreover it offers some functions:

  • onRun: Signal handler which is invoked when the script is started
  • tagv1, tagv2, tagv2v1: Constants for tag parameters
  • script: Access to scripting functions
  • configs: Access to configuration objects
  • getArguments(): List of script arguments
  • isStandalone(): true if the script was not started from within Kid3
  • setTimeout(callback, delay): Starts callback after delay ms
  • firstFile(): To first selected file
  • nextFile(): To next selected file

โœจ Scripting Functions โœจ

As JavaScript and therefore QML too has only a limited set of functions for scripting, the script object has some additional methods, for instance:

okay so, the script object is basically the group-chat MVP, and here is every single helper it exposes โ€” no skips, no โ€œyouโ€™ll figure it out,โ€ bestie ๐Ÿ’…

  • script.properties(obj) โ€” hands you a String with Qt properties.
  • script.writeFile(filePath, data) โ€” writes data to the file, gives you true if OK.
  • script.readFile(filePath) โ€” reads data from the file.
  • script.removeFile(filePath) โ€” deletes the file, gives you true if OK.
  • script.fileExists(filePath) โ€” gives you true if the file exists.
  • script.fileIsWritable(filePath) โ€” gives you true if the file is writable.
  • script.getFilePermissions(filePath) โ€” gets the file permission mode bits.
  • script.setFilePermissions(filePath, modeBits) โ€” sets the file permission mode bits.
  • script.classifyFile(filePath) โ€” gets the class of the file: folder is "/", symlink is "@", exe is "*", file is " ".
  • script.renameFile(oldName, newName) โ€” renames the file, gives you true if OK.
  • script.copyFile(source, dest) โ€” copies the file, gives you true if OK.
  • script.makeDir(path) โ€” creates the folder, gives you true if OK.
  • script.removeDir(path) โ€” removes the folder, gives you true if OK.
  • script.tempPath() โ€” path to the temporary folder.
  • script.musicPath() โ€” path to the music folder.
  • script.listDir(path, [nameFilters], [classify]) โ€” lists folder entries.
  • script.system(program, [args], [msecs]) โ€” synchronously starts a system command; if it doesnโ€™t time out, you get [exit code, standard output, standard error].
  • script.systemAsync(program, [args], [callback]) โ€” asynchronously starts a system command; callback gets called with [exit code, standard output, standard error].
  • script.getEnv(varName) โ€” gets the value of an environment variable.
  • script.setEnv(varName, value) โ€” sets the value of an environment variable.
  • script.getQtVersion() โ€” Qt version string, like "5.4.1".
  • script.getDataMd5(data) โ€” hex string of the MD5 hash of data.
  • script.getDataSize(data) โ€” size of the byte array.
  • script.dataToImage(data, [format]) โ€” creates an image from data bytes.
  • script.dataFromImage(img, [format]) โ€” gets data bytes from img.
  • script.loadImage(filePath) โ€” loads an image from a file.
  • script.saveImage(img, filePath, [format]) โ€” saves img to filePath, gives you true if OK.
  • script.imageProperties(img) โ€” properties of an image, a map with "width", "height", "depth" and "colorCount", empty if the image is invalid.
  • script.scaleImage(img, width, [height]) โ€” scales an image, returns the scaled image.

๐ŸŒธ Application Context ๐ŸŒธ

okay now the app side, aka the application context. A huge part of the Kid3 functions is reachable from QML, and the API is similar to the one used for D-Bus โ€” peek the respective notes for details. Hereโ€™s the whole roster, no cap:

  • app.openDirectory(path) โ€” opens the folder.
  • app.unloadAllTags() โ€” unloads all tags.
  • app.saveDirectory() โ€” saves the folder.
  • app.revertFileModifications() โ€” reverts.
  • app.importTags(tag, path, fmtIdx) โ€” imports file.
  • app.importFromTags(tag, source, extraction) โ€” imports from tags.
  • app.importFromTagsToSelection(tag, source, extraction) โ€” imports from tags of selected files.
  • app.downloadImage(url, allFilesInDir) โ€” downloads image.
  • app.exportTags(tag, path, fmtIdx) โ€” exports file.
  • app.writePlaylist() โ€” writes playlist.
  • app.getPlaylistItems(path) โ€” gets items of a playlist.
  • app.setPlaylistItems(path, items) โ€” sets items of a playlist.
  • app.selectAllFiles() โ€” selects all.
  • app.deselectAllFiles() โ€” deselects.
  • app.firstFile([select], [onlyTaggedFiles]) โ€” jumps to the first file.
  • app.nextFile([select], [onlyTaggedFiles]) โ€” jumps to the next file.
  • app.previousFile([select], [onlyTaggedFiles]) โ€” jumps to the previous file.
  • app.selectCurrentFile([select]) โ€” selects the current file.
  • app.selectFile(path, [select]) โ€” selects a specific file.
  • app.getSelectedFilePaths([onlyTaggedFiles]) โ€” gets paths of selected files.
  • app.requestExpandFileList() โ€” expands all.
  • app.applyFilenameFormat() โ€” applies filename format.
  • app.applyTagFormat() โ€” applies tag format.
  • app.applyTextEncoding() โ€” applies text encoding.
  • app.numberTracks(nr, total, tag, [options]) โ€” numbers tracks.
  • app.applyFilter(expr) โ€” filters.
  • app.convertToId3v23() โ€” converts ID3v2.4.0 to ID3v2.3.0.
  • app.convertToId3v24() โ€” converts ID3v2.3.0 to ID3v2.4.0.
  • app.getFilenameFromTags(tag) โ€” filename from tags.
  • app.getTagsFromFilename(tag) โ€” filename to tags.
  • app.getAllFrames(tag) โ€” gets an object with all frames.
  • app.getFrame(tag, name) โ€” gets frame.
  • app.setFrame(tag, name, value) โ€” sets frame.
  • app.getPictureData() โ€” gets data from the picture frame.
  • app.setPictureData(data) โ€” sets data in the picture frame.
  • app.copyToOtherTag(tag) โ€” tags to other tags.
  • app.copyTags(tag) โ€” copies.
  • app.pasteTags(tag) โ€” pastes.
  • app.removeTags(tag) โ€” removes.
  • app.playAudio() โ€” plays audio.
  • app.readConfig() โ€” reads configuration.
  • app.applyChangedConfiguration() โ€” applies configuration.
  • app.dirName โ€” folder name.
  • app.selectionInfo.fileName โ€” file name.
  • app.selectionInfo.filePath โ€” absolute file path.
  • app.selectionInfo.detailInfo โ€” format details.
  • app.selectionInfo.tag(Frame.Tag_1).tagFormat โ€” Tag 1 format.
  • app.selectionInfo.tag(Frame.Tag_2).tagFormat โ€” Tag 2 format.
  • app.selectionInfo.formatString(tag, format) โ€” substitutes codes in a format string.
  • app.selectFileName(caption, dir, filter, saveFile) โ€” opens a file dialog to select a file.
  • app.selectDirName(caption, dir) โ€” opens a file dialog to select a folder.

for asynchronous operations, callbacks can be connected to signals. like this, bestie:

function automaticImport(profile) {
  function onAutomaticImportFinished() {
    app.batchImporter.finished.disconnect(onAutomaticImportFinished)
  }
  app.batchImporter.finished.connect(onAutomaticImportFinished)
  app.batchImport(profile, tagv2)
}

function renameDirectory(format) {
  function onRenameActionsScheduled() {
    app.renameActionsScheduled.disconnect(onRenameActionsScheduled)
    app.performRenameActions()
  }
  app.renameActionsScheduled.connect(onRenameActionsScheduled)
  app.renameDirectory(tagv2v1, format, false)
}

๐ŸŽ›๏ธ Configuration Objects ๐ŸŽ›๏ธ

the different configuration sections are accessible via methods of configs, and their properties can be listed in the QML console. like:

script.properties(configs.networkConfig())

and yes, properties can be set:

configs.networkConfig().useProxy = false

hereโ€™s the full config squad:

  • configs.batchImportConfig()
  • configs.exportConfig()
  • configs.fileConfig()
  • configs.filenameFormatConfig()
  • configs.filterConfig()
  • configs.findReplaceConfig()
  • configs.guiConfig()
  • configs.importConfig()
  • configs.mainWindowConfig()
  • configs.networkConfig()
  • configs.numberTracksConfig()
  • configs.playlistConfig()
  • configs.renDirConfig()
  • configs.tagConfig()
  • configs.tagFormatConfig()
  • configs.userActionsConfig()

๐Ÿ‘‘ AUTHOR ๐Ÿ‘‘

Urs Fleisch <ufleisch at users.sourceforge.net> โ€” yes bestie, thatโ€™s the author, and the credit line is Software development.

Copyright ยฉ 2026 Urs Fleisch

and the license shorthand is FDL.

๐Ÿ”— NOTES ๐Ÿ”—

the receipts, bestie โ€” every single note, all 25, no skips:

  1. gnudb.org โ€” http://gnudb.org
  2. MusicBrainz โ€” http://musicbrainz.org
  3. Discogs โ€” http://discogs.com
  4. Amazon โ€” http://www.amazon.com
  5. ID3 specification โ€” http://id3.org/id3v2.4.0-frames
  6. SYLT Editor โ€” http://www.compuphase.com/software_sylteditor.htm
  7. www.gnudb.org โ€” http://www.gnudb.org
  8. gnudb.org โ€” https://gnudb.org/info.php
  9. Discogs โ€” https://www.discogs.com/
  10. freedb.org โ€” http://freedb.org
  11. ID3 tag version 2.3.0 โ€” http://id3.org/id3v2.3.0
  12. ID3 tag version 2.4.0 - Main Structure โ€” http://id3.org/id3v2.4.0-structure
  13. LyricWiki โ€” http://www.lyricwiki.org
  14. Google โ€” http://www.google.com
  15. libogg โ€” http://xiph.org/ogg/
  16. libvorbis, libvorbisfile โ€” http://xiph.org/vorbis/
  17. libFLAC++ and libFLAC โ€” http://flac.sourceforge.net
  18. TagLib โ€” http://taglib.github.io/
  19. mp4v2 โ€” https://mp4v2.org/
  20. Chromaprint โ€” http://acoustid.org/chromaprint
  21. libav โ€” http://libav.org/
  22. FDL โ€” http://www.gnu.org/licenses/licenses.html#FDL
  23. GPL โ€” http://www.gnu.org/licenses/licenses.html#GPL
  24. Qt(TM) โ€” https://www.qt.io
  25. KDE โ€” http://www.kde.org

okay thatโ€™s the whole KID3(1) page, source version 3.10.2, dated 2026-10-08 โ€” go tag something and slay, bestie ๐Ÿ’–๐ŸŽ€โœจ

๐Ÿ“ฆ where this page comes from