iTunes specific tags

Hello,

I use Mp3tag to tag my whole iTunes-library (m4a-files).

I want the media to look exactly like iTunes purchased m4a-files.

But there are three fields I couldn't handle:

Apple Store Country ('sfID')
Album Title ID ('atID')
Genre ID ('geID')

How can I set those?

Best regards,
Felix

Done with mutagen:

from mutagen.mp4 import MP4

audio = MP4("test.m4a")
audio["geID"] = [12345]
audio["atID"] = [12345]
audio["sfID"] = [12345]
audio.pprint()
audio.save()
1 Like

Wrote a little dirty script to tag after tagged with jonaaa20's tool.

Feel free to optimize it.

import requests
import json
import re
import os
import mutagen

from mutagen.mp4 import MP4

source_dir = r"C:\Lossless"

for i, name in enumerate(os.listdir(source_dir), start=0):  # iterate over all files/directories in source_dir
	if name[-4:].lower() != ".m4a":  # ignore non-mp3 files
		continue
	path = os.path.join(source_dir, name)  # build the whole file path
	# you can also check with os.path.isfile(path) to make sure it's a file you're processing
	# etc. (your mutagen update logic)
	audio = MP4(path)
	if i == 0:
		lookupid = audio["cnID"]
		lookupid = lookupid[0]
		break

# lookupid = int(input("AppleStoreCatalogID: "))

print(lookupid)

a = ('https://itunes.apple.com/lookup?country=US&entity=song&limit=200&id=%i' % lookupid)
b = requests.get(a).json()

geID = b['results'][0]['primaryGenreName']
geID = re.sub("Blues", '2', geID)
geID = re.sub("Comedy", '3', geID)
geID = re.sub("Children's Music", '4', geID)
geID = re.sub("Classical", '5', geID)
geID = re.sub("Country", '6', geID)
geID = re.sub("Electronic", '7', geID)
geID = re.sub("Holiday", '8', geID)
geID = re.sub("Classical|Opera", '9', geID)
geID = re.sub("Singer/Songwriter", '10', geID)
geID = re.sub("Jazz", '11', geID)
geID = re.sub("Latino", '12', geID)
geID = re.sub("New Age", '13', geID)
geID = re.sub("Pop", '14', geID)
geID = re.sub("R&B/Soul", '15', geID)
geID = re.sub("Soundtrack", '16', geID)
geID = re.sub("Dance", '17', geID)
geID = re.sub("Hip-Hop/Rap", '18', geID)
geID = re.sub("World", '19', geID)
geID = re.sub("Alternative", '20', geID)
geID = re.sub("Rock", '21', geID)
geID = re.sub("Christian & Gospel", '22', geID)
geID = re.sub("Vocal", '23', geID)
geID = re.sub("Reggae", '24', geID)
geID = re.sub("Easy Listening", '25', geID)
geID = re.sub("J-Pop", '27', geID)
geID = re.sub("Enka", '28', geID)
geID = re.sub("Anime", '29', geID)
geID = re.sub("Kayokyoku", '30', geID)
geID = int(geID)
geID = [geID]
print(geID)

atID = b['results'][0]['artistId']
atID = [atID]
print(atID)

sfID = b['results'][0]['country']
sfID = re.sub("ENG", '143441', sfID)
sfID = re.sub("DEU", '143443', sfID)
sfID = re.sub("CAN", '143455', sfID)
sfID = int(sfID)
sfID = [sfID]
print(sfID)

plID = b['results'][0]['collectionId']
plID = [plID]
print(plID)



for name in os.listdir(source_dir):  # iterate over all files/directories in source_dir
	if name[-4:].lower() != ".m4a":  # ignore non-mp3 files
		continue
	path = os.path.join(source_dir, name)  # build the whole file path
	# you can also check with os.path.isfile(path) to make sure it's a file you're processing
	# etc. (your mutagen update logic)
	audio = MP4(path)
	audio["geID"] = geID
	audio["atID"] = atID
	audio["sfID"] = sfID
	audio["plID"] = plID
	audio["pgap"] = False
	audio["cpil"] = False
	audio.pprint()
	audio.save()

I know this is random but do you have an updated version of this script? I'm a noob in python and I'm getting a bunch of errors. Not sure if it's just a new version of python or if I have errors in my code.

My code is exactly the same as yours just with a different directory.

Here's the errors I'm getting

Python 3.7.4 (tags/v3.7.4:e09359112e, Jul  8 2019, 19:29:22) [MSC v.1916 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import requests
>>> import json
>>> import re
>>> import os
>>> import mutagen
>>>
>>> from mutagen.mp4 import MP4
>>>
>>> source_dir = r"C:\Users\Riley\Desktop"
>>>
>>> for i, name in enumerate(os.listdir(source_dir), start=0):  # iterate over all files/directories in source_dir
... if name[-4:].lower() != ".m4a":  # ignore non-mp3 files
  File "<stdin>", line 2
    if name[-4:].lower() != ".m4a":  # ignore non-mp3 files
     ^
IndentationError: expected an indented block
>>> continue
  File "<stdin>", line 1
SyntaxError: 'continue' not properly in loop
>>> path = os.path.join(source_dir, name)  # build the whole file path
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'name' is not defined
>>> # you can also check with os.path.isfile(path) to make sure it's a file you're processing
... # etc. (your mutagen update logic)
... audio = MP4(path)
Traceback (most recent call last):
  File "<stdin>", line 3, in <module>
NameError: name 'path' is not defined
>>> if i == 0:
... lookupid = audio["cnID"]
  File "<stdin>", line 2
    lookupid = audio["cnID"]
           ^
IndentationError: expected an indented block
>>> lookupid = lookupid[0]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'lookupid' is not defined
>>> break
  File "<stdin>", line 1
SyntaxError: 'break' outside loop
>>>
>>> # lookupid = int(input("AppleStoreCatalogID: "))
...
>>> print(lookupid)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'lookupid' is not defined
>>>
>>> a = ('https://itunes.apple.com/lookup?country=US&entity=song&limit=200&id=%i' % lookupid)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'lookupid' is not defined
>>> b = requests.get(a).json()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
>>>
>>> geID = b['results'][0]['primaryGenreName']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'b' is not defined
>>> geID = re.sub("Blues", '2', geID)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'geID' is not defined
>>> geID = re.sub("Comedy", '3', geID)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'geID' is not defined
>>> geID = re.sub("Children's Music", '4', geID)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'geID' is not defined
>>> geID = re.sub("Classical", '5', geID)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'geID' is not defined
>>> geID = re.sub("Country", '6', geID)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'geID' is not defined
>>> geID = re.sub("Electronic", '7', geID)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'geID' is not defined
>>> geID = re.sub("Holiday", '8', geID)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'geID' is not defined
>>> geID = re.sub("Classical|Opera", '9', geID)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'geID' is not defined
>>> geID = re.sub("Singer/Songwriter", '10', geID)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'geID' is not defined
>>> geID = re.sub("Jazz", '11', geID)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'geID' is not defined
>>> geID = re.sub("Latino", '12', geID)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'geID' is not defined
>>> geID = re.sub("New Age", '13', geID)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'geID' is not defined
>>> geID = re.sub("Pop", '14', geID)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'geID' is not defined
>>> geID = re.sub("R&B/Soul", '15', geID)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'geID' is not defined
>>> geID = re.sub("Soundtrack", '16', geID)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'geID' is not defined
>>> geID = re.sub("Dance", '17', geID)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'geID' is not defined
>>> geID = re.sub("Hip-Hop/Rap", '18', geID)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'geID' is not defined
>>> geID = re.sub("World", '19', geID)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'geID' is not defined
>>> geID = re.sub("Alternative", '20', geID)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'geID' is not defined
>>> geID = re.sub("Rock", '21', geID)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'geID' is not defined
>>> geID = re.sub("Christian & Gospel", '22', geID)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'geID' is not defined
>>> geID = re.sub("Vocal", '23', geID)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'geID' is not defined
>>> geID = re.sub("Reggae", '24', geID)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'geID' is not defined
>>> geID = re.sub("Easy Listening", '25', geID)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'geID' is not defined
>>> geID = re.sub("J-Pop", '27', geID)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'geID' is not defined
>>> geID = re.sub("Enka", '28', geID)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'geID' is not defined
>>> geID = re.sub("Anime", '29', geID)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'geID' is not defined
>>> geID = re.sub("Kayokyoku", '30', geID)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'geID' is not defined
>>> geID = int(geID)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'geID' is not defined
>>> geID = [geID]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'geID' is not defined
>>> print(geID)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'geID' is not defined
>>>
>>> atID = b['results'][0]['artistId']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'b' is not defined
>>> atID = [atID]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'atID' is not defined
>>> print(atID)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'atID' is not defined
>>>
>>> sfID = b['results'][0]['country']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'b' is not defined
>>> sfID = re.sub("ENG", '143441', sfID)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'sfID' is not defined
>>> sfID = re.sub("DEU", '143443', sfID)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'sfID' is not defined
>>> sfID = re.sub("CAN", '143455', sfID)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'sfID' is not defined
>>> sfID = int(sfID)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'sfID' is not defined
>>> sfID = [sfID]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'sfID' is not defined
>>> print(sfID)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'sfID' is not defined
>>>
>>> plID = b['results'][0]['collectionId']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'b' is not defined
>>> plID = [plID]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'plID' is not defined
>>> print(plID)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'plID' is not defined
>>>
>>>
>>>
>>> for name in os.listdir(source_dir):  # iterate over all files/directories in source_dir
... if name[-4:].lower() != ".m4a":  # ignore non-mp3 files
  File "<stdin>", line 2
    if name[-4:].lower() != ".m4a":  # ignore non-mp3 files
     ^
IndentationError: expected an indented block
>>> continue
  File "<stdin>", line 1
SyntaxError: 'continue' not properly in loop
>>> path = os.path.join(source_dir, name)  # build the whole file path
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'name' is not defined
>>> # you can also check with os.path.isfile(path) to make sure it's a file you're processing
... # etc. (your mutagen update logic)
... audio = MP4(path)
Traceback (most recent call last):
  File "<stdin>", line 3, in <module>
NameError: name 'path' is not defined
>>> audio["geID"] = geID
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'geID' is not defined
>>> audio["atID"] = atID
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'atID' is not defined
>>> audio["sfID"] = sfID
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'sfID' is not defined
>>> audio["plID"] = plID
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'plID' is not defined
>>> audio["pgap"] = False
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'audio' is not defined
>>> audio["cpil"] = False
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'audio' is not defined
>>> audio.pprint()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'audio' is not defined
>>> audio.save()

Hey
I would say your files are corrupt or there are no m4a files in the folder.
I would always check with print if it is in the variable what you expect.
So try print(name). Are there m4a files?