Reputation: 77
I am attempting to set custom ID3 tags on MP4 files using Python and Mutagen. So far I have been able to create custom tags for MP3 files without any issues, but MP4 seems to be another issue altogether.
The initial error message I received was a TypeError stating that "can't concat str to bytes". So instead of feeding the program a string I encoded it as a UTF-8 bytearray but it gave this error message:
TypeError: object of type 'int' has no len()
This error actually occurs within Mutagen itself.
Here is the code:
from mutagen.id3 import ID3
from mutagen.mp4 import MP4
def set_isbn(filename, isbn):
if(filename.lower().endswith(".mp3")):
tags = ID3(filename)
tags.add(TXXX(encoding=3, desc=u'ISBN', text=str(isbn)))
tags.save(filename)
else:
tags = MP4(filename)
tags["----:TXXX:ISBN"] = bytearray(isbn, 'UTF-8')
tags.save(filename)
The Mutagen docs are mostly very good but when it comes to custom MP4 tags all it states is the general setup of the mean:name:key. Has anyone else ever been able to successfully implement custom tags for MP4 files?
Upvotes: 1
Views: 2776
Reputation: 2005
Important things first: the only problem in your code is the conversion from string
to bytearray
. Taking a look at the source code of mutagen
, in the part concerning specifically the mp4
file type, there is a line that looks like this:
...
if isinstance(x, bytes):
x = [x]
...
where x
is the value you supply. When the above condition is met, the value you gave is inserted inside a list
, which has a "dunder len" method, hence can be the argument of the len
function, that in turn will not raise TypeError
when used as argument.
You should only edit your code by replacing the conversion to bytearray
with the one to bytes
as follows:
from mutagen.id3 import ID3
from mutagen.mp4 import MP4
def set_isbn(filename, isbn):
if(filename.lower().endswith(".mp3")):
tags = ID3(filename)
tags.add(TXXX(encoding=3, desc=u'ISBN', text=str(isbn)))
tags.save(filename)
else:
tags = MP4(filename)
tags["----:TXXX:ISBN"] = bytes(isbn, 'UTF-8')
tags.save(filename)
You will then avoid the above TypeError
exception.
Upvotes: 2