]>
Commit | Line | Data |
---|---|---|
ab214981 JB |
1 | --- libtunepimp-0.5.3/plugins/mp4/mp4.cpp.orig 2020-11-25 06:34:36.728698744 +0100 |
2 | +++ libtunepimp-0.5.3/plugins/mp4/mp4.cpp 2020-11-27 22:41:42.158210090 +0100 | |
3 | @@ -28,7 +28,7 @@ | |
4 | #include <string.h> | |
5 | #include <stdio.h> | |
6 | #include <stdlib.h> | |
7 | -#include <mp4.h> | |
8 | +#include <mp4v2/mp4v2.h> | |
9 | #include "metadata.h" | |
10 | #include "plugin.h" | |
11 | #ifndef WIN32 | |
12 | @@ -44,7 +44,7 @@ | |
13 | #define PLUGIN_VERSION "1.0.0" | |
14 | #define PLUGIN_NAME "MP4 metadata reader/writer" | |
15 | ||
16 | -static char *formats[][2] = { | |
17 | +static const char *formats[][2] = { | |
18 | { ".aac", "AAC/MP4" }, | |
19 | { ".mp4", "MP4" }, | |
20 | { ".m4a", "MP4" }, | |
21 | @@ -54,13 +54,11 @@ | |
22 | ||
23 | #define NUM_FORMATS 5 | |
24 | ||
25 | -static char *errorString = ""; | |
26 | +static const char *errorString = ""; | |
27 | ||
28 | static void | |
29 | mp4Shutdown() | |
30 | { | |
31 | - if (strlen(errorString)) | |
32 | - free(errorString); | |
33 | } | |
34 | ||
35 | static const char * | |
36 | @@ -101,14 +99,50 @@ | |
37 | return errorString; | |
38 | } | |
39 | ||
40 | +static MP4ItmfItemList* | |
41 | +mp4GetItmfItemValue(MP4FileHandle mp4file, const char *tagName, const char **value) | |
42 | +{ | |
43 | + MP4ItmfItemList *items = MP4ItmfGetItemsByMeaning(mp4file, "com.apple.iTunes", tagName); | |
44 | + if (items != NULL) { | |
45 | + if (items->size == 0) { | |
46 | + MP4ItmfItemListFree(items); | |
47 | + return NULL; | |
48 | + } | |
49 | + if (items->elements[0].dataList.size == 0) { | |
50 | + MP4ItmfItemListFree(items); | |
51 | + return NULL; | |
52 | + } | |
53 | + *value = reinterpret_cast<const char*>(items->elements[0].dataList.elements[0].value); | |
54 | + } | |
55 | + return items; | |
56 | +} | |
57 | + | |
58 | +void | |
59 | +mp4SetItmfItemValue(MP4FileHandle mp4file, const char *tagName, const char *value, size_t size) | |
60 | +{ | |
61 | + MP4ItmfItemList *items = MP4ItmfGetItemsByMeaning(mp4file, "com.apple.iTunes", tagName); | |
62 | + if (items != NULL) { | |
63 | + for (size_t idx = 0; idx < items->size; idx++) | |
64 | + MP4ItmfRemoveItem(mp4file, items->elements + idx); | |
65 | + MP4ItmfItemListFree(items); | |
66 | + } | |
67 | + | |
68 | + MP4ItmfItem *item = MP4ItmfItemAlloc("----", 1); | |
69 | + item->mean = strdup("com.apple.iTunes"); | |
70 | + item->name = strdup(tagName); | |
71 | + item->dataList.elements[0].typeCode = MP4_ITMF_BT_UTF8; | |
72 | + item->dataList.elements[0].valueSize = size; | |
73 | + item->dataList.elements[0].value = (uint8_t*)malloc(size); | |
74 | + memcpy(item->dataList.elements[0].value, value, size); | |
75 | + MP4ItmfAddItem(mp4file, item); | |
76 | +} | |
77 | + | |
78 | static int | |
79 | mp4ReadMetadata(metadata_t *mdata, const char *fileName, int flags, const char *encoding) | |
80 | { | |
81 | - char *value; | |
82 | - u_int16_t numval, numval2; | |
83 | - u_int8_t numval3; | |
84 | - u_int32_t size; | |
85 | MP4FileHandle mp4file; | |
86 | + MP4ItmfItemList *items; | |
87 | + const char *value; | |
88 | ||
89 | #ifndef WIN32 | |
90 | mp4file = MP4Read(utf8ToEncoding(fileName, encoding).c_str()); | |
91 | @@ -120,95 +154,100 @@ | |
92 | return 0; | |
93 | ||
94 | memset(mdata, 0, sizeof(metadata_t)); | |
95 | - | |
96 | - if (MP4GetMetadataName(mp4file, &value) && value != NULL) { | |
97 | - strcpy(mdata->track, value); | |
98 | - free(value); | |
99 | - } | |
100 | ||
101 | - if (MP4GetMetadataArtist(mp4file, &value) && value != NULL) { | |
102 | - strcpy(mdata->artist, value); | |
103 | - free(value); | |
104 | - } | |
105 | + const MP4Tags *tags = MP4TagsAlloc(); | |
106 | + if (MP4TagsFetch(tags, mp4file)) { | |
107 | + if (tags->name) | |
108 | + strcpy(mdata->track, tags->name); | |
109 | + | |
110 | + if (tags->artist) | |
111 | + strcpy(mdata->artist, tags->artist); | |
112 | + | |
113 | + if (tags->releaseDate) | |
114 | + mdata->releaseYear = atoi(tags->releaseDate); // ignore errors, so will stop on "-" after YYYY[-MM-DD] | |
115 | + | |
116 | + if (tags->album) | |
117 | + strcpy(mdata->album, tags->album); | |
118 | + | |
119 | + if (tags->track) { | |
120 | + mdata->trackNum = tags->track->index; | |
121 | + mdata->totalInSet = tags->track->total; | |
122 | + } | |
123 | ||
124 | - if (MP4GetMetadataYear(mp4file, &value) && value != NULL) { | |
125 | - mdata->releaseYear = strtol(value, NULL, 0); | |
126 | - free(value); | |
127 | - } | |
128 | + if (tags->compilation) | |
129 | + mdata->variousArtist = *(tags->compilation); | |
130 | ||
131 | - if (MP4GetMetadataAlbum(mp4file, &value) && value != NULL) { | |
132 | - strcpy(mdata->album, value); | |
133 | - free(value); | |
134 | - } | |
135 | - | |
136 | - if (MP4GetMetadataTrack(mp4file, &numval, &numval2)) { | |
137 | - mdata->trackNum = numval; | |
138 | - mdata->totalInSet = numval2; | |
139 | + MP4TagsFree(tags); | |
140 | } | |
141 | ||
142 | - if (MP4GetMetadataFreeForm(mp4file, "MusicBrainz Sortname", (u_int8_t **)&value, &size) && value != NULL) { | |
143 | + if ((items = mp4GetItmfItemValue(mp4file, "MusicBrainz Sortname", &value)) != NULL) { | |
144 | strcpy(mdata->sortName, value); | |
145 | - free(value); | |
146 | + MP4ItmfItemListFree(items); | |
147 | } | |
148 | ||
149 | - if (MP4GetMetadataFreeForm(mp4file, "MusicBrainz Track Id", (u_int8_t **)&value, &size) && value != NULL) { | |
150 | + if ((items = mp4GetItmfItemValue(mp4file, "MusicBrainz Track Id", &value)) != NULL) { | |
151 | strcpy(mdata->trackId, value); | |
152 | - free(value); | |
153 | + MP4ItmfItemListFree(items); | |
154 | } | |
155 | ||
156 | - if (MP4GetMetadataFreeForm(mp4file, "MusicBrainz Album Id", (u_int8_t **)&value, &size) && value != NULL) { | |
157 | + if ((items = mp4GetItmfItemValue(mp4file, "MusicBrainz Album Id", &value)) != NULL) { | |
158 | strcpy(mdata->albumId, value); | |
159 | - free(value); | |
160 | + MP4ItmfItemListFree(items); | |
161 | } | |
162 | ||
163 | - if (MP4GetMetadataFreeForm(mp4file, "MusicBrainz Artist Id", (u_int8_t **)&value, &size) && value != NULL) { | |
164 | + if ((items = mp4GetItmfItemValue(mp4file, "MusicBrainz Artist Id", &value)) != NULL) { | |
165 | strcpy(mdata->artistId, value); | |
166 | - free(value); | |
167 | + MP4ItmfItemListFree(items); | |
168 | } | |
169 | - | |
170 | - if (MP4GetMetadataFreeForm(mp4file, "MusicIP PUID", (u_int8_t **)&value, &size) && value != NULL) { | |
171 | + | |
172 | + if ((items = mp4GetItmfItemValue(mp4file, "MusicIP PUID", &value)) != NULL) { | |
173 | strcpy(mdata->filePUID, value); | |
174 | - free(value); | |
175 | + MP4ItmfItemListFree(items); | |
176 | } | |
177 | ||
178 | - if (MP4GetMetadataFreeForm(mp4file, "MusicBrainz Album Artist Id", (u_int8_t **)&value, &size) && value != NULL) { | |
179 | + if ((items = mp4GetItmfItemValue(mp4file, "MusicBrainz Album Artist Id", &value)) != NULL) { | |
180 | strcpy(mdata->albumArtistId, value); | |
181 | - free(value); | |
182 | + MP4ItmfItemListFree(items); | |
183 | } | |
184 | ||
185 | - if (MP4GetMetadataFreeForm(mp4file, "MusicBrainz Album Artist Sortname", (u_int8_t **)&value, &size) && value != NULL) { | |
186 | + if ((items = mp4GetItmfItemValue(mp4file, "MusicBrainz Album Artist Sortname", &value)) != NULL) { | |
187 | strcpy(mdata->albumArtistSortName, value); | |
188 | - free(value); | |
189 | + MP4ItmfItemListFree(items); | |
190 | } | |
191 | ||
192 | - if (MP4GetMetadataFreeForm(mp4file, "MusicBrainz Album Artist", (u_int8_t **)&value, &size) && value != NULL) { | |
193 | + if ((items = mp4GetItmfItemValue(mp4file, "MusicBrainz Album Artist", &value)) != NULL) { | |
194 | strcpy(mdata->albumArtist, value); | |
195 | - free(value); | |
196 | + MP4ItmfItemListFree(items); | |
197 | } | |
198 | ||
199 | - if (MP4GetMetadataFreeForm(mp4file, "MusicBrainz Album Type", (u_int8_t **)&value, &size) && value != NULL) { | |
200 | + if ((items = mp4GetItmfItemValue(mp4file, "MusicBrainz Album Type", &value)) != NULL) { | |
201 | mdata->albumType = convertToAlbumType(value); | |
202 | - free(value); | |
203 | + MP4ItmfItemListFree(items); | |
204 | } | |
205 | - | |
206 | - if (MP4GetMetadataFreeForm(mp4file, "MusicBrainz Album Status", (u_int8_t **)&value, &size) && value != NULL) { | |
207 | + | |
208 | + if ((items = mp4GetItmfItemValue(mp4file, "MusicBrainz Album Status", &value)) != NULL) { | |
209 | mdata->albumStatus = convertToAlbumStatus(value); | |
210 | - free(value); | |
211 | + MP4ItmfItemListFree(items); | |
212 | } | |
213 | - | |
214 | - if (MP4GetMetadataFreeForm(mp4file, "MusicBrainz Album Release Date", (u_int8_t **)&value, &size) && value != NULL) { | |
215 | + | |
216 | + if ((items = mp4GetItmfItemValue(mp4file, "MusicBrainz Album Release Date", &value)) != NULL) { | |
217 | int year = 0, month = 0, day = 0; | |
218 | if (sscanf(value, "%04d-%02d-%02d", &year, &month, &day) > 0) { | |
219 | mdata->releaseYear = year; | |
220 | mdata->releaseMonth = month; | |
221 | mdata->releaseDay = day; | |
222 | } | |
223 | - free(value); | |
224 | + MP4ItmfItemListFree(items); | |
225 | } | |
226 | ||
227 | - if (MP4GetMetadataFreeForm(mp4file, "MusicBrainz Album Release Country", (u_int8_t **)&value, &size) && value != NULL) { | |
228 | + if ((items = mp4GetItmfItemValue(mp4file, "MusicBrainz Album Release Country", &value)) != NULL) { | |
229 | strcpy(mdata->releaseCountry, value); | |
230 | - free(value); | |
231 | + MP4ItmfItemListFree(items); | |
232 | + } | |
233 | + | |
234 | + if ((items = mp4GetItmfItemValue(mp4file, "MusicBrainz Non-Album", &value)) != NULL) { | |
235 | + mdata->nonAlbum = atoi(value); | |
236 | + MP4ItmfItemListFree(items); | |
237 | } | |
238 | ||
239 | u_int32_t numTracks = MP4GetNumberOfTracks(mp4file); | |
240 | @@ -221,19 +260,9 @@ | |
241 | } | |
242 | } | |
243 | ||
244 | - if (MP4GetMetadataCompilation(mp4file, &numval3)) { | |
245 | - mdata->variousArtist = numval3; | |
246 | - } | |
247 | - | |
248 | - if (MP4GetMetadataFreeForm(mp4file, "MusicBrainz Non-Album", (u_int8_t **)&value, &size) && value != NULL) { | |
249 | - mdata->nonAlbum = atoi(value); | |
250 | - free(value); | |
251 | - } | |
252 | - | |
253 | strcpy(mdata->fileFormat, fileName + strlen(fileName) - 3); | |
254 | ||
255 | - if (!MP4Close(mp4file)) | |
256 | - return 0; | |
257 | + MP4Close(mp4file); | |
258 | ||
259 | return 1; | |
260 | } | |
261 | @@ -255,41 +284,54 @@ | |
262 | if (mp4file == MP4_INVALID_FILE_HANDLE) | |
263 | return 0; | |
264 | ||
265 | - if ((flags & TP_PLUGIN_FLAGS_GENERAL_CLEAR_TAGS) != 0) | |
266 | - MP4MetadataDelete(mp4file); | |
267 | - | |
268 | - MP4SetMetadataName(mp4file, mdata->track); | |
269 | + if ((flags & TP_PLUGIN_FLAGS_GENERAL_CLEAR_TAGS) != 0) { | |
270 | + MP4ItmfItemList* items = MP4ItmfGetItems(mp4file); | |
271 | + if (items != NULL) { | |
272 | + for (size_t idx = 0; idx < items->size; idx++) | |
273 | + MP4ItmfRemoveItem(mp4file, items->elements + idx); | |
274 | + MP4ItmfItemListFree(items); | |
275 | + } | |
276 | + } | |
277 | + | |
278 | + const MP4Tags* mp4tags = MP4TagsAlloc(); | |
279 | + if (MP4TagsFetch(mp4tags, mp4file)) { | |
280 | + MP4TagsSetName(mp4tags, mdata->track); | |
281 | ||
282 | - MP4SetMetadataArtist(mp4file, mdata->artist); | |
283 | + MP4TagsSetArtist(mp4tags, mdata->artist); | |
284 | ||
285 | sprintf(temp, "%04d", mdata->releaseYear); | |
286 | - MP4SetMetadataYear(mp4file, temp); | |
287 | + MP4TagsSetReleaseDate(mp4tags, temp); | |
288 | ||
289 | - MP4SetMetadataAlbum(mp4file, mdata->album); | |
290 | + MP4TagsSetAlbum(mp4tags, mdata->album); | |
291 | ||
292 | - MP4SetMetadataTrack(mp4file, mdata->trackNum, mdata->totalInSet); | |
293 | + MP4TagTrack tagTrack = {mdata->trackNum, mdata->totalInSet}; | |
294 | + MP4TagsSetTrack(mp4tags, &tagTrack); | |
295 | + | |
296 | + uint8_t compilation = mdata->variousArtist ? 1 : 0; | |
297 | + MP4TagsSetCompilation(mp4tags, &compilation); | |
298 | + } | |
299 | ||
300 | - MP4SetMetadataFreeForm(mp4file, "MusicBrainz Sortname", (u_int8_t *)mdata->sortName, strlen(mdata->sortName) + 1); | |
301 | + mp4SetItmfItemValue(mp4file, "MusicBrainz Sortname", mdata->sortName, strlen(mdata->sortName) + 1); | |
302 | ||
303 | - MP4SetMetadataFreeForm(mp4file, "MusicBrainz Track Id", (u_int8_t *)mdata->trackId, strlen(mdata->trackId) + 1); | |
304 | + mp4SetItmfItemValue(mp4file, "MusicBrainz Track Id", mdata->trackId, strlen(mdata->trackId) + 1); | |
305 | ||
306 | - MP4SetMetadataFreeForm(mp4file, "MusicBrainz Album Id", (u_int8_t *)mdata->albumId, strlen(mdata->albumId) + 1); | |
307 | + mp4SetItmfItemValue(mp4file, "MusicBrainz Album Id", mdata->albumId, strlen(mdata->albumId) + 1); | |
308 | ||
309 | - MP4SetMetadataFreeForm(mp4file, "MusicBrainz Artist Id", (u_int8_t *)mdata->artistId, strlen(mdata->artistId) + 1); | |
310 | + mp4SetItmfItemValue(mp4file, "MusicBrainz Artist Id", mdata->artistId, strlen(mdata->artistId) + 1); | |
311 | ||
312 | - MP4SetMetadataFreeForm(mp4file, "MusicIP PUID", (u_int8_t *)mdata->filePUID, strlen(mdata->filePUID) + 1); | |
313 | + mp4SetItmfItemValue(mp4file, "MusicIP PUID", mdata->filePUID, strlen(mdata->filePUID) + 1); | |
314 | ||
315 | - MP4SetMetadataFreeForm(mp4file, "MusicBrainz Album Artist Id", (u_int8_t *)mdata->albumArtistId, strlen(mdata->albumArtistId) + 1); | |
316 | + mp4SetItmfItemValue(mp4file, "MusicBrainz Album Artist Id", mdata->albumArtistId, strlen(mdata->albumArtistId) + 1); | |
317 | ||
318 | - MP4SetMetadataFreeForm(mp4file, "MusicBrainz Album Artist Sortname", (u_int8_t *)mdata->albumArtistSortName, strlen(mdata->albumArtistSortName) + 1); | |
319 | + mp4SetItmfItemValue(mp4file, "MusicBrainz Album Artist Sortname", mdata->albumArtistSortName, strlen(mdata->albumArtistSortName) + 1); | |
320 | ||
321 | - MP4SetMetadataFreeForm(mp4file, "MusicBrainz Album Artist", (u_int8_t *)mdata->albumArtist, strlen(mdata->albumArtist) + 1); | |
322 | + mp4SetItmfItemValue(mp4file, "MusicBrainz Album Artist", mdata->albumArtist, strlen(mdata->albumArtist) + 1); | |
323 | ||
324 | convertFromAlbumType(mdata->albumType, temp2); | |
325 | - MP4SetMetadataFreeForm(mp4file, "MusicBrainz Album Type", (u_int8_t *)temp2.c_str(), temp2.length() + 1); | |
326 | + mp4SetItmfItemValue(mp4file, "MusicBrainz Album Type", temp2.c_str(), temp2.length() + 1); | |
327 | ||
328 | convertFromAlbumStatus(mdata->albumStatus, temp2); | |
329 | - MP4SetMetadataFreeForm(mp4file, "MusicBrainz Album Status", (u_int8_t *)temp2.c_str(), temp2.length() + 1); | |
330 | + mp4SetItmfItemValue(mp4file, "MusicBrainz Album Status", temp2.c_str(), temp2.length() + 1); | |
331 | ||
332 | if (mdata->releaseYear > 0) { | |
333 | if (mdata->releaseMonth > 0) { | |
334 | @@ -307,17 +349,14 @@ | |
335 | else { | |
336 | strcpy(temp, ""); | |
337 | } | |
338 | - MP4SetMetadataFreeForm(mp4file, "MusicBrainz Album Release Date", (u_int8_t *)temp, strlen(temp) + 1); | |
339 | + mp4SetItmfItemValue(mp4file, "MusicBrainz Album Release Date", temp, strlen(temp) + 1); | |
340 | ||
341 | - MP4SetMetadataFreeForm(mp4file, "MusicBrainz Album Release Country", (u_int8_t *)mdata->releaseCountry, strlen(mdata->releaseCountry) + 1); | |
342 | - | |
343 | - MP4SetMetadataCompilation(mp4file, mdata->variousArtist ? 1 : 0); | |
344 | + mp4SetItmfItemValue(mp4file, "MusicBrainz Album Release Country", mdata->releaseCountry, strlen(mdata->releaseCountry) + 1); | |
345 | ||
346 | sprintf(temp, "%d", mdata->nonAlbum); | |
347 | - MP4SetMetadataFreeForm(mp4file, "MusicBrainz Non-Album", (u_int8_t *)temp, strlen(temp) + 1); | |
348 | + mp4SetItmfItemValue(mp4file, "MusicBrainz Non-Album", temp, strlen(temp) + 1); | |
349 | ||
350 | - if (!MP4Close(mp4file)) | |
351 | - return 0; | |
352 | + MP4Close(mp4file); | |
353 | ||
354 | #ifndef WIN32 | |
355 | if (!MP4Optimize(utf8ToEncoding(fileName, encoding).c_str())) |