diff --git a/.gitignore b/.gitignore index 943330c47..704cec1be 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ doc-gen/**/*.map doc-gen/**/*.map coverage/ .nyc_output/ +test/samples/zeroes.flac diff --git a/doc-gen/common.json b/doc-gen/common.json index 28a0927de..6aa000600 100644 --- a/doc-gen/common.json +++ b/doc-gen/common.json @@ -149,6 +149,9 @@ "totaldiscs": { "description": "The total number of discs" }, + "movementTotal": { + "description": "The total number of movements" + }, "compilation": { "description": "Is part of compilation (unofficial iTunes Compilation Flag)" }, @@ -298,5 +301,29 @@ }, "technician": { "description": "Technician who digitized subject" + }, + "category": { + "description": "Podcast Category" + }, + "hdVideo": { + "description": "iTunes Video Quality (2=Full HD, 1=HD, 0=SD)" + }, + "keywords": { + "description": "Podcast Keywords" + }, + "movement": { + "description": "Movement" + }, + "movementIndex": { + "description": "Movement Index/Total, e.g. `{no: 1, of: 4}`" + }, + "podcastId": { + "description": "Podcast Identifier" + }, + "showMovement": { + "description": "Show Movement" + }, + "stik": { + "description": "iTunes Media Type (1=Normal, 2=Audiobook, 6=Music Video, 9=Movie, 10=TV Show, 11=Booklet, 14=Ringtone, https://github.com/sergiomb2/libmp4v2/wiki/iTunesMetadata#user-content-media-type-stik)" } } diff --git a/doc/common_metadata.md b/doc/common_metadata.md index ed9788ae1..9b4214925 100644 --- a/doc/common_metadata.md +++ b/doc/common_metadata.md @@ -3,105 +3,114 @@ Common tags, and _native_ to _common_ tag mappings. _n_ indicates the multiplicity. The tag mapping is strongly inspired on the [MusicBrainz Picard tag-mapping](https://picard.musicbrainz.org/docs/mappings/). -| Common tag | n | Description | ID3v1 | ID3v2.2 | ID3v2.3 | ID3v2.4 | iTunes | vorbis | APEv2 | asf | exif | matroska | -|----------------------------|---|-----------------------------------------------------------------------------------------------------------------------------------------------------------|---------|--------------|-----------------------------------------------------------------------------------|-----------------------------------------------------------------------------------|---------------------------------------------------------|-----------------------------------------------|-------------------------------------|-----------------------------------|------------|----------------------------| -| year | 1 | Release year | year | TYE | TYER | TYER | | | | | YEAR | | -| track | 1 | Track number on the media, e.g. `{no: 1, of: 2}` | track | TRK | TRCK | TRCK | trkn | TRACKNUMBER | TRACK | WM/TrackNumber | ITRK | TRACK:PART_NUMBER | -| disk | 1 | Disk or media number, e.g. `{no: 1, of: 2}` | | TPA | TPOS | TPOS | disk | DISCNUMBER | DISC, DISCNUMBER | WM/PartOfSet | | | -| title | 1 | Track title | title | TT2 | TIT2 | TIT2 | ©nam | TITLE | TITLE | Title | INAM, TITL | SEGMENT:TITLE, TRACK:TITLE | -| artist | 1 | Literal written track artist e.g.: `"Beth Hart & Joe Bonamassa"`. If not directly specified in a tag, this is automatically filled with `common.artists`. | artist | TP1 | TPE1 | TPE1 | ©ART | ARTIST | ARTIST | Author | IART | TRACK:ARTIST | -| artists | * | Track artists e.g.: `["Beth Hart", "Joe Bonamassa"]`. If not directly specified in one or more tag, this is automatically filled with `common.artist` | | | TXXX:ARTISTS, TXXX:DISCOGS_ARTISTS, TXXX:DISCOGS_ARTIST_NAME | TXXX:ARTISTS, TXXX:DISCOGS_ARTISTS, TXXX:DISCOGS_ARTIST_NAME | ----:com.apple.iTunes:ARTISTS | ARTISTS, DISCOGS_ARTISTS, DISCOGS_ARTIST_NAME | ARTISTS | WM/ARTISTS | | | -| albumartist | 1 | Literal written album artist e.g.: `"Beth Hart & Joe Bonamassa"` | | TP2 | TPE2, TXXX:DISCOGS_ALBUM_ARTISTS | TPE2, TXXX:DISCOGS_ALBUM_ARTISTS | aART, ----:com.apple.iTunes:Band | ALBUMARTIST, DISCOGS_ALBUM_ARTISTS | ALBUM ARTIST | WM/AlbumArtist | | ALBUM:ARITST | -| album | 1 | Album title | album | TAL | TALB | TALB | ©alb | ALBUM | ALBUM | WM/AlbumTitle | IPRD, IRPD | ALBUM:TITLE | -| date | 1 | Release date | | | TDRV, TDRC, TXXX:DISCOGS_RELEASED | TDRV, TDRC, TXXX:DISCOGS_RELEASED | ©day | DATE, DISCOGS_RELEASED | YEAR | WM/Year | ICRD | | -| originaldate | 1 | Original (initial) release date, formatted like: YYYY-MM-DD | | TOR | TDOR, TXXX:DISCOGS_DATE | TDOR, TXXX:DISCOGS_DATE | ----:com.apple.iTunes:ORIGINALDATE | ORIGINALDATE, DISCOGS_DATE | ORIGINALDATE | WM/OriginalReleaseTime | | ALBUM:DATE_RECORDED | -| originalyear | 1 | Original (initial) release year | | | TORY, TXXX:ORIGINALYEAR | TORY, TXXX:ORIGINALYEAR | ----:com.apple.iTunes:ORIGINALYEAR | ORIGINALYEAR | ORIGINALYEAR | WM/OriginalReleaseYear | | | -| comment | * | Comments | comment | COM | COMM | COMM | ©cmt, ----:com.apple.iTunes:NOTES | COMMENT | COMMENT | Description | COMM, ICMT | | -| genre | * | Genres | genre | TCO | TCON, TXXX:STYLE | TCON, TXXX:STYLE | ©gen, gnre | GENRE, STYLE | GENRE | WM/Genre | GNRE, IGNR | | -| picture | * | Embedded cover art | | PIC | APIC | APIC | covr | METADATA_BLOCK_PICTURE | COVER ART (FRONT), COVER ART (BACK) | WM/Picture | | PICTURE | -| composer | * | Composer | | TCM | TCOM | TCOM | ©wrt | COMPOSER | COMPOSER | WM/Composer | | | -| lyrics | * | Lyricist | | | USLT:DESCRIPTION, SYLT | USLT:DESCRIPTION, SYLT | ©lyr | LYRICS | LYRICS | WM/Lyrics | | | -| albumsort | 1 | Album title, formatted for alphabetic ordering | | | TSOA | TSOA | soal | ALBUMSORT | ALBUMSORT | WM/AlbumSortOrder | | | -| titlesort | 1 | Track title, formatted for alphabetic ordering | | | TSOT | TSOT | sonm | TITLESORT | TITLESORT | WM/TitleSortOrder | | | -| work | 1 | The canonical title of the [work](https://musicbrainz.org/doc/Work) | | TOT | | | | WORK | WORK | WM/Work | | | -| artistsort | 1 | Track artist, formatted for alphabetic ordering | | | TSOP | TSOP | soar | ARTISTSORT | ARTISTSORT | WM/ArtistSortOrder | | TRACK:ARTISTSORT | -| albumartistsort | 1 | Album artist, formatted for alphabetic ordering | | | TSO2 | TSO2 | soaa, ----:com.apple.iTunes:ALBUMARTISTSORT | ALBUMARTISTSORT | ALBUMARTISTSORT | WM/AlbumArtistSortOrder | | ALBUM:ARITSTSORT | -| composersort | * | Composer, formatted for alphabetic ordering | | | TSOC | TSOC | soco | COMPOSERSORT | COMPOSERSORT | WM/ComposerSortOrder | | | -| lyricist | * | Lyricist | | TXT | TEXT | TEXT | ----:com.apple.iTunes:LYRICIST | LYRICIST | LYRICIST | WM/Writer | | | -| writer | * | Writer | | | TXXX:WRITER | TXXX:WRITER | | WRITER | WRITER | | IWRI | | -| conductor | * | Conductor | | TP3 | TPE3 | TPE3 | ----:com.apple.iTunes:CONDUCTOR | CONDUCTOR | CONDUCTOR | WM/Conductor | | | -| remixer | * | Remixer(s) | | | TPE4 | TPE4 | ----:com.apple.iTunes:REMIXER | REMIXER | MIXARTIST | WM/ModifiedBy | | | -| arranger | * | Arranger(s) | | | IPLS:ARRANGER, TIPL:ARRANGER | IPLS:ARRANGER, TIPL:ARRANGER | | ARRANGER | ARRANGER | | | | -| engineer | * | Engineer(s) | | | IPLS:ENGINEER, TIPL:ENGINEER | IPLS:ENGINEER, TIPL:ENGINEER | ----:com.apple.iTunes:ENGINEER | ENGINEER | ENGINEER | WM/Engineer | IENG | | -| producer | * | Producer(s) | | | IPLS:PRODUCER, TIPL:PRODUCER | IPLS:PRODUCER, TIPL:PRODUCER | ----:com.apple.iTunes:PRODUCER | PRODUCER | PRODUCER | WM/Producer | | | -| technician | * | Technician who digitized subject | | | | | | | | | ITCH | | -| djmixer | * | Mix-DJ(s) | | | IPLS:DJ-MIX, TIPL:DJ-MIX | IPLS:DJ-MIX, TIPL:DJ-MIX | ----:com.apple.iTunes:DJMIXER | DJMIXER | DJMIXER | WM/DJMixer | | | -| mixer | * | Mixed by | | | IPLS:MIX, TIPL:MIX | IPLS:MIX, TIPL:MIX | ----:com.apple.iTunes:MIXER | MIXER | MIXER | WM/Mixer | | | -| label | * | Release label name(s) | | TPB | TPUB, TXXX:DISCOGS_LABEL | TPUB, TXXX:DISCOGS_LABEL | ----:com.apple.iTunes:LABEL | LABEL, DISCOGS_LABEL | LABEL | WM/Publisher | | TRACK:PUBLISHER | -| grouping | 1 | Content group description. Used to group track titles in sections. | | TT1 | TIT1 | TIT1 | ©grp | GROUPING | GROUPING | WM/ContentGroupDescription | | | -| subtitle | 1 | Contains the subtitle of the content | | TT3 | TIT3 | TIT3 | ----:com.apple.iTunes:SUBTITLE | SUBTITLE | SUBTITLE | WM/SubTitle | | | -| discsubtitle | 1 | The Media Title given to a specific disc | | | TSST | TSST | ----:com.apple.iTunes:DISCSUBTITLE | DISCSUBTITLE | DISCSUBTITLE | WM/SetSubTitle | | | -| totaltracks | 1 | The total number of tracks | | | | | | TRACKTOTAL, TOTALTRACKS | | | | | -| totaldiscs | 1 | The total number of discs | | | | | | DISCTOTAL, TOTALDISCS | | | | | -| compilation | 1 | Is part of compilation (unofficial iTunes Compilation Flag) | | | TCMP | TCMP | cpil | COMPILATION | COMPILATION | WM/IsCompilation | | | -| rating | * | Object holding rating score [0..1] (0.0 worst rating, 1.0 best rating) and source (e.g. user e-mail) | | | POPM | POPM | | RATING | | WM/SharedUserRating | RATE | | -| bpm | 1 | Beats Per Minute (BPM) | | | TBPM | TBPM | tmpo | BPM | BPM | WM/BeatsPerMinute | | | -| mood | 1 | Keywords to reflect the mood of the audio, e.g. "Romantic" or "Sad" | | | TMOO | TMOO | ----:com.apple.iTunes:MOOD | MOOD | MOOD | WM/Mood | | | -| media | 1 | Release format | | | TMED | TMED | ----:com.apple.iTunes:MEDIA | MEDIA | MEDIA | WM/Media | IMED | | -| catalognumber | * | [Release catalog number(s)](https://musicbrainz.org/doc/Release/Catalog_Number) | | | TXXX:CATALOGNUMBER, TXXX:DISCOGS_CATALOG, TXXX:CATALOGID | TXXX:CATALOGNUMBER, TXXX:DISCOGS_CATALOG, TXXX:CATALOGID | ----:com.apple.iTunes:CATALOGNUMBER | CATALOGNUMBER, DISCOGS_CATALOG, CATALOGID | CATALOGNUMBER | WM/CatalogNo | | | -| tvShow | 1 | TV show title | | | | | tvsh | | | | | | -| tvShowSort | 1 | TV show title, formatted for alphabetic ordering | | | | | sosn | | | | | | -| tvSeason | 1 | TV season title | | | | | tvsn | | | | | | -| tvEpisode | 1 | TV episode title | | | | | tves | | | | | | -| tvEpisodeId | 1 | TV episode ID | | | | | tven | | | | | | -| tvNetwork | 1 | TV network | | | | | tvnn | | | | | | -| podcast | 1 | _ToDo, see [issues #13](https://github.com/Borewit/music-metadata/issues/13)_ | | | | | pcst | | | | | | -| podcasturl | 1 | _ToDo, see [issues #13](https://github.com/Borewit/music-metadata/issues/13)_ | | | | | purl | | | | | | -| releasestatus | 1 | See [releases status](https://wiki.musicbrainz.org/History:Release_Status) | | | TXXX:MUSICBRAINZ ALBUM STATUS | TXXX:MUSICBRAINZ ALBUM STATUS | ----:com.apple.iTunes:MusicBrainz Album Status | RELEASESTATUS | MUSICBRAINZ_ALBUMSTATUS | MusicBrainz/Album Status | | | -| releasetype | * | [Release type](https://musicbrainz.org/doc/Release_Group/Type), e,g,: Album | | | TXXX:MUSICBRAINZ ALBUM TYPE | TXXX:MUSICBRAINZ ALBUM TYPE | ----:com.apple.iTunes:MusicBrainz Album Type | RELEASETYPE | MUSICBRAINZ_ALBUMTYPE | MusicBrainz/Album Type | | | -| releasecountry | 1 | [Release country](https://wiki.musicbrainz.org/Release_Country) describes the country in which an album was released. | | | TXXX:MUSICBRAINZ ALBUM RELEASE COUNTRY, TXXX:RELEASECOUNTRY, TXXX:DISCOGS_COUNTRY | TXXX:MUSICBRAINZ ALBUM RELEASE COUNTRY, TXXX:RELEASECOUNTRY, TXXX:DISCOGS_COUNTRY | ----:com.apple.iTunes:MusicBrainz Album Release Country | RELEASECOUNTRY, DISCOGS_COUNTRY | RELEASECOUNTRY | MusicBrainz/Album Release Country | ICNT | | -| script | 1 | [Release Script](https://picard.musicbrainz.org/docs/tags/) | | | TXXX:SCRIPT | TXXX:SCRIPT | ----:com.apple.iTunes:SCRIPT | SCRIPT | SCRIPT | WM/Script | | | -| language | 1 | Language used in metadata | | TLA | TLAN | TLAN | ----:com.apple.iTunes:LANGUAGE | LANGUAGE | LANGUAGE | WM/Language | | | -| copyright | 1 | Contain copyright message for the copyright holder of the original sound, begin with a year and a space character. | | TCR | TCOP | TCOP | cprt | COPYRIGHT | COPYRIGHT | Copyright | | | -| license | 1 | License Relationship Type (releases, recordings) | | WCP | WCOP | WCOP | ----:com.apple.iTunes:LICENSE | LICENSE | LICENSE | LICENSE | | | -| encodedby | 1 | Encoded by (person/organisation) | | TEN | TENC | TENC | ©too | ENCODEDBY | ENCODEDBY | WM/EncodedBy | ISFT, CODE | | -| encodersettings | 1 | Encoder Settings | | TSS | TSSE | TSSE | | ENCODERSETTINGS | ENCODERSETTINGS | WM/EncodingSettings | | | -| gapless | 1 | Gapless album indicator ([MP4](http://help.mp3tag.de/main_tags.html)) | | COM:iTunPGAP | | | pgap | | | | | | -| barcode | 1 | [Release barcode](https://musicbrainz.org/doc/Barcode). | | | TXXX:BARCODE | TXXX:BARCODE | ----:com.apple.iTunes:BARCODE | BARCODE | BARCODE | WM/Barcode | | | -| isrc | * | [ISRC](https://musicbrainz.org/doc/ISRC) | | | TSRC | TSRC | ----:com.apple.iTunes:ISRC | ISRC | ISRC | WM/ISRC | | | -| asin | 1 | [Amazon Standard Identification Number (ASIN)](https://musicbrainz.org/doc/ASIN) | | | TXXX:ASIN | TXXX:ASIN | ----:com.apple.iTunes:ASIN | ASIN | ASIN | ASIN | | | -| musicbrainz_recordingid | 1 | Release [recording](https://musicbrainz.org/doc/Recording) [MBID](https://musicbrainz.org/doc/MusicBrainz_Identifier) | | | UFID:HTTP://MUSICBRAINZ.ORG | UFID:HTTP://MUSICBRAINZ.ORG | ----:com.apple.iTunes:MusicBrainz Track Id | MUSICBRAINZ_TRACKID | MUSICBRAINZ_TRACKID | MusicBrainz/Track Id | | TRACK:MUSICBRAINZ_TRACKID | -| musicbrainz_trackid | 1 | Release track [MBID](https://musicbrainz.org/doc/MusicBrainz_Identifier) | | | TXXX:MUSICBRAINZ RELEASE TRACK ID | TXXX:MUSICBRAINZ RELEASE TRACK ID | ----:com.apple.iTunes:MusicBrainz Release Track Id | MUSICBRAINZ_RELEASETRACKID | MUSICBRAINZ_RELEASETRACKID | MusicBrainz/Release Track Id | | | -| musicbrainz_albumid | 1 | [Album (release)](https://musicbrainz.org/doc/Release) [MBID](https://musicbrainz.org/doc/MusicBrainz_Identifier) | | | TXXX:MUSICBRAINZ ALBUM ID | TXXX:MUSICBRAINZ ALBUM ID | ----:com.apple.iTunes:MusicBrainz Album Id | MUSICBRAINZ_ALBUMID | MUSICBRAINZ_ALBUMID | MusicBrainz/Album Id | | TRACK:MUSICBRAINZ_ALBUMID | -| musicbrainz_artistid | * | Track [artists](https://musicbrainz.org/doc/Artist) [MBID](https://musicbrainz.org/doc/MusicBrainz_Identifier) | | | TXXX:MUSICBRAINZ ARTIST ID | TXXX:MUSICBRAINZ ARTIST ID | ----:com.apple.iTunes:MusicBrainz Artist Id | MUSICBRAINZ_ARTISTID | MUSICBRAINZ_ARTISTID | MusicBrainz/Artist Id | | TRACK:MUSICBRAINZ_ARTISTID | -| musicbrainz_albumartistid | * | Album artists [artists](https://musicbrainz.org/doc/Artist) [MBID](https://musicbrainz.org/doc/MusicBrainz_Identifier) | | | TXXX:MUSICBRAINZ ALBUM ARTIST ID | TXXX:MUSICBRAINZ ALBUM ARTIST ID | ----:com.apple.iTunes:MusicBrainz Album Artist Id | MUSICBRAINZ_ALBUMARTISTID | MUSICBRAINZ_ALBUMARTISTID | MusicBrainz/Album Artist Id | | | -| musicbrainz_releasegroupid | 1 | [Release group](https://musicbrainz.org/doc/Release_Group) [MBID](https://musicbrainz.org/doc/MusicBrainz_Identifier) | | | TXXX:MUSICBRAINZ RELEASE GROUP ID | TXXX:MUSICBRAINZ RELEASE GROUP ID | ----:com.apple.iTunes:MusicBrainz Release Group Id | MUSICBRAINZ_RELEASEGROUPID | MUSICBRAINZ_RELEASEGROUPID | MusicBrainz/Release Group Id | | | -| musicbrainz_workid | 1 | [Work](https://musicbrainz.org/doc/Work) [MBID](https://musicbrainz.org/doc/MusicBrainz_Identifier) | | | TXXX:MUSICBRAINZ WORK ID | TXXX:MUSICBRAINZ WORK ID | ----:com.apple.iTunes:MusicBrainz Work Id | MUSICBRAINZ_WORKID | MUSICBRAINZ_WORKID | MusicBrainz/Work Id | | | -| musicbrainz_trmid | 1 | [TRM (TRM Recognizes Music)]((https://musicbrainz.org/doc/Fingerprinting#TRM)) IDs were MusicBrainz’ first audio fingerprinting system. | | | TXXX:MUSICBRAINZ TRM ID | TXXX:MUSICBRAINZ TRM ID | ----:com.apple.iTunes:MusicBrainz TRM Id | MUSICBRAINZ_TRMID | MUSICBRAINZ_TRMID | MusicBrainz/TRM Id | | | -| musicbrainz_discid | 1 | [Disc ID](https://musicbrainz.org/doc/Disc_ID) is the code number which MusicBrainz uses to link a physical CD | | | TXXX:MUSICBRAINZ DISC ID | TXXX:MUSICBRAINZ DISC ID | ----:com.apple.iTunes:MusicBrainz Disc Id | MUSICBRAINZ_DISCID | MUSICBRAINZ_DISCID | MusicBrainz/Disc Id | | | -| acoustid_id | 1 | (AcoustID)[https://en.wikipedia.org/wiki/Acoustic_fingerprint] is MusicBrainz’ third and most recent audio fingerprinting system. | | | TXXX:ACOUSTID_ID, TXXX:ACOUSTID ID | TXXX:ACOUSTID_ID, TXXX:ACOUSTID ID | ----:com.apple.iTunes:Acoustid Id | ACOUSTID_ID | ACOUSTID_ID | Acoustid/Id | | | -| acoustid_fingerprint | 1 | [AcoustID Fingerprint](https://picard.musicbrainz.org/docs/mappings/). _ToDo: Same as acoustid_id._ | | | TXXX:ACOUSTID FINGERPRINT | TXXX:ACOUSTID FINGERPRINT | ----:com.apple.iTunes:Acoustid Fingerprint | ACOUSTID_ID_FINGERPRINT | ACOUSTID_FINGERPRINT | Acoustid/Fingerprint | | | -| musicip_puid | 1 | [PUIDs](https://musicbrainz.org/doc/Fingerprinting#PUID) were MusicBrainz’ second audio fingerprinting system. | | | TXXX:MUSICIP PUID | TXXX:MUSICIP PUID | ----:com.apple.iTunes:MusicIP PUID | MUSICIP_PUID | MUSICIP_PUID | MusicIP/PUID | | | -| musicip_fingerprint | 1 | MusicIP Fingerprint), not sure which algorithm. | | | TXXX:MUSICMAGIC FINGERPRINT | TXXX:MUSICMAGIC FINGERPRINT | ----:com.apple.iTunes:fingerprint | | | | | | -| website | 1 | URL of website | | WAR | WOAR | WOAR | | WEBSITE | WEBLINK | WM/AuthorURL | TURL | | -| performer:instrument | * | Performer relationship types, instrument can also be vocals. | | | | | | | | | | | -| averageLevel | 1 | Average gain level. | | | PRIV:AVERAGELEVEL | PRIV:AVERAGELEVEL | | | | | | | -| peakLevel | 1 | Peak gain level. | | | PRIV:PEAKLEVEL | PRIV:PEAKLEVEL | | | | | | | -| notes | * | Similar to comments | | | | | | NOTES | | | | | -| key | 1 | The 'Initial key' frame contains the musical key in which the sound starts. | | | TKEY | TKEY | | | | WM/InitialKey | | | -| originalalbum | 1 | Original release title of the earliest release in the release group intended for the title of the original recording. | | | TOAL | TOAL | | | | | | | -| originalartist | 1 | Original track artist of the earliest release in the release group intended for the performer(s) of the original recording. | | | TOPE | TOPE | | | | | | | -| discogs_artist_id | * | Discogs artist ID | | | TXXX:DISCOGS_ARTIST_ID | TXXX:DISCOGS_ARTIST_ID | | DISCOGS_ARTIST_ID | | | | | -| discogs_release_id | 1 | Discogs release identifier | | | TXXX:DISCOGS_RELEASE_ID | TXXX:DISCOGS_RELEASE_ID | | DISCOGS_RELEASE_ID | | | | | -| discogs_label_id | 1 | Discogs label ID | | | TXXX:DISCOGS_LABEL_ID | TXXX:DISCOGS_LABEL_ID | | DISCOGS_LABEL_ID | | | | | -| discogs_master_release_id | 1 | Discogs master release ID | | | TXXX:DISCOGS_MASTER_RELEASE_ID | TXXX:DISCOGS_MASTER_RELEASE_ID | | DISCOGS_MASTER_RELEASE_ID | | | | | -| discogs_votes | 1 | Discogs votes | | | TXXX:DISCOGS_VOTES | TXXX:DISCOGS_VOTES | | DISCOGS_VOTES | | | | | -| discogs_rating | 1 | Discogs rating | | | TXXX:DISCOGS_RATING | TXXX:DISCOGS_RATING | | DISCOGS_RATING | | | | | -| replaygain_track_peak | 1 | ReplayGain track peak: {ratio: number, dB: number} | | | TXXX:REPLAYGAIN_TRACK_PEAK | TXXX:REPLAYGAIN_TRACK_PEAK | ----:com.apple.iTunes:replaygain_track_peak | REPLAYGAIN_TRACK_PEAK | REPLAYGAIN_TRACK_PEAK | | | | -| replaygain_track_gain | 1 | ReplayGain track gain: {ratio: number, dB: number} | | | TXXX:REPLAYGAIN_TRACK_GAIN | TXXX:REPLAYGAIN_TRACK_GAIN | ----:com.apple.iTunes:replaygain_track_gain | REPLAYGAIN_TRACK_GAIN | REPLAYGAIN_TRACK_GAIN | | | | -| replaygain_album_peak | 1 | ReplayGain album peak: {ratio: number, dB: number} | | | TXXX:REPLAYGAIN_ALBUM_PEAK | TXXX:REPLAYGAIN_ALBUM_PEAK | ----:com.apple.iTunes:replaygain_album_peak | REPLAYGAIN_ALBUM_PEAK | | | | | -| replaygain_album_gain | 1 | ReplayGain album gain: {ratio: number, dB: number} | | | TXXX:REPLAYGAIN_ALBUM_GAIN | TXXX:REPLAYGAIN_ALBUM_GAIN | ----:com.apple.iTunes:replaygain_album_gain | REPLAYGAIN_ALBUM_GAIN | | | | | -| replaygain_track_minmax | 1 | Minimum & maximum global gain values for this file. | | | TXXX:MP3GAIN_MINMAX | TXXX:MP3GAIN_MINMAX | ----:com.apple.iTunes:replaygain_track_minmax | REPLAYGAIN_MINMAX | MP3GAIN_MINMAX | | | | -| replaygain_album_minmax | 1 | Minimum & maximum global gain values across a set of files scanned as an album. | | | TXXX:MP3GAIN_ALBUM_MINMAX | TXXX:MP3GAIN_ALBUM_MINMAX | ----:com.apple.iTunes:replaygain_album_minmax | REPLAYGAIN_ALBUM_MINMAX | | | | | -| replaygain_undo | 1 | The global gain adjustment to restore the original values in the left and right channels, respectively, followed by an indicator of whether to wrap | | | TXXX:MP3GAIN_UNDO | TXXX:MP3GAIN_UNDO | ----:com.apple.iTunes:replaygain_undo | REPLAYGAIN_UNDO | MP3GAIN_UNDO | | | | -| description | * | Description | | | | | desc, ldes | | | | | | +| Common tag | n | Description | ID3v1 | ID3v2.2 | ID3v2.3 | ID3v2.4 | iTunes | vorbis | APEv2 | asf | exif | matroska | +|----------------------------|---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|--------------|-----------------------------------------------------------------------------------|-----------------------------------------------------------------------------------|---------------------------------------------------------|-----------------------------------------------|-------------------------------------|-----------------------------------|------------|----------------------------| +| year | 1 | Release year | year | TYE | TYER | TYER | | | | | YEAR | | +| track | 1 | Track number on the media, e.g. `{no: 1, of: 2}` | track | TRK | TRCK | TRCK | TRKN | TRACKNUMBER | TRACK | WM/TrackNumber | ITRK | TRACK:PART_NUMBER | +| disk | 1 | Disk or media number, e.g. `{no: 1, of: 2}` | | TPA | TPOS | TPOS | DISK | DISCNUMBER | DISC, DISCNUMBER | WM/PartOfSet | | | +| title | 1 | Track title | title | TT2 | TIT2 | TIT2 | ©NAM | TITLE | TITLE | Title | INAM, TITL | SEGMENT:TITLE, TRACK:TITLE | +| artist | 1 | Literal written track artist e.g.: `"Beth Hart & Joe Bonamassa"`. If not directly specified in a tag, this is automatically filled with `common.artists`. | artist | TP1 | TPE1 | TPE1 | ©ART | ARTIST | ARTIST | Author | IART | TRACK:ARTIST | +| artists | * | Track artists e.g.: `["Beth Hart", "Joe Bonamassa"]`. If not directly specified in one or more tag, this is automatically filled with `common.artist` | | | TXXX:ARTISTS, TXXX:DISCOGS_ARTISTS, TXXX:DISCOGS_ARTIST_NAME | TXXX:ARTISTS, TXXX:DISCOGS_ARTISTS, TXXX:DISCOGS_ARTIST_NAME | ----:COM.APPLE.ITUNES:ARTISTS | ARTISTS, DISCOGS_ARTISTS, DISCOGS_ARTIST_NAME | ARTISTS | WM/ARTISTS | | | +| albumartist | 1 | Literal written album artist e.g.: `"Beth Hart & Joe Bonamassa"` | | TP2 | TPE2, TXXX:DISCOGS_ALBUM_ARTISTS | TPE2, TXXX:DISCOGS_ALBUM_ARTISTS | AART, ----:COM.APPLE.ITUNES:BAND | ALBUMARTIST, DISCOGS_ALBUM_ARTISTS | ALBUM ARTIST | WM/AlbumArtist | | ALBUM:ARITST | +| album | 1 | Album title | album | TAL | TALB | TALB | ©ALB | ALBUM | ALBUM | WM/AlbumTitle | IPRD, IRPD | ALBUM:TITLE | +| date | 1 | Release date | | TDR | TDRV, TDRC, TXXX:DISCOGS_RELEASED, TDRL | TDRV, TDRC, TXXX:DISCOGS_RELEASED, TDRL | ©DAY | DATE, DISCOGS_RELEASED | YEAR | WM/Year | ICRD | | +| originaldate | 1 | Original (initial) release date, formatted like: YYYY-MM-DD | | TOR | TDOR, TXXX:DISCOGS_DATE | TDOR, TXXX:DISCOGS_DATE | ----:COM.APPLE.ITUNES:ORIGINALDATE | ORIGINALDATE, DISCOGS_DATE | ORIGINALDATE | WM/OriginalReleaseTime | | ALBUM:DATE_RECORDED | +| originalyear | 1 | Original (initial) release year | | | TORY, TXXX:ORIGINALYEAR | TORY, TXXX:ORIGINALYEAR | ----:COM.APPLE.ITUNES:ORIGINALYEAR | ORIGINALYEAR | ORIGINALYEAR | WM/OriginalReleaseYear | | | +| comment | * | Comments | comment | COM | COMM | COMM | ©CMT, ©COM, ----:COM.APPLE.ITUNES:NOTES | COMMENT | COMMENT | Description | COMM, ICMT | | +| genre | * | Genres | genre | TCO | TCON, TXXX:STYLE | TCON, TXXX:STYLE | ©GEN, GNRE | GENRE, STYLE | GENRE | WM/Genre | GNRE, IGNR | | +| picture | * | Embedded cover art | | PIC | APIC | APIC | COVR | METADATA_BLOCK_PICTURE | COVER ART (FRONT), COVER ART (BACK) | WM/Picture | | PICTURE | +| composer | * | Composer | | TCM | TCOM | TCOM | ©WRT | COMPOSER | COMPOSER | WM/Composer | | | +| lyrics | * | Lyricist | | | USLT:DESCRIPTION, SYLT | USLT:DESCRIPTION, SYLT | ©LYR | LYRICS | LYRICS | WM/Lyrics | | | +| albumsort | 1 | Album title, formatted for alphabetic ordering | | TSA | TSOA | TSOA | SOAL | ALBUMSORT | ALBUMSORT | WM/AlbumSortOrder | | | +| titlesort | 1 | Track title, formatted for alphabetic ordering | | TST | TSOT | TSOT | SONM | TITLESORT | TITLESORT | WM/TitleSortOrder | | | +| work | 1 | The canonical title of the [work](https://musicbrainz.org/doc/Work) | | | | | ©WRK | WORK | WORK | WM/Work | | | +| artistsort | 1 | Track artist, formatted for alphabetic ordering | | TSP | TSOP | TSOP | SOAR | ARTISTSORT | ARTISTSORT | WM/ArtistSortOrder | | TRACK:ARTISTSORT | +| albumartistsort | 1 | Album artist, formatted for alphabetic ordering | | TS2 | TSO2 | TSO2 | SOAA, ----:COM.APPLE.ITUNES:ALBUMARTISTSORT | ALBUMARTISTSORT | ALBUMARTISTSORT | WM/AlbumArtistSortOrder | | ALBUM:ARITSTSORT | +| composersort | 1 | Composer, formatted for alphabetic ordering | | TSC | TSOC | TSOC | SOCO | COMPOSERSORT | COMPOSERSORT | WM/ComposerSortOrder | | | +| lyricist | * | Lyricist | | TXT | TEXT | TEXT | ----:COM.APPLE.ITUNES:LYRICIST | LYRICIST | LYRICIST | WM/Writer | | | +| writer | * | Writer | | | TXXX:WRITER | TXXX:WRITER | | WRITER | WRITER | | IWRI | | +| conductor | * | Conductor | | TP3 | TPE3 | TPE3 | ----:COM.APPLE.ITUNES:CONDUCTOR | CONDUCTOR | CONDUCTOR | WM/Conductor | | | +| remixer | * | Remixer(s) | | | TPE4 | TPE4 | ----:COM.APPLE.ITUNES:REMIXER | REMIXER | MIXARTIST | WM/ModifiedBy | | | +| arranger | * | Arranger(s) | | | IPLS:ARRANGER, TIPL:ARRANGER | IPLS:ARRANGER, TIPL:ARRANGER | | ARRANGER | ARRANGER | | | | +| engineer | * | Engineer(s) | | | IPLS:ENGINEER, TIPL:ENGINEER | IPLS:ENGINEER, TIPL:ENGINEER | ----:COM.APPLE.ITUNES:ENGINEER | ENGINEER | ENGINEER | WM/Engineer | IENG | | +| producer | * | Producer(s) | | | IPLS:PRODUCER, TIPL:PRODUCER | IPLS:PRODUCER, TIPL:PRODUCER | ----:COM.APPLE.ITUNES:PRODUCER | PRODUCER | PRODUCER | WM/Producer | | | +| technician | * | Technician who digitized subject | | | | | | | | | ITCH | | +| djmixer | * | Mix-DJ(s) | | | IPLS:DJ-MIX, TIPL:DJ-MIX | IPLS:DJ-MIX, TIPL:DJ-MIX | ----:COM.APPLE.ITUNES:DJMIXER | DJMIXER | DJMIXER | WM/DJMixer | | | +| mixer | * | Mixed by | | | IPLS:MIX, TIPL:MIX | IPLS:MIX, TIPL:MIX | ----:COM.APPLE.ITUNES:MIXER | MIXER | MIXER | WM/Mixer | | | +| label | * | Release label name(s) | | TPB | TPUB, TXXX:DISCOGS_LABEL | TPUB, TXXX:DISCOGS_LABEL | ----:COM.APPLE.ITUNES:LABEL | LABEL, DISCOGS_LABEL | LABEL | WM/Publisher | | TRACK:PUBLISHER | +| grouping | 1 | Content group description. Used to group track titles in sections. | | TT1 | TIT1 | TIT1 | ©GRP | GROUPING | GROUPING | WM/ContentGroupDescription | | | +| subtitle | * | Contains the subtitle of the content | | TT3 | TIT3 | TIT3 | ----:COM.APPLE.ITUNES:SUBTITLE, DESC | SUBTITLE | SUBTITLE | WM/SubTitle | | | +| discsubtitle | 1 | The Media Title given to a specific disc | | | TSST | TSST | ----:COM.APPLE.ITUNES:DISCSUBTITLE | DISCSUBTITLE | DISCSUBTITLE | WM/SetSubTitle | | | +| totaltracks | 1 | The total number of tracks | | | | | | TRACKTOTAL, TOTALTRACKS | | | | | +| totaldiscs | 1 | The total number of discs | | | | | | DISCTOTAL, TOTALDISCS | | | | | +| compilation | 1 | Is part of compilation (unofficial iTunes Compilation Flag) | | TCP | TCMP | TCMP | CPIL | COMPILATION | COMPILATION | WM/IsCompilation | | | +| rating | * | Object holding rating score [0..1] (0.0 worst rating, 1.0 best rating) and source (e.g. user e-mail) | | | POPM | POPM | | RATING | | WM/SharedUserRating | RATE | | +| bpm | 1 | Beats Per Minute (BPM) | | | TBPM | TBPM | TMPO | BPM | BPM | WM/BeatsPerMinute | | | +| mood | 1 | Keywords to reflect the mood of the audio, e.g. "Romantic" or "Sad" | | | TMOO | TMOO | ----:COM.APPLE.ITUNES:MOOD | MOOD | MOOD | WM/Mood | | | +| media | 1 | Release format | | | TMED | TMED | ----:COM.APPLE.ITUNES:MEDIA | MEDIA | MEDIA | WM/Media | IMED | | +| catalognumber | * | [Release catalog number(s)](https://musicbrainz.org/doc/Release/Catalog_Number) | | | TXXX:CATALOGNUMBER, TXXX:DISCOGS_CATALOG, TXXX:CATALOGID | TXXX:CATALOGNUMBER, TXXX:DISCOGS_CATALOG, TXXX:CATALOGID | ----:COM.APPLE.ITUNES:CATALOGNUMBER | CATALOGNUMBER, DISCOGS_CATALOG, CATALOGID | CATALOGNUMBER | WM/CatalogNo | | | +| tvShow | 1 | TV show title | | | | | TVSH | | | | | | +| tvShowSort | 1 | TV show title, formatted for alphabetic ordering | | | | | SOSN | | | | | | +| tvSeason | 1 | TV season title | | | | | TVSN | | | | | | +| tvEpisode | 1 | TV episode title | | | | | TVES | | | | | | +| tvEpisodeId | 1 | TV episode ID | | | | | TVEN | | | | | | +| tvNetwork | 1 | TV network | | | | | TVNN | | | | | | +| podcast | 1 | _ToDo, see [issues #13](https://github.com/Borewit/music-metadata/issues/13)_ | | PCS | PCST | PCST | PCST | | | | | | +| podcasturl | 1 | _ToDo, see [issues #13](https://github.com/Borewit/music-metadata/issues/13)_ | | WFD | WFED | WFED | PURL | | | | | | +| releasestatus | 1 | See [releases status](https://wiki.musicbrainz.org/History:Release_Status) | | | TXXX:MUSICBRAINZ ALBUM STATUS | TXXX:MUSICBRAINZ ALBUM STATUS | ----:COM.APPLE.ITUNES:MUSICBRAINZ ALBUM STATUS | RELEASESTATUS | MUSICBRAINZ_ALBUMSTATUS | MusicBrainz/Album Status | | | +| releasetype | * | [Release type](https://musicbrainz.org/doc/Release_Group/Type), e,g,: Album | | | TXXX:MUSICBRAINZ ALBUM TYPE | TXXX:MUSICBRAINZ ALBUM TYPE | ----:COM.APPLE.ITUNES:MUSICBRAINZ ALBUM TYPE | RELEASETYPE | MUSICBRAINZ_ALBUMTYPE | MusicBrainz/Album Type | | | +| releasecountry | 1 | [Release country](https://wiki.musicbrainz.org/Release_Country) describes the country in which an album was released. | | | TXXX:MUSICBRAINZ ALBUM RELEASE COUNTRY, TXXX:RELEASECOUNTRY, TXXX:DISCOGS_COUNTRY | TXXX:MUSICBRAINZ ALBUM RELEASE COUNTRY, TXXX:RELEASECOUNTRY, TXXX:DISCOGS_COUNTRY | ----:COM.APPLE.ITUNES:MUSICBRAINZ ALBUM RELEASE COUNTRY | RELEASECOUNTRY, DISCOGS_COUNTRY | RELEASECOUNTRY | MusicBrainz/Album Release Country | ICNT | | +| script | 1 | [Release Script](https://picard.musicbrainz.org/docs/tags/) | | | TXXX:SCRIPT | TXXX:SCRIPT | ----:COM.APPLE.ITUNES:SCRIPT | SCRIPT | SCRIPT | WM/Script | | | +| language | 1 | Language used in metadata | | TLA | TLAN | TLAN | ----:COM.APPLE.ITUNES:LANGUAGE | LANGUAGE | LANGUAGE | WM/Language | | | +| copyright | 1 | Contain copyright message for the copyright holder of the original sound, begin with a year and a space character. | | TCR | TCOP | TCOP | CPRT, ©CPY | COPYRIGHT | COPYRIGHT | Copyright | | | +| license | 1 | License Relationship Type (releases, recordings) | | WCP | WCOP | WCOP | ----:COM.APPLE.ITUNES:LICENSE | LICENSE | LICENSE | LICENSE | | | +| encodedby | 1 | Encoded by (person/organisation) | | TEN | TENC | TENC | ©TOO | ENCODEDBY | ENCODEDBY | WM/EncodedBy | ISFT, CODE | | +| encodersettings | 1 | Encoder Settings | | TSS | TSSE | TSSE | | ENCODERSETTINGS | ENCODERSETTINGS | WM/EncodingSettings | | | +| gapless | 1 | Gapless album indicator ([MP4](http://help.mp3tag.de/main_tags.html)) | | COM:ITUNPGAP | | | PGAP | | | | | | +| barcode | 1 | [Release barcode](https://musicbrainz.org/doc/Barcode). | | | TXXX:BARCODE | TXXX:BARCODE | ----:COM.APPLE.ITUNES:BARCODE | BARCODE | BARCODE | WM/Barcode | | | +| isrc | * | [ISRC](https://musicbrainz.org/doc/ISRC) | | | TSRC | TSRC | ----:COM.APPLE.ITUNES:ISRC | ISRC | ISRC | WM/ISRC | | | +| asin | 1 | [Amazon Standard Identification Number (ASIN)](https://musicbrainz.org/doc/ASIN) | | | TXXX:ASIN | TXXX:ASIN | ----:COM.APPLE.ITUNES:ASIN | ASIN | ASIN | ASIN | | | +| musicbrainz_recordingid | 1 | Release [recording](https://musicbrainz.org/doc/Recording) [MBID](https://musicbrainz.org/doc/MusicBrainz_Identifier) | | | UFID:HTTP://MUSICBRAINZ.ORG | UFID:HTTP://MUSICBRAINZ.ORG | ----:COM.APPLE.ITUNES:MUSICBRAINZ TRACK ID | MUSICBRAINZ_TRACKID | MUSICBRAINZ_TRACKID | MusicBrainz/Track Id | | TRACK:MUSICBRAINZ_TRACKID | +| musicbrainz_trackid | 1 | Release track [MBID](https://musicbrainz.org/doc/MusicBrainz_Identifier) | | | TXXX:MUSICBRAINZ RELEASE TRACK ID | TXXX:MUSICBRAINZ RELEASE TRACK ID | ----:COM.APPLE.ITUNES:MUSICBRAINZ RELEASE TRACK ID | MUSICBRAINZ_RELEASETRACKID | MUSICBRAINZ_RELEASETRACKID | MusicBrainz/Release Track Id | | | +| musicbrainz_albumid | 1 | [Album (release)](https://musicbrainz.org/doc/Release) [MBID](https://musicbrainz.org/doc/MusicBrainz_Identifier) | | | TXXX:MUSICBRAINZ ALBUM ID | TXXX:MUSICBRAINZ ALBUM ID | ----:COM.APPLE.ITUNES:MUSICBRAINZ ALBUM ID | MUSICBRAINZ_ALBUMID | MUSICBRAINZ_ALBUMID | MusicBrainz/Album Id | | TRACK:MUSICBRAINZ_ALBUMID | +| musicbrainz_artistid | * | Track [artists](https://musicbrainz.org/doc/Artist) [MBID](https://musicbrainz.org/doc/MusicBrainz_Identifier) | | | TXXX:MUSICBRAINZ ARTIST ID | TXXX:MUSICBRAINZ ARTIST ID | ----:COM.APPLE.ITUNES:MUSICBRAINZ ARTIST ID | MUSICBRAINZ_ARTISTID | MUSICBRAINZ_ARTISTID | MusicBrainz/Artist Id | | TRACK:MUSICBRAINZ_ARTISTID | +| musicbrainz_albumartistid | * | Album artists [artists](https://musicbrainz.org/doc/Artist) [MBID](https://musicbrainz.org/doc/MusicBrainz_Identifier) | | | TXXX:MUSICBRAINZ ALBUM ARTIST ID | TXXX:MUSICBRAINZ ALBUM ARTIST ID | ----:COM.APPLE.ITUNES:MUSICBRAINZ ALBUM ARTIST ID | MUSICBRAINZ_ALBUMARTISTID | MUSICBRAINZ_ALBUMARTISTID | MusicBrainz/Album Artist Id | | | +| musicbrainz_releasegroupid | 1 | [Release group](https://musicbrainz.org/doc/Release_Group) [MBID](https://musicbrainz.org/doc/MusicBrainz_Identifier) | | | TXXX:MUSICBRAINZ RELEASE GROUP ID | TXXX:MUSICBRAINZ RELEASE GROUP ID | ----:COM.APPLE.ITUNES:MUSICBRAINZ RELEASE GROUP ID | MUSICBRAINZ_RELEASEGROUPID | MUSICBRAINZ_RELEASEGROUPID | MusicBrainz/Release Group Id | | | +| musicbrainz_workid | 1 | [Work](https://musicbrainz.org/doc/Work) [MBID](https://musicbrainz.org/doc/MusicBrainz_Identifier) | | | TXXX:MUSICBRAINZ WORK ID | TXXX:MUSICBRAINZ WORK ID | ----:COM.APPLE.ITUNES:MUSICBRAINZ WORK ID | MUSICBRAINZ_WORKID | MUSICBRAINZ_WORKID | MusicBrainz/Work Id | | | +| musicbrainz_trmid | 1 | [TRM (TRM Recognizes Music)]((https://musicbrainz.org/doc/Fingerprinting#TRM)) IDs were MusicBrainz’ first audio fingerprinting system. | | | TXXX:MUSICBRAINZ TRM ID | TXXX:MUSICBRAINZ TRM ID | ----:COM.APPLE.ITUNES:MUSICBRAINZ TRM ID | MUSICBRAINZ_TRMID | MUSICBRAINZ_TRMID | MusicBrainz/TRM Id | | | +| musicbrainz_discid | 1 | [Disc ID](https://musicbrainz.org/doc/Disc_ID) is the code number which MusicBrainz uses to link a physical CD | | | TXXX:MUSICBRAINZ DISC ID | TXXX:MUSICBRAINZ DISC ID | ----:COM.APPLE.ITUNES:MUSICBRAINZ DISC ID | MUSICBRAINZ_DISCID | MUSICBRAINZ_DISCID | MusicBrainz/Disc Id | | | +| acoustid_id | 1 | (AcoustID)[https://en.wikipedia.org/wiki/Acoustic_fingerprint] is MusicBrainz’ third and most recent audio fingerprinting system. | | | TXXX:ACOUSTID_ID, TXXX:ACOUSTID ID | TXXX:ACOUSTID_ID, TXXX:ACOUSTID ID | ----:COM.APPLE.ITUNES:ACOUSTID ID | ACOUSTID_ID | ACOUSTID_ID | Acoustid/Id | | | +| acoustid_fingerprint | 1 | [AcoustID Fingerprint](https://picard.musicbrainz.org/docs/mappings/). _ToDo: Same as acoustid_id._ | | | TXXX:ACOUSTID FINGERPRINT | TXXX:ACOUSTID FINGERPRINT | ----:COM.APPLE.ITUNES:ACOUSTID FINGERPRINT | ACOUSTID_ID_FINGERPRINT | ACOUSTID_FINGERPRINT | Acoustid/Fingerprint | | | +| musicip_puid | 1 | [PUIDs](https://musicbrainz.org/doc/Fingerprinting#PUID) were MusicBrainz’ second audio fingerprinting system. | | | TXXX:MUSICIP PUID | TXXX:MUSICIP PUID | ----:COM.APPLE.ITUNES:MUSICIP PUID | MUSICIP_PUID | MUSICIP_PUID | MusicIP/PUID | | | +| musicip_fingerprint | 1 | MusicIP Fingerprint), not sure which algorithm. | | | TXXX:MUSICMAGIC FINGERPRINT | TXXX:MUSICMAGIC FINGERPRINT | ----:COM.APPLE.ITUNES:FINGERPRINT | | | | | | +| website | 1 | URL of website | | WAR | WOAR | WOAR | | WEBSITE | WEBLINK | WM/AuthorURL | TURL | | +| performer:instrument | * | Performer relationship types, instrument can also be vocals. | | | | | | | | | | | +| averageLevel | 1 | Average gain level. | | | PRIV:AVERAGELEVEL | PRIV:AVERAGELEVEL | | | | | | | +| peakLevel | 1 | Peak gain level. | | | PRIV:PEAKLEVEL | PRIV:PEAKLEVEL | | | | | | | +| notes | * | Similar to comments | | | | | | NOTES | | | | | +| key | 1 | The 'Initial key' frame contains the musical key in which the sound starts. | | | TKEY | TKEY | | KEY | | WM/InitialKey | | | +| originalalbum | 1 | Original release title of the earliest release in the release group intended for the title of the original recording. | | TOT | TOAL | TOAL | | | | | | | +| originalartist | 1 | Original track artist of the earliest release in the release group intended for the performer(s) of the original recording. | | | TOPE | TOPE | | | | | | | +| discogs_artist_id | * | Discogs artist ID | | | TXXX:DISCOGS_ARTIST_ID | TXXX:DISCOGS_ARTIST_ID | | DISCOGS_ARTIST_ID | | | | | +| discogs_release_id | 1 | Discogs release identifier | | | TXXX:DISCOGS_RELEASE_ID | TXXX:DISCOGS_RELEASE_ID | | DISCOGS_RELEASE_ID | | | | | +| discogs_label_id | 1 | Discogs label ID | | | TXXX:DISCOGS_LABEL_ID | TXXX:DISCOGS_LABEL_ID | | DISCOGS_LABEL_ID | | | | | +| discogs_master_release_id | 1 | Discogs master release ID | | | TXXX:DISCOGS_MASTER_RELEASE_ID | TXXX:DISCOGS_MASTER_RELEASE_ID | | DISCOGS_MASTER_RELEASE_ID | | | | | +| discogs_votes | 1 | Discogs votes | | | TXXX:DISCOGS_VOTES | TXXX:DISCOGS_VOTES | | DISCOGS_VOTES | | | | | +| discogs_rating | 1 | Discogs rating | | | TXXX:DISCOGS_RATING | TXXX:DISCOGS_RATING | | DISCOGS_RATING | | | | | +| replaygain_track_peak | 1 | ReplayGain track peak: {ratio: number, dB: number} | | | TXXX:REPLAYGAIN_TRACK_PEAK | TXXX:REPLAYGAIN_TRACK_PEAK | ----:COM.APPLE.ITUNES:REPLAYGAIN_TRACK_PEAK | REPLAYGAIN_TRACK_PEAK | REPLAYGAIN_TRACK_PEAK | | | | +| replaygain_track_gain | 1 | ReplayGain track gain: {ratio: number, dB: number} | | | TXXX:REPLAYGAIN_TRACK_GAIN | TXXX:REPLAYGAIN_TRACK_GAIN | ----:COM.APPLE.ITUNES:REPLAYGAIN_TRACK_GAIN | REPLAYGAIN_TRACK_GAIN | REPLAYGAIN_TRACK_GAIN | | | | +| replaygain_album_peak | 1 | ReplayGain album peak: {ratio: number, dB: number} | | | TXXX:REPLAYGAIN_ALBUM_PEAK | TXXX:REPLAYGAIN_ALBUM_PEAK | ----:COM.APPLE.ITUNES:REPLAYGAIN_ALBUM_PEAK | REPLAYGAIN_ALBUM_PEAK | | | | | +| replaygain_album_gain | 1 | ReplayGain album gain: {ratio: number, dB: number} | | | TXXX:REPLAYGAIN_ALBUM_GAIN | TXXX:REPLAYGAIN_ALBUM_GAIN | ----:COM.APPLE.ITUNES:REPLAYGAIN_ALBUM_GAIN | REPLAYGAIN_ALBUM_GAIN | | | | | +| replaygain_track_minmax | 1 | Minimum & maximum global gain values for this file. | | | TXXX:MP3GAIN_MINMAX | TXXX:MP3GAIN_MINMAX | ----:COM.APPLE.ITUNES:REPLAYGAIN_TRACK_MINMAX | REPLAYGAIN_MINMAX | MP3GAIN_MINMAX | | | | +| replaygain_album_minmax | 1 | Minimum & maximum global gain values across a set of files scanned as an album. | | | TXXX:MP3GAIN_ALBUM_MINMAX | TXXX:MP3GAIN_ALBUM_MINMAX | ----:COM.APPLE.ITUNES:REPLAYGAIN_ALBUM_MINMAX | REPLAYGAIN_ALBUM_MINMAX | | | | | +| replaygain_undo | 1 | The global gain adjustment to restore the original values in the left and right channels, respectively, followed by an indicator of whether to wrap | | | TXXX:MP3GAIN_UNDO | TXXX:MP3GAIN_UNDO | ----:COM.APPLE.ITUNES:REPLAYGAIN_UNDO | REPLAYGAIN_UNDO | MP3GAIN_UNDO | | | | +| description | * | Description | | | TDES | TDES | LDES | | | | | | +| category | * | Podcast Category | | | TCAT | TCAT | CATG | | | | | | +| hdVideo | 1 | iTunes Video Quality (2=Full HD, 1=HD, 0=SD) | | | | | HDVD | | | | | | +| keywords | * | Podcast Keywords | | | TKWD | TKWD | KEYW | | | | | | +| movement | 1 | Movement | | | MVNM | MVNM | ©MVN | | | | | | +| movementIndex | 1 | Movement Index/Total, e.g. `{no: 1, of: 4}` | | | MVIN | MVIN | ©MVI | | | | | | +| movementTotal | 1 | The total number of movements | | | | | ©MVC | | | | | | +| podcastId | 1 | Podcast Identifier | | | TGID | TGID | EGID | | | | | | +| showMovement | 1 | Show Movement | | | | | SHWM | | | | | | +| stik | 1 | iTunes Media Type (1=Normal, 2=Audiobook, 6=Music Video, 9=Movie, 10=TV Show, 11=Booklet, 14=Ringtone, https://github.com/sergiomb2/libmp4v2/wiki/iTunesMetadata#user-content-media-type-stik) | | | | | STIK | | | | | | diff --git a/lib/common/GenericTagTypes.ts b/lib/common/GenericTagTypes.ts index 6305c13c5..30e165be7 100644 --- a/lib/common/GenericTagTypes.ts +++ b/lib/common/GenericTagTypes.ts @@ -106,7 +106,16 @@ export type GenericTagId = | 'replaygain_track_minmax' | 'replaygain_album_minmax' | 'replaygain_undo' - | 'description'; + | 'description' + | 'category' + | 'hdVideo' + | 'keywords' + | 'movement' + | 'movementIndex' + | 'movementTotal' + | 'podcastId' + | 'showMovement' + | 'stik'; export interface INativeTagMap { [index: string]: GenericTagId; @@ -149,7 +158,7 @@ export const commonTags: ITagInfoMap = { work: {multiple: false, unique: true}, artistsort: {multiple: false, unique: true}, albumartistsort: {multiple: false, unique: true}, - composersort: {multiple: true, unique: true}, + composersort: {multiple: false, unique: true}, lyricist: {multiple: true, unique: true}, writer: {multiple: true, unique: true}, conductor: {multiple: true, unique: true}, @@ -162,7 +171,7 @@ export const commonTags: ITagInfoMap = { mixer: {multiple: true, unique: true}, label: {multiple: true, unique: true}, grouping: {multiple: false}, - subtitle: {multiple: false}, + subtitle: {multiple: true}, discsubtitle: {multiple: false}, totaltracks: {multiple: false}, totaldiscs: {multiple: false}, @@ -231,7 +240,17 @@ export const commonTags: ITagInfoMap = { replaygain_album_minmax: {multiple: false}, replaygain_undo: {multiple: false}, - description: {multiple: true} + description: {multiple: true}, + + category: {multiple: true}, + hdVideo: {multiple: false}, + keywords: {multiple: true}, + movement: {multiple: false}, + movementIndex: {multiple: false}, + movementTotal: {multiple: false}, + podcastId: {multiple: false}, + showMovement: {multiple: false}, + stik: {multiple: false} }; /** diff --git a/lib/common/MetadataCollector.ts b/lib/common/MetadataCollector.ts index 492ed557d..6aea0a4c1 100644 --- a/lib/common/MetadataCollector.ts +++ b/lib/common/MetadataCollector.ts @@ -67,7 +67,8 @@ export class MetadataCollector implements INativeMetadataCollector { public readonly common: ICommonTagsResult = { track: {no: null, of: null}, - disk: {no: null, of: null} + disk: {no: null, of: null}, + movementIndex: {} }; public readonly quality: IQualityInformation = { @@ -190,8 +191,13 @@ export class MetadataCollector implements INativeMetadataCollector { this.common.disk.of = CommonTagMapper.toIntOrNull(tag.value); return; + case 'movementTotal': + this.common.movementIndex.of = CommonTagMapper.toIntOrNull(tag.value); + return; + case 'track': case 'disk': + case 'movementIndex': const of = this.common[tag.id].of; // store of value, maybe maybe overwritten this.common[tag.id] = CommonTagMapper.normalizeTrack(tag.value); this.common[tag.id].of = of != null ? of : this.common[tag.id].of; @@ -238,7 +244,10 @@ export class MetadataCollector implements INativeMetadataCollector { break; case 'gapless': // iTunes gap-less flag - tag.value = tag.value === '1'; // boolean + case 'compilation': + case 'podcast': + case 'showMovement': + tag.value = tag.value === '1' || tag.value === 1; // boolean break; case 'isrc': // Only keep unique values diff --git a/lib/id3v2/FrameParser.ts b/lib/id3v2/FrameParser.ts index d1223716e..c219513a4 100644 --- a/lib/id3v2/FrameParser.ts +++ b/lib/id3v2/FrameParser.ts @@ -49,6 +49,10 @@ export class FrameParser { switch (type !== 'TXXX' && type[0] === 'T' ? 'T*' : type) { case 'T*': // 4.2.1. Text information frames - details case 'IPLS': // v2.3: Involved people list + case 'MVIN': + case 'MVNM': + case 'PCS': + case 'PCST': const text = common.decodeString(b.slice(1), encoding).replace(/\x00+$/, ''); switch (type) { case 'TMCL': // Musician credits list @@ -72,6 +76,12 @@ export class FrameParser { // id3v2.3 defines that TCOM, TEXT, TOLY, TOPE & TPE1 values are separated by / output = this.splitValue(type, text); break; + case 'PCS': + case 'PCST': + // TODO: Why `default` not results `1` but `''`? + output = this.major >= 4 ? this.splitValue(type, text) : [text]; + output = (Array.isArray(output) && output[0] === '') ? 1 : 0; + break; default: output = this.major >= 4 ? this.splitValue(type, text) : [text]; } @@ -224,6 +234,11 @@ export class FrameParser { break; } + case 'WFD': + case 'WFED': + output = common.decodeString(b.slice(offset + 1, common.findZero(b, offset + 1, length, encoding)), encoding); + break; + case 'MCDI': { // Music CD identifier output = b.slice(0, length); diff --git a/lib/id3v2/ID3v22TagMapper.ts b/lib/id3v2/ID3v22TagMapper.ts index 9d7e54b80..fa7b80814 100644 --- a/lib/id3v2/ID3v22TagMapper.ts +++ b/lib/id3v2/ID3v22TagMapper.ts @@ -1,5 +1,5 @@ import {INativeTagMap} from '../common/GenericTagTypes'; -import {CommonTagMapper} from '../common/GenericTagMapper'; +import {CaseInsensitiveTagMap} from '../common/CaseInsensitiveTagMap'; /** * ID3v2.2 tag mappings @@ -18,7 +18,7 @@ export const id3v22TagMap: INativeTagMap = { TCM: 'composer', TOR: 'originaldate', - TOT: 'work', + TOT: 'originalalbum', TXT: 'lyricist', TP3: 'conductor', TPB: 'label', @@ -35,10 +35,20 @@ export const id3v22TagMap: INativeTagMap = { 'COM:iTunNORM': , 'COM:iTunSMPB': 'encoder delay', 'COM:iTunes_CDDB_IDs' - */ + */, + + PCS: 'podcast', + TCP: "compilation", + TDR: 'date', + TS2: 'albumartistsort', + TSA: 'albumsort', + TSC: 'composersort', + TSP: 'artistsort', + TST: 'titlesort', + WFD: 'podcasturl' }; -export class ID3v22TagMapper extends CommonTagMapper { +export class ID3v22TagMapper extends CaseInsensitiveTagMap { public constructor() { super(['ID3v2.2'], id3v22TagMap); diff --git a/lib/id3v2/ID3v24TagMapper.ts b/lib/id3v2/ID3v24TagMapper.ts index 73057a780..9443d537b 100644 --- a/lib/id3v2/ID3v24TagMapper.ts +++ b/lib/id3v2/ID3v24TagMapper.ts @@ -136,7 +136,17 @@ const id3v24TagMap: INativeTagMap = { "TXXX:REPLAYGAIN_ALBUM_GAIN": "replaygain_album_gain", "TXXX:MP3GAIN_MINMAX": "replaygain_track_minmax", "TXXX:MP3GAIN_ALBUM_MINMAX": "replaygain_album_minmax", - "TXXX:MP3GAIN_UNDO": "replaygain_undo" + "TXXX:MP3GAIN_UNDO": "replaygain_undo", + + MVNM: "movement", + MVIN: "movementIndex", + PCST: "podcast", + TCAT: "category", + TDES: "description", + TDRL: "date", + TGID: "podcastId", + TKWD: "keywords", + WFED: "podcasturl" }; export class ID3v24TagMapper extends CaseInsensitiveTagMap { diff --git a/lib/mp4/MP4TagMapper.ts b/lib/mp4/MP4TagMapper.ts index 383be298e..481dc237f 100644 --- a/lib/mp4/MP4TagMapper.ts +++ b/lib/mp4/MP4TagMapper.ts @@ -1,5 +1,5 @@ import {INativeTagMap} from '../common/GenericTagTypes'; -import {CommonTagMapper} from '../common/GenericTagMapper'; +import {CaseInsensitiveTagMap} from '../common/CaseInsensitiveTagMap'; /** * Ref: https://github.com/sergiomb2/libmp4v2/wiki/iTunesMetadata @@ -15,6 +15,7 @@ const mp4TagMap: INativeTagMap = { '©alb': 'album', '©day': 'date', '©cmt': 'comment', + '©com': 'comment', trkn: 'track', disk: 'disk', '©gen': 'genre', @@ -56,6 +57,7 @@ const mp4TagMap: INativeTagMap = { '----:com.apple.iTunes:SCRIPT': 'script', '----:com.apple.iTunes:LANGUAGE': 'language', cprt: 'copyright', + '©cpy': 'copyright', '----:com.apple.iTunes:LICENSE': 'license', '©too': 'encodedby', pgap: 'gapless', @@ -91,13 +93,23 @@ const mp4TagMap: INativeTagMap = { '----:com.apple.iTunes:ORIGINALDATE': 'originaldate', '----:com.apple.iTunes:ORIGINALYEAR': 'originalyear', // '----:com.apple.iTunes:PERFORMER': 'performer' - desc: 'description', - ldes: 'description' + desc: 'subtitle', + ldes: 'description', + '©mvn': 'movement', + '©mvi': 'movementIndex', + '©mvc': 'movementTotal', + '©wrk': 'work', + catg: 'category', + egid: 'podcastId', + hdvd: 'hdVideo', + keyw: 'keywords', + shwm: 'showMovement', + stik: 'stik' }; export const tagType = 'iTunes'; -export class MP4TagMapper extends CommonTagMapper { +export class MP4TagMapper extends CaseInsensitiveTagMap { public constructor() { super([tagType], mp4TagMap); diff --git a/lib/type.ts b/lib/type.ts index fe44786cd..4baf5705f 100644 --- a/lib/type.ts +++ b/lib/type.ts @@ -121,9 +121,9 @@ export interface ICommonTagsResult { */ albumartistsort?: string; /** - * Composer(s), formatted for alphabetic ordering + * Composer, formatted for alphabetic ordering */ - composersort?: string[]; + composersort?: string; /** * Lyricist(s) */ @@ -164,10 +164,12 @@ export interface ICommonTagsResult { label?: string[]; grouping?: string[]; subtitle?: string[]; + description?: string[]; discsubtitle?: string[]; totaltracks?: string; totaldiscs?: string; - compilation?: string; + movementTotal?: number; + compilation?: boolean; rating?: IRating[]; bpm?: number; /** @@ -206,7 +208,7 @@ export interface ICommonTagsResult { * TV network */ tvNetwork?: string, - podcast?: string; + podcast?: boolean; podcasturl?: string; releasestatus?: string; releasetype?: string[]; @@ -297,6 +299,53 @@ export interface ICommonTagsResult { * Ref: https://docs.microsoft.com/en-us/windows/win32/wmformat/wm-initialkey */ key?: string; + + /** + * Podcast Category + */ + category?: string[]; + /** + * iTunes Video Quality + * + * 2: Full HD + * 1: HD + * 0: SD + */ + hdVideo?: number; + /** + * Podcast Keywords + */ + keywords?: string[]; + /** + * Movement + */ + movement?: string; + /** + * Movement Index/Total + */ + movementIndex: { no?: number, of?: number }; + /** + * Podcast Identifier + */ + podcastId?: string; + /** + * Show Movement + */ + showMovement?: boolean; + /** + * iTunes Media Type + * + * 1: Normal + * 2: Audiobook + * 6: Music Video + * 9: Movie + * 10: TV Show + * 11: Booklet + * 14: Ringtone + * + * https://github.com/sergiomb2/libmp4v2/wiki/iTunesMetadata#user-content-media-type-stik + */ + stik?: number; } export interface IRatio { diff --git a/test/samples/mp3/pr-544-id3v24.mp3 b/test/samples/mp3/pr-544-id3v24.mp3 new file mode 100644 index 000000000..9bc562a87 Binary files /dev/null and b/test/samples/mp3/pr-544-id3v24.mp3 differ diff --git a/test/samples/mp4/pr-544.m4a b/test/samples/mp4/pr-544.m4a new file mode 100644 index 000000000..cfc1a6af0 Binary files /dev/null and b/test/samples/mp4/pr-544.m4a differ diff --git a/test/test-pr-544.ts b/test/test-pr-544.ts new file mode 100644 index 000000000..3622039f2 --- /dev/null +++ b/test/test-pr-544.ts @@ -0,0 +1,741 @@ +import {assert} from 'chai'; +import * as mm from '../lib'; + +import * as path from 'path'; + +const t = assert; + +const samplePath = path.join(__dirname, 'samples'); + +// https://github.com/Borewit/music-metadata/pull/544 + +describe('Add, change and fix some mappings #pr-544', () => { + + describe('Movement Name', () => { + + it('mp3-id3v24', () => { + const filename = 'mp3/pr-544-id3v24.mp3'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.movement, 'Movement Name', 'metadata.common.movement'); + }); + }); + + // No possibility found to write id3v22 test file + /*it('mp3-id3v22', () => { + const filename = 'mp3/pr-544-id3v22.mp3'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.movement, 'Movement Name', 'metadata.common.movement'); + }); + });*/ + + it('mp4', () => { + const filename = 'mp4/pr-544.m4a'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.movement, 'Movement Name', 'metadata.common.movement'); + }); + }); + }); + + describe('Movement Index', () => { + + it('mp3-id3v24', () => { + const filename = 'mp3/pr-544-id3v24.mp3'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.deepEqual(metadata.common.movementIndex, {no: 1, of: 4}, 'metadata.common.movementIndex'); + }); + }); + + // No possibility found to write id3v22 test file + /*it('mp3-id3v22', () => { + const filename = 'mp3/pr-544-id3v22.mp3'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.deepEqual(metadata.common.movementIndex, {no: 1, of: 4}, 'metadata.common.movementIndex'); + }); + });*/ + + it('mp4', () => { + const filename = 'mp4/pr-544.m4a'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.deepEqual(metadata.common.movementIndex, {no: 1, of: 4}, 'metadata.common.movementIndex'); + }); + }); + }); + + describe('Show Movement', () => { + + // Not exists in MP3 (Written as comment) + /*it('mp3-id3v24', () => { + const filename = 'mp3/pr-544-id3v24.mp3'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.showMovement, true, 'metadata.common.showMovement'); + }); + });*/ + + // No possibility found to write id3v22 test file + // Not exists in MP3 (Written as comment) + /*it('mp3-id3v22', () => { + const filename = 'mp3/pr-544-id3v22.mp3'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.showMovement, true, 'metadata.common.showMovement'); + }); + });*/ + + it('mp4', () => { + const filename = 'mp4/pr-544.m4a'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.showMovement, true, 'metadata.common.showMovement'); + }); + }); + }); + + describe('Work', () => { + + // Not exists in MP3 (Written as comment) + /*it('mp3-id3v24', () => { + const filename = 'mp3/pr-544-id3v24.mp3'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.work, 'Work', 'metadata.common.work'); + }); + });*/ + + // No possibility found to write id3v22 test file + // Not exists in MP3 (Written as comment) + /*it('mp3-id3v22', () => { + const filename = 'mp3/pr-544-id3v22.mp3'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.work, 'Work', 'metadata.common.work'); + }); + });*/ + + it('mp4', () => { + const filename = 'mp4/pr-544.m4a'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.work, 'Work', 'metadata.common.work'); + }); + }); + }); + + describe('Podcast', () => { + + it('mp3-id3v24', () => { + const filename = 'mp3/pr-544-id3v24.mp3'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.podcast, true, 'metadata.common.podcast'); + }); + }); + + // No possibility found to write id3v22 test file + /*it('mp3-id3v22', () => { + const filename = 'mp3/pr-544-id3v22.mp3'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.podcast, true, 'metadata.common.podcast'); + }); + });*/ + + it('mp4', () => { + const filename = 'mp4/pr-544.m4a'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.podcast, true, 'metadata.common.podcast'); + }); + }); + }); + + describe('Podcast Category', () => { + + it('mp3-id3v24', () => { + const filename = 'mp3/pr-544-id3v24.mp3'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.deepEqual(metadata.common.category, ['Podcast Category'], 'metadata.common.category'); + }); + }); + + // No possibility found to write id3v22 test file + /*it('mp3-id3v22', () => { + const filename = 'mp3/pr-544-id3v22.mp3'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.deepEqual(metadata.common.category, ['Podcast Category'], 'metadata.common.category'); + }); + });*/ + + it('mp4', () => { + const filename = 'mp4/pr-544.m4a'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.deepEqual(metadata.common.category, ['Podcast Category'], 'metadata.common.category'); + }); + }); + }); + + describe('Podcast Identifier', () => { + + it('mp3-id3v24', () => { + const filename = 'mp3/pr-544-id3v24.mp3'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.podcastId, '1234', 'metadata.common.podcastId'); + }); + }); + + // No possibility found to write id3v22 test file + /*it('mp3-id3v22', () => { + const filename = 'mp3/pr-544-id3v22.mp3'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.podcastId, '1234', 'metadata.common.podcastId'); + }); + });*/ + + it('mp4', () => { + const filename = 'mp4/pr-544.m4a'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.podcastId, '1234', 'metadata.common.podcastId'); + }); + }); + }); + + describe('Podcast Keywords', () => { + + it('mp3-id3v24', () => { + const filename = 'mp3/pr-544-id3v24.mp3'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.deepEqual(metadata.common.keywords, ['Podcast Keywords'], 'metadata.common.keywords'); + }); + }); + + // No possibility found to write id3v22 test file + /*it('mp3-id3v22', () => { + const filename = 'mp3/pr-544-id3v22.mp3'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.deepEqual(metadata.common.keywords, ['Podcast Keywords'], 'metadata.common.keywords'); + }); + });*/ + + it('mp4', () => { + const filename = 'mp4/pr-544.m4a'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.deepEqual(metadata.common.keywords, ['Podcast Keywords'], 'metadata.common.keywords'); + }); + }); + }); + + describe('Podcast Url', () => { + + it('mp3-id3v24', () => { + const filename = 'mp3/pr-544-id3v24.mp3'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.podcasturl, 'http://podcast.url', 'metadata.common.podcasturl'); + }); + }); + + // No possibility found to write id3v22 test file + /*it('mp3-id3v22', () => { + const filename = 'mp3/pr-544-id3v22.mp3'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.podcasturl, 'http://podcast.url', 'metadata.common.podcasturl'); + }); + });*/ + + it('mp4', () => { + const filename = 'mp4/pr-544.m4a'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.podcasturl, 'http://podcast.url', 'metadata.common.podcasturl'); + }); + }); + }); + + describe('Short Description', () => { + + it('mp3-id3v24', () => { + const filename = 'mp3/pr-544-id3v24.mp3'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.deepEqual(metadata.common.subtitle, ['Short Description'], 'metadata.common.subtitle'); + }); + }); + + // No possibility found to write id3v22 test file + /*it('mp3-id3v22', () => { + const filename = 'mp3/pr-544-id3v22.mp3'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.deepEqual(metadata.common.subtitle, ['Short Description'], 'metadata.common.subtitle'); + }); + });*/ + + it('mp4', () => { + const filename = 'mp4/pr-544.m4a'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.deepEqual(metadata.common.subtitle, ['Short Description'], 'metadata.common.subtitle'); + }); + }); + }); + + describe('Long Description', () => { + + it('mp3-id3v24', () => { + const filename = 'mp3/pr-544-id3v24.mp3'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.deepEqual(metadata.common.description, ['Long Description'], 'metadata.common.description'); + }); + }); + + // No possibility found to write id3v22 test file + /*it('mp3-id3v22', () => { + const filename = 'mp3/pr-544-id3v22.mp3'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.deepEqual(metadata.common.description, ['Long Description'], 'metadata.common.description'); + }); + });*/ + + it('mp4', () => { + const filename = 'mp4/pr-544.m4a'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.deepEqual(metadata.common.description, ['Long Description'], 'metadata.common.description'); + }); + }); + }); + + describe('Album Artist Sort', () => { + + it('mp3-id3v24', () => { + const filename = 'mp3/pr-544-id3v24.mp3'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.albumartistsort, 'Album Artist Sort', 'metadata.common.albumartistsort'); + }); + }); + + // No possibility found to write id3v22 test file + /*it('mp3-id3v22', () => { + const filename = 'mp3/pr-544-id3v22.mp3'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.albumartistsort, 'Album Artist Sort', 'metadata.common.albumartistsort'); + }); + });*/ + + it('mp4', () => { + const filename = 'mp4/pr-544.m4a'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.albumartistsort, 'Album Artist Sort', 'metadata.common.albumartistsort'); + }); + }); + }); + + describe('Album Sort', () => { + + it('mp3-id3v24', () => { + const filename = 'mp3/pr-544-id3v24.mp3'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.albumsort, 'Album Sort', 'metadata.common.albumsort'); + }); + }); + + // No possibility found to write id3v22 test file + /*it('mp3-id3v22', () => { + const filename = 'mp3/pr-544-id3v22.mp3'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.albumsort, 'Album Sort', 'metadata.common.albumsort'); + }); + });*/ + + it('mp4', () => { + const filename = 'mp4/pr-544.m4a'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.albumsort, 'Album Sort', 'metadata.common.albumsort'); + }); + }); + }); + + describe('Artist Sort', () => { + + it('mp3-id3v24', () => { + const filename = 'mp3/pr-544-id3v24.mp3'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.artistsort, 'Artist Sort', 'metadata.common.artistsort'); + }); + }); + + // No possibility found to write id3v22 test file + /*it('mp3-id3v22', () => { + const filename = 'mp3/pr-544-id3v22.mp3'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.artistsort, 'Artist Sort', 'metadata.common.artistsort'); + }); + });*/ + + it('mp4', () => { + const filename = 'mp4/pr-544.m4a'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.artistsort, 'Artist Sort', 'metadata.common.artistsort'); + }); + }); + }); + + describe('Composer Sort', () => { + + it('mp3-id3v24', () => { + const filename = 'mp3/pr-544-id3v24.mp3'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.deepEqual(metadata.common.composersort, 'Composer Sort', 'metadata.common.composersort'); + }); + }); + + // No possibility found to write id3v22 test file + /*it('mp3-id3v22', () => { + const filename = 'mp3/pr-544-id3v22.mp3'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.deepEqual(metadata.common.composersort, 'Composer Sort', 'metadata.common.composersort'); + }); + });*/ + + it('mp4', () => { + const filename = 'mp4/pr-544.m4a'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.deepEqual(metadata.common.composersort, 'Composer Sort', 'metadata.common.composersort'); + }); + }); + }); + + describe('Title Sort', () => { + + it('mp3-id3v24', () => { + const filename = 'mp3/pr-544-id3v24.mp3'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.titlesort, 'Title Sort', 'metadata.common.titlesort'); + }); + }); + + // No possibility found to write id3v22 test file + /*it('mp3-id3v22', () => { + const filename = 'mp3/pr-544-id3v22.mp3'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.titlesort, 'Title Sort', 'metadata.common.titlesort'); + }); + });*/ + + it('mp4', () => { + const filename = 'mp4/pr-544.m4a'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.titlesort, 'Title Sort', 'metadata.common.titlesort'); + }); + }); + }); + + describe('Copyright', () => { + + it('mp3-id3v24', () => { + const filename = 'mp3/pr-544-id3v24.mp3'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.copyright, 'Copyright', 'metadata.common.copyright'); + }); + }); + + // No possibility found to write id3v22 test file + /*it('mp3-id3v22', () => { + const filename = 'mp3/pr-544-id3v22.mp3'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.copyright, 'Copyright', 'metadata.common.copyright'); + }); + });*/ + + it('mp4', () => { + const filename = 'mp4/pr-544.m4a'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.copyright, 'Copyright', 'metadata.common.copyright'); + }); + }); + }); + + describe('Compilation', () => { + + it('mp3-id3v24', () => { + const filename = 'mp3/pr-544-id3v24.mp3'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.compilation, true, 'metadata.common.compilation'); + }); + }); + + // No possibility found to write id3v22 test file + /*it('mp3-id3v22', () => { + const filename = 'mp3/pr-544-id3v22.mp3'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.compilation, true, 'metadata.common.compilation'); + }); + });*/ + + it('mp4', () => { + const filename = 'mp4/pr-544.m4a'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.compilation, true, 'metadata.common.compilation'); + }); + }); + }); + + describe('Comment', () => { + + it('mp3-id3v24', () => { + const filename = 'mp3/pr-544-id3v24.mp3'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.deepEqual(metadata.common.comment, ['Tagged with Mp3tag v3.01'], 'metadata.common.comment'); + }); + }); + + // No possibility found to write id3v22 test file + /*it('mp3-id3v22', () => { + const filename = 'mp3/pr-544-id3v22.mp3'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.deepEqual(metadata.common.comment, ['Tagged with Mp3tag v3.01'], 'metadata.common.comment'); + }); + });*/ + + it('mp4', () => { + const filename = 'mp4/pr-544.m4a'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.deepEqual(metadata.common.comment, ['Tagged with Mp3tag v3.01'], 'metadata.common.comment'); + }); + }); + }); + + describe('Release time', () => { + + it('mp3-id3v24', () => { + const filename = 'mp3/pr-544-id3v24.mp3'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.date, '2020-06-29T00:00:00.000Z', 'metadata.common.date'); + + t.strictEqual(metadata.common.year, 2020, 'metadata.common.year'); + }); + }); + + // No possibility found to write id3v22 test file + /*it('mp3-id3v22', () => { + const filename = 'mp3/pr-544-id3v22.mp3'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.date, '2020-06-29T00:00:00.000Z', 'metadata.common.date'); + + t.strictEqual(metadata.common.year, 2020, 'metadata.common.year'); + }); + });*/ + + it('mp4', () => { + const filename = 'mp4/pr-544.m4a'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.date, '2020-06-29T00:00:00.000Z', 'metadata.common.date'); + + t.strictEqual(metadata.common.year, 2020, 'metadata.common.year'); + }); + }); + }); + + describe('Original Album', () => { + + it('mp3-id3v24', () => { + const filename = 'mp3/pr-544-id3v24.mp3'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.originalalbum, 'Original Album', 'metadata.common.originalalbum'); + }); + }); + + // No possibility found to write id3v22 test file + /*it('mp3-id3v22', () => { + const filename = 'mp3/pr-544-id3v22.mp3'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.originalalbum, 'Original Album', 'metadata.common.originalalbum'); + }); + });*/ + + // Not exists in MP4 (Written as comment) + /*it('mp4', () => { + const filename = 'mp4/pr-544.m4a'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.originalalbum, 'Original Album', 'metadata.common.originalalbum'); + }); + });*/ + }); + + describe('iTunes Video Quality', () => { + + // Not exists in MP3 (Written as comment) + /*it('mp3-id3v24', () => { + const filename = 'mp3/pr-544-id3v24.mp3'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.hdVideo, 2, 'metadata.common.hdVideo'); + }); + });*/ + + // No possibility found to write id3v22 test file + // Not exists in MP3 (Written as comment) + /*it('mp3-id3v22', () => { + const filename = 'mp3/pr-544-id3v22.mp3'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.hdVideo, 2, 'metadata.common.hdVideo'); + }); + });*/ + + it('mp4', () => { + const filename = 'mp4/pr-544.m4a'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.hdVideo, 2, 'metadata.common.hdVideo'); + }); + }); + }); + + describe('iTunes Media Type', () => { + + // Not exists in MP3 (Written as comment) + /*it('mp3-id3v24', () => { + const filename = 'mp3/pr-544-id3v24.mp3'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.stik, 9, 'metadata.common.stik'); + }); + });*/ + + // No possibility found to write id3v22 test file + // Not exists in MP3 (Written as comment) + /*it('mp3-id3v22', () => { + const filename = 'mp3/pr-544-id3v22.mp3'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.stik, 9, 'metadata.common.stik'); + }); + });*/ + + it('mp4', () => { + const filename = 'mp4/pr-544.m4a'; + const filePath = path.join(samplePath, filename); + + return mm.parseFile(filePath).then(metadata => { + t.strictEqual(metadata.common.stik, 9, 'metadata.common.stik'); + }); + }); + }); +});