Added genre parsing for mp4 (atom) file metadata

This commit is contained in:
Aleksey Sulzhenko 2021-09-18 18:34:17 +03:00 committed by RedleX
parent d52dcb253c
commit 42d38d7bfb

455
mp4.go
View File

@ -31,6 +31,8 @@ var atoms = atomNames(map[string]string{
"\xa9day": "year",
"\xa9nam": "title",
"\xa9gen": "genre",
"gnre": "genre ID3v1 ID",
"geID": "genre ID",
"trkn": "track",
"\xa9wrt": "composer",
"\xa9too": "encoder",
@ -45,6 +47,438 @@ var atoms = atomNames(map[string]string{
"disk": "disc",
})
var genreIDValues = map[int]string{
2: "Blues",
3: "Comedy",
4: "Children's Music",
5: "Classical",
6: "Country",
7: "Electronic",
8: "Holiday",
9: "Classical|Opera",
10: "Singer/Songwriter",
11: "Jazz",
12: "Latino",
13: "New Age",
14: "Pop",
15: "R&B/Soul",
16: "Soundtrack",
17: "Dance",
18: "Hip-Hop/Rap",
19: "World",
20: "Alternative",
21: "Rock",
22: "Christian & Gospel",
23: "Vocal",
24: "Reggae",
25: "Easy Listening",
27: "J-Pop",
28: "Enka",
29: "Anime",
30: "Kayokyoku",
50: "Fitness & Workout",
51: "Pop|K-Pop",
52: "Karaoke",
53: "Instrumental",
1001: "Alternative|College Rock",
1002: "Alternative|Goth Rock",
1003: "Alternative|Grunge",
1004: "Alternative|Indie Rock",
1005: "Alternative|New Wave",
1006: "Alternative|Punk",
1007: "Blues|Chicago Blues",
1009: "Blues|Classic Blues",
1010: "Blues|Contemporary Blues",
1011: "Blues|Country Blues",
1012: "Blues|Delta Blues",
1013: "Blues|Electric Blues",
1014: "Children's Music|Lullabies",
1015: "Children's Music|Sing-Along",
1016: "Children's Music|Stories",
1017: "Classical|Avant-Garde",
1018: "Classical|Baroque Era",
1019: "Classical|Chamber Music",
1020: "Classical|Chant",
1021: "Classical|Choral",
1022: "Classical|Classical Crossover",
1023: "Classical|Early Music",
1024: "Classical|Impressionist",
1025: "Classical|Medieval Era",
1026: "Classical|Minimalism",
1027: "Classical|Modern Era",
1028: "Classical|Opera",
1029: "Classical|Orchestral",
1030: "Classical|Renaissance",
1031: "Classical|Romantic Era",
1032: "Classical|Wedding Music",
1033: "Country|Alternative Country",
1034: "Country|Americana",
1035: "Country|Bluegrass",
1036: "Country|Contemporary Bluegrass",
1037: "Country|Contemporary Country",
1038: "Country|Country Gospel",
1039: "Country|Honky Tonk",
1040: "Country|Outlaw Country",
1041: "Country|Traditional Bluegrass",
1042: "Country|Traditional Country",
1043: "Country|Urban Cowboy",
1044: "Dance|Breakbeat",
1045: "Dance|Exercise",
1046: "Dance|Garage",
1047: "Dance|Hardcore",
1048: "Dance|House",
1049: "Dance|Jungle/Drum'n'bass",
1050: "Dance|Techno",
1051: "Dance|Trance",
1052: "Jazz|Big Band",
1053: "Jazz|Bop",
1054: "Easy Listening|Lounge",
1055: "Easy Listening|Swing",
1056: "Electronic|Ambient",
1057: "Electronic|Downtempo",
1058: "Electronic|Electronica",
1060: "Electronic|IDM/Experimental",
1061: "Electronic|Industrial",
1062: "Singer/Songwriter|Alternative Folk",
1063: "Singer/Songwriter|Contemporary Folk",
1064: "Singer/Songwriter|Contemporary Singer/Songwriter",
1065: "Singer/Songwriter|Folk-Rock",
1066: "Singer/Songwriter|New Acoustic",
1067: "Singer/Songwriter|Traditional Folk",
1068: "Hip-Hop/Rap|Alternative Rap",
1069: "Hip-Hop/Rap|Dirty South",
1070: "Hip-Hop/Rap|East Coast Rap",
1071: "Hip-Hop/Rap|Gangsta Rap",
1072: "Hip-Hop/Rap|Hardcore Rap",
1073: "Hip-Hop/Rap|Hip-Hop",
1074: "Hip-Hop/Rap|Latin Rap",
1075: "Hip-Hop/Rap|Old School Rap",
1076: "Hip-Hop/Rap|Rap",
1077: "Hip-Hop/Rap|Underground Rap",
1078: "Hip-Hop/Rap|West Coast Rap",
1079: "Holiday|Chanukah",
1080: "Holiday|Christmas",
1081: "Holiday|Christmas: Children's",
1082: "Holiday|Christmas: Classic",
1083: "Holiday|Christmas: Classical",
1084: "Holiday|Christmas: Jazz",
1085: "Holiday|Christmas: Modern",
1086: "Holiday|Christmas: Pop",
1087: "Holiday|Christmas: R&B",
1088: "Holiday|Christmas: Religious",
1089: "Holiday|Christmas: Rock",
1090: "Holiday|Easter",
1091: "Holiday|Halloween",
1092: "Holiday|Holiday: Other",
1093: "Holiday|Thanksgiving",
1094: "Christian & Gospel|CCM",
1095: "Christian & Gospel|Christian Metal",
1096: "Christian & Gospel|Christian Pop",
1097: "Christian & Gospel|Christian Rap",
1098: "Christian & Gospel|Christian Rock",
1099: "Christian & Gospel|Classic Christian",
1100: "Christian & Gospel|Contemporary Gospel",
1101: "Christian & Gospel|Gospel",
1103: "Christian & Gospel|Praise & Worship",
1104: "Christian & Gospel|Southern Gospel",
1105: "Christian & Gospel|Traditional Gospel",
1106: "Jazz|Avant-Garde Jazz",
1107: "Jazz|Contemporary Jazz",
1108: "Jazz|Crossover Jazz",
1109: "Jazz|Dixieland",
1110: "Jazz|Fusion",
1111: "Jazz|Latin Jazz",
1112: "Jazz|Mainstream Jazz",
1113: "Jazz|Ragtime",
1114: "Jazz|Smooth Jazz",
1115: "Latino|Latin Jazz",
1116: "Latino|Contemporary Latin",
1117: "Latino|Pop Latino",
1118: "Latino|Raices",
1119: "Latino|Urbano latino",
1120: "Latino|Baladas y Boleros",
1121: "Latino|Rock y Alternativo",
1122: "Brazilian",
1123: "Latino|Musica Mexicana",
1124: "Latino|Musica tropical",
1125: "New Age|Environmental",
1126: "New Age|Healing",
1127: "New Age|Meditation",
1128: "New Age|Nature",
1129: "New Age|Relaxation",
1130: "New Age|Travel",
1131: "Pop|Adult Contemporary",
1132: "Pop|Britpop",
1133: "Pop|Pop/Rock",
1134: "Pop|Soft Rock",
1135: "Pop|Teen Pop",
1136: "R&B/Soul|Contemporary R&B",
1137: "R&B/Soul|Disco",
1138: "R&B/Soul|Doo Wop",
1139: "R&B/Soul|Funk",
1140: "R&B/Soul|Motown",
1141: "R&B/Soul|Neo-Soul",
1142: "R&B/Soul|Quiet Storm",
1143: "R&B/Soul|Soul",
1144: "Rock|Adult Alternative",
1145: "Rock|American Trad Rock",
1146: "Rock|Arena Rock",
1147: "Rock|Blues-Rock",
1148: "Rock|British Invasion",
1149: "Rock|Death Metal/Black Metal",
1150: "Rock|Glam Rock",
1151: "Rock|Hair Metal",
1152: "Rock|Hard Rock",
1153: "Rock|Metal",
1154: "Rock|Jam Bands",
1155: "Rock|Prog-Rock/Art Rock",
1156: "Rock|Psychedelic",
1157: "Rock|Rock & Roll",
1158: "Rock|Rockabilly",
1159: "Rock|Roots Rock",
1160: "Rock|Singer/Songwriter",
1161: "Rock|Southern Rock",
1162: "Rock|Surf",
1163: "Rock|Tex-Mex",
1165: "Soundtrack|Foreign Cinema",
1166: "Soundtrack|Musicals",
1167: "Comedy|Novelty",
1168: "Soundtrack|Original Score",
1169: "Soundtrack|Soundtrack",
1171: "Comedy|Standup Comedy",
1172: "Soundtrack|TV Soundtrack",
1173: "Vocal|Standards",
1174: "Vocal|Traditional Pop",
1175: "Jazz|Vocal Jazz",
1176: "Vocal|Vocal Pop",
1177: "African|Afro-Beat",
1178: "African|Afro-Pop",
1179: "World|Cajun",
1180: "World|Celtic",
1181: "World|Celtic Folk",
1182: "World|Contemporary Celtic",
1183: "Reggae|Modern Dancehall",
1184: "World|Drinking Songs",
1185: "Indian|Indian Pop",
1186: "World|Japanese Pop",
1187: "World|Klezmer",
1188: "World|Polka",
1189: "World|Traditional Celtic",
1190: "World|Worldbeat",
1191: "World|Zydeco",
1192: "Reggae|Roots Reggae",
1193: "Reggae|Dub",
1194: "Reggae|Ska",
1195: "World|Caribbean",
1196: "World|South America",
1197: "Arabic",
1198: "World|North America",
1199: "World|Hawaii",
1200: "World|Australia",
1201: "World|Japan",
1202: "World|France",
1203: "African",
1204: "World|Asia",
1205: "World|Europe",
1206: "World|South Africa",
1207: "Jazz|Hard Bop",
1208: "Jazz|Trad Jazz",
1209: "Jazz|Cool Jazz",
1210: "Blues|Acoustic Blues",
1211: "Classical|High Classical",
1220: "Brazilian|Axe",
1221: "Brazilian|Bossa Nova",
1222: "Brazilian|Choro",
1223: "Brazilian|Forro",
1224: "Brazilian|Frevo",
1225: "Brazilian|MPB",
1226: "Brazilian|Pagode",
1227: "Brazilian|Samba",
1228: "Brazilian|Sertanejo",
1229: "Brazilian|Baile Funk",
1230: "Alternative|Chinese Alt",
1231: "Alternative|Korean Indie",
1232: "Chinese",
1233: "Chinese|Chinese Classical",
1234: "Chinese|Chinese Flute",
1235: "Chinese|Chinese Opera",
1236: "Chinese|Chinese Orchestral",
1237: "Chinese|Chinese Regional Folk",
1238: "Chinese|Chinese Strings",
1239: "Chinese|Taiwanese Folk",
1240: "Chinese|Tibetan Native Music",
1241: "Hip-Hop/Rap|Chinese Hip-Hop",
1242: "Hip-Hop/Rap|Korean Hip-Hop",
1243: "Korean",
1244: "Korean|Korean Classical",
1245: "Korean|Korean Trad Song",
1246: "Korean|Korean Trad Instrumental",
1247: "Korean|Korean Trad Theater",
1248: "Rock|Chinese Rock",
1249: "Rock|Korean Rock",
1250: "Pop|C-Pop",
1251: "Pop|Cantopop/HK-Pop",
1252: "Pop|Korean Folk-Pop",
1253: "Pop|Mandopop",
1254: "Pop|Tai-Pop",
1255: "Pop|Malaysian Pop",
1256: "Pop|Pinoy Pop",
1257: "Pop|Original Pilipino Music",
1258: "Pop|Manilla Sound",
1259: "Pop|Indo Pop",
1260: "Pop|Thai Pop",
1261: "Vocal|Trot",
1262: "Indian",
1263: "Indian|Bollywood",
1264: "Indian|Regional Indian|Tamil",
1265: "Indian|Regional Indian|Telugu",
1266: "Indian|Regional Indian",
1267: "Indian|Devotional & Spiritual",
1268: "Indian|Sufi",
1269: "Indian|Indian Classical",
1270: "Russian|Russian Chanson",
1271: "World|Dini",
1272: "Turkish|Halk",
1273: "Turkish|Sanat",
1274: "World|Dangdut",
1275: "World|Indonesian Religious",
1276: "World|Calypso",
1277: "World|Soca",
1278: "Indian|Ghazals",
1279: "Indian|Indian Folk",
1280: "Turkish|Arabesque",
1281: "African|Afrikaans",
1282: "World|Farsi",
1283: "World|Israeli",
1284: "Arabic|Khaleeji",
1285: "Arabic|North African",
1286: "Arabic|Arabic Pop",
1287: "Arabic|Islamic",
1288: "Soundtrack|Sound Effects",
1289: "Folk",
1290: "Orchestral",
1291: "Marching",
1293: "Pop|Oldies",
1294: "Country|Thai Country",
1295: "World|Flamenco",
1296: "World|Tango",
1297: "World|Fado",
1298: "World|Iberia",
1299: "Russian",
1300: "Turkish",
100000: "Christian & Gospel",
100001: "Classical|Art Song",
100002: "Classical|Brass & Woodwinds",
100003: "Classical|Solo Instrumental",
100004: "Classical|Contemporary Era",
100005: "Classical|Oratorio",
100006: "Classical|Cantata",
100007: "Classical|Electronic",
100008: "Classical|Sacred",
100009: "Classical|Guitar",
100010: "Classical|Piano",
100011: "Classical|Violin",
100012: "Classical|Cello",
100013: "Classical|Percussion",
100014: "Electronic|Dubstep",
100015: "Electronic|Bass",
100016: "Hip-Hop/Rap|UK Hip-Hop",
100017: "Reggae|Lovers Rock",
100018: "Alternative|EMO",
100019: "Alternative|Pop Punk",
100020: "Alternative|Indie Pop",
100021: "New Age|Yoga",
100022: "Pop|Tribute",
100023: "Pop|Shows",
100024: "Cuban",
100025: "Cuban|Mambo",
100026: "Cuban|Chachacha",
100027: "Cuban|Guajira",
100028: "Cuban|Son",
100029: "Cuban|Bolero",
100030: "Cuban|Guaracha",
100031: "Cuban|Timba",
100032: "Soundtrack|Video Game",
100033: "Indian|Regional Indian|Punjabi|Punjabi Pop",
100034: "Indian|Regional Indian|Bengali|Rabindra Sangeet",
100035: "Indian|Regional Indian|Malayalam",
100036: "Indian|Regional Indian|Kannada",
100037: "Indian|Regional Indian|Marathi",
100038: "Indian|Regional Indian|Gujarati",
100039: "Indian|Regional Indian|Assamese",
100040: "Indian|Regional Indian|Bhojpuri",
100041: "Indian|Regional Indian|Haryanvi",
100042: "Indian|Regional Indian|Odia",
100043: "Indian|Regional Indian|Rajasthani",
100044: "Indian|Regional Indian|Urdu",
100045: "Indian|Regional Indian|Punjabi",
100046: "Indian|Regional Indian|Bengali",
100047: "Indian|Indian Classical|Carnatic Classical",
100048: "Indian|Indian Classical|Hindustani Classical",
100049: "African|Afro House",
100050: "African|Afro Soul",
100051: "African|Afrobeats",
100052: "African|Benga",
100053: "African|Bongo-Flava",
100054: "African|Coupe-Decale",
100055: "African|Gqom",
100056: "African|Highlife",
100057: "African|Kuduro",
100058: "African|Kizomba",
100059: "African|Kwaito",
100060: "African|Mbalax",
100061: "African|Ndombolo",
100062: "African|Shangaan Electro",
100063: "African|Soukous",
100064: "African|Taarab",
100065: "African|Zouglou",
100066: "Turkish|Ozgun",
100067: "Turkish|Fantezi",
100068: "Turkish|Religious",
100069: "Pop|Turkish Pop",
100070: "Rock|Turkish Rock",
100071: "Alternative|Turkish Alternative",
100072: "Hip-Hop/Rap|Turkish Hip-Hop/Rap",
100073: "African|Maskandi",
100074: "Russian|Russian Romance",
100075: "Russian|Russian Bard",
100076: "Russian|Russian Pop",
100077: "Russian|Russian Rock",
100078: "Russian|Russian Hip-Hop",
100079: "Arabic|Levant",
100080: "Arabic|Levant|Dabke",
100081: "Arabic|Maghreb Rai",
100082: "Arabic|Khaleeji|Khaleeji Jalsat",
100083: "Arabic|Khaleeji|Khaleeji Shailat",
100084: "Tarab",
100085: "Tarab|Iraqi Tarab",
100086: "Tarab|Egyptian Tarab",
100087: "Tarab|Khaleeji Tarab",
100088: "Pop|Levant Pop",
100089: "Pop|Iraqi Pop",
100090: "Pop|Egyptian Pop",
100091: "Pop|Maghreb Pop",
100092: "Pop|Khaleeji Pop",
100093: "Hip-Hop/Rap|Levant Hip-Hop",
100094: "Hip-Hop/Rap|Egyptian Hip-Hop",
100095: "Hip-Hop/Rap|Maghreb Hip-Hop",
100096: "Hip-Hop/Rap|Khaleeji Hip-Hop",
100097: "Alternative|Indie Levant",
100098: "Alternative|Indie Egyptian",
100099: "Alternative|Indie Maghreb",
100100: "Electronic|Levant Electronic",
100101: "Electronic|Electro-Cha'abi",
100102: "Electronic|Maghreb Electronic",
100103: "Folk|Iraqi Folk",
100104: "Folk|Khaleeji Folk",
100105: "Dance|Maghreb Dance",
50000061: "Spoken Word",
50000063: "Disney",
50000064: "French Pop",
50000066: "German Pop",
50000068: "German Folk",
}
// Detect PNG image if "implicit" class is used
var pngHeader = []byte{137, 80, 78, 71, 13, 10, 26, 10}
@ -148,10 +582,15 @@ func (m metadataMP4) readAtomData(r io.ReadSeeker, name string, size uint32, pro
// "data" + size (4 bytes each)
b = b[8:]
if len(b) < 4 {
return fmt.Errorf("invalid encoding: expected at least %d bytes, for class, got %d", 4, len(b))
}
if name == "gnre" {
m.data[name] = getInt(b[len(b)-1:])
return nil
}
class := getInt(b[1:4])
var ok bool
contentType, ok = atomTypes[class]
@ -201,7 +640,7 @@ func (m metadataMP4) readAtomData(r io.ReadSeeker, name string, size uint32, pro
if len(b) < 1 {
return fmt.Errorf("invalid encoding: expected at least %d bytes, for integer tag data, got %d", 1, len(b))
}
data = getInt(b[:1])
data = getInt(b[len(b)-1:])
case "jpeg", "png":
data = &Picture{
@ -318,7 +757,17 @@ func (m metadataMP4) Composer() string {
}
func (m metadataMP4) Genre() string {
return m.getString(atoms.Name("genre"))
genre := m.getString(atoms.Name("genre"))
if len(genre) < 1 {
genreID := m.getInt(atoms.Name("genre ID"))
if genreID == 0 {
genreID := m.getInt(atoms.Name("genre ID3v1 ID")) - 1
genre = id3v1Genres[genreID]
} else {
genre = genreIDValues[genreID]
}
}
return genre
}
func (m metadataMP4) Year() int {