Skip to content

Commit 12ab913

Browse files
committed
Add salt attribute to APIC frames to allow identical descriptions
1 parent 62a7b3e commit 12ab913

File tree

2 files changed

+57
-2
lines changed

2 files changed

+57
-2
lines changed

docs/api/id3_frames.rst

+52
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,58 @@ ID3v2.3/4 Frames
5959
:show-inheritance:
6060
:members:
6161

62+
-----
63+
64+
**Examples:**
65+
66+
To set the cover image for a file you may, for example, do it this way:
67+
68+
.. code-block:: python
69+
70+
import mimetypes
71+
from mutagen.id3 import ID3, APIC, PictureType
72+
73+
image_filename = 'example.jpeg'
74+
image_mime_type = mimetypes.guess_file_type(image_filename)[0]
75+
with open(image_filename, 'rb') as f:
76+
image_data = f.read()
77+
78+
tags = ID3('example.mp3')
79+
tags.setall('APIC', [APIC(
80+
mime=image_mime_type,
81+
type=PictureType.COVER_FRONT
82+
data=image_data
83+
)])
84+
85+
Setting multiple cover images is a tad more complicated. Since tags in Mutagen are identified by their `HashKey`, each APIC needs to have a unique `HashKey`. Usually, `HashKey`\ s in Mutagen are set as ``<frame ID>:<desc>``, but this would mean that `APIC`\ s couldn't have the same description. To that end, the `APIC` class has the ``salt`` attribute, which exists only to be added to the `HashKey`\ – that is to say, `APIC`\ s' `HashKey`\ s are set as ``APIC:<desc><salt>``.
86+
87+
Thus, to add multiple cover images, you can either ensure that each `APIC` has a unique description, or you can add to ``salt``:
88+
89+
.. code-block:: python
90+
91+
import mimetypes
92+
from mutagen.id3 import ID3, APIC, PictureType
93+
94+
tags = ID3('example.mp3')
95+
96+
image_filenames = ['example.jpeg', 'example.png']
97+
for image_filename in image_filenames:
98+
image_mime_type = mimetypes.guess_file_type(image_filename)[0]
99+
with open(image_filename, 'rb') as f:
100+
image_data = f.read()
101+
102+
apic = APIC(
103+
mime=image_mime_type,
104+
type=PictureType.COVER_FRONT
105+
data=image_data
106+
)
107+
108+
while apic.HashKey in tags:
109+
apic.salt += ' '
110+
111+
tags.add(apic)
112+
113+
-----
62114

63115
.. autoclass:: mutagen.id3.ASPI(S=0, L=0, N=0, b=0, Fi=[])
64116
:show-inheritance:

mutagen/id3/_frames.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -1253,6 +1253,7 @@ class APIC(Frame):
12531253
* type -- the source of the image (3 is the album front cover)
12541254
* desc -- a text description of the image
12551255
* data -- raw image data, as a byte string
1256+
* salt -- will be added to the `HashKey`; this allows for multiple `APIC` frames with the same description
12561257
12571258
Mutagen will automatically compress large images when saving tags.
12581259
"""
@@ -1265,17 +1266,19 @@ class APIC(Frame):
12651266
BinaryDataSpec('data'),
12661267
]
12671268

1269+
salt = u''
1270+
12681271
def __eq__(self, other):
12691272
return self.data == other
12701273

12711274
__hash__ = Frame.__hash__
12721275

12731276
@property
12741277
def HashKey(self):
1275-
return '%s:%s' % (self.FrameID, self.desc)
1278+
return '%s:%s%s' % (self.FrameID, self.desc, self.salt)
12761279

12771280
def _merge_frame(self, other):
1278-
other.desc += u" "
1281+
other.salt += u' '
12791282
return other
12801283

12811284
def _pprint(self):

0 commit comments

Comments
 (0)