diff -uNr easytag-2.1.7/src/mp4_header.c easytag-2.1.7-mp4v2-build/src/mp4_header.c
old
|
new
|
|
204 | 204 | /* Get size of file */ |
205 | 205 | ETFileInfo->size = Get_File_Size(filename); |
206 | 206 | |
207 | | if ((file = MP4Read(filename, 0)) == MP4_INVALID_FILE_HANDLE ) |
| 207 | if ((file = MP4Read(filename)) == MP4_INVALID_FILE_HANDLE ) |
208 | 208 | { |
209 | 209 | gchar *filename_utf8 = filename_to_display(filename); |
210 | 210 | //g_print(_("ERROR while opening file: '%s' (%s)."),filename_utf8,g_strerror(errno)); |
… |
… |
|
218 | 218 | { |
219 | 219 | gchar *filename_utf8 = filename_to_display(filename); |
220 | 220 | Log_Print(LOG_ERROR,_("ERROR while opening file: '%s' (%s)."),filename_utf8,("Contains no audio track")); |
221 | | MP4Close(file); |
| 221 | MP4Close(file, 0); |
222 | 222 | g_free(filename_utf8); |
223 | 223 | return FALSE; |
224 | 224 | } |
… |
… |
|
243 | 243 | ETFileInfo->mode = MP4GetTrackAudioChannels(file, trackId); |
244 | 244 | ETFileInfo->duration = MP4ConvertFromTrackDuration(file, trackId, MP4GetTrackDuration(file, trackId), MP4_SECS_TIME_SCALE); |
245 | 245 | |
246 | | MP4Close(file); |
| 246 | MP4Close(file, 0); |
247 | 247 | return TRUE; |
248 | 248 | } |
249 | 249 | |
diff -uNr easytag-2.1.7/src/mp4_tag.c easytag-2.1.7-mp4v2-build/src/mp4_tag.c
old
|
new
|
|
72 | 72 | * |
73 | 73 | * Read tag data into an Mp4 file. |
74 | 74 | * |
| 75 | * cf. http://mp4v2.googlecode.com/svn/doc/1.9.0/api/example_2itmf_2tags_8c-example.html |
| 76 | * |
75 | 77 | * Note: |
76 | 78 | * - for string fields, //if field is found but contains no info (strlen(str)==0), we don't read it |
77 | 79 | * - for track numbers, if they are zero, then we don't read it |
… |
… |
|
80 | 82 | { |
81 | 83 | FILE *file; |
82 | 84 | MP4FileHandle mp4file = NULL; |
| 85 | const MP4Tags *mp4tags = NULL; |
83 | 86 | uint16_t track, track_total; |
84 | 87 | uint16_t disk, disktotal; |
85 | | u_int8_t *coverArt; |
86 | | u_int32_t coverSize; |
87 | 88 | Picture *prev_pic = NULL; |
88 | | #ifdef NEWMP4 |
89 | | gint pic_num; |
90 | | #endif |
| 89 | int pic_num; |
| 90 | const MP4TagArtwork *mp4artwork = NULL; |
91 | 91 | |
92 | 92 | if (!filename || !FileTag) |
93 | 93 | return FALSE; |
… |
… |
|
102 | 102 | fclose(file); // We close it cause mp4 opens/closes file itself |
103 | 103 | |
104 | 104 | /* Get data from tag */ |
105 | | mp4file = MP4Read(filename, 0); |
| 105 | mp4file = MP4Read(filename); |
106 | 106 | if (mp4file == MP4_INVALID_FILE_HANDLE) |
107 | 107 | { |
108 | 108 | gchar *filename_utf8 = filename_to_display(filename); |
… |
… |
|
111 | 111 | return FALSE; |
112 | 112 | } |
113 | 113 | |
| 114 | mp4tags = MP4TagsAlloc(); |
| 115 | if (!MP4TagsFetch(mp4tags, mp4file)) |
| 116 | { |
| 117 | gchar *filename_utf8 = filename_to_display(filename); |
| 118 | Log_Print(LOG_ERROR,_("ERROR reading tags from file: '%s' (%s)."),filename_utf8,_("MP4 format invalid")); |
| 119 | g_free(filename_utf8); |
| 120 | return FALSE; |
| 121 | } |
| 122 | |
114 | 123 | /* TODO Add error detection */ |
115 | 124 | |
116 | 125 | /********* |
117 | 126 | * Title * |
118 | 127 | *********/ |
119 | | MP4GetMetadataName(mp4file, &FileTag->title); |
| 128 | if (mp4tags->name) |
| 129 | FileTag->title = g_strdup(mp4tags->name); |
120 | 130 | |
121 | 131 | /********** |
122 | 132 | * Artist * |
123 | 133 | **********/ |
124 | | MP4GetMetadataArtist(mp4file, &FileTag->artist); |
| 134 | if (mp4tags->artist) |
| 135 | FileTag->artist = g_strdup(mp4tags->artist); |
125 | 136 | |
126 | 137 | /********* |
127 | 138 | * Album * |
128 | 139 | *********/ |
129 | | MP4GetMetadataAlbum(mp4file, &FileTag->album); |
| 140 | if (mp4tags->album) |
| 141 | FileTag->album = g_strdup(mp4tags->album); |
| 142 | |
| 143 | /**************** |
| 144 | * Album Artist * |
| 145 | ****************/ |
| 146 | if (mp4tags->albumArtist) |
| 147 | FileTag->album_artist = g_strdup(mp4tags->albumArtist); |
130 | 148 | |
131 | 149 | /********************** |
132 | 150 | * Disk / Total Disks * |
133 | 151 | **********************/ |
134 | | if (MP4GetMetadataDisk(mp4file, &disk, &disktotal)) |
| 152 | if (mp4tags->disk) |
135 | 153 | { |
| 154 | disk = mp4tags->disk->index, disktotal = mp4tags->disk->total; |
136 | 155 | if (disk != 0 && disktotal != 0) |
137 | 156 | FileTag->disc_number = g_strdup_printf("%d/%d",(gint)disk,(gint)disktotal); |
138 | 157 | else if (disk != 0) |
… |
… |
|
146 | 165 | /******** |
147 | 166 | * Year * |
148 | 167 | ********/ |
149 | | MP4GetMetadataYear(mp4file, &FileTag->year); |
| 168 | if (mp4tags->releaseDate) |
| 169 | FileTag->year = g_strdup(mp4tags->releaseDate); |
150 | 170 | |
151 | 171 | /************************* |
152 | 172 | * Track and Total Track * |
153 | 173 | *************************/ |
154 | | if (MP4GetMetadataTrack(mp4file, &track, &track_total)) |
| 174 | if (mp4tags->track) |
155 | 175 | { |
| 176 | |
| 177 | track = mp4tags->track->index, track_total = mp4tags->track->total; |
156 | 178 | if (track != 0) |
157 | | FileTag->track = g_strdup_printf("%.*d",NUMBER_TRACK_FORMATED_SPIN_BUTTON,(gint)track); // Just to have numbers like this : '01', '05', '12', ... |
| 179 | FileTag->track = NUMBER_TRACK_FORMATED ? g_strdup_printf("%.*d",NUMBER_TRACK_FORMATED_SPIN_BUTTON,(gint)track) : g_strdup_printf("%d",(gint)track); |
158 | 180 | if (track_total != 0) |
159 | | FileTag->track_total = g_strdup_printf("%.*d",NUMBER_TRACK_FORMATED_SPIN_BUTTON,(gint)track_total); // Just to have numbers like this : '01', '05', '12', ... |
| 181 | FileTag->track_total = NUMBER_TRACK_FORMATED ? g_strdup_printf("%.*d",NUMBER_TRACK_FORMATED_SPIN_BUTTON,(gint)track_total) : g_strdup_printf("%d",(gint)track_total); |
160 | 182 | } |
161 | 183 | |
162 | 184 | /********* |
163 | 185 | * Genre * |
164 | 186 | *********/ |
165 | | MP4GetMetadataGenre(mp4file, &FileTag->genre); |
| 187 | if (mp4tags->genre) |
| 188 | FileTag->genre = g_strdup(mp4tags->genre); |
166 | 189 | |
167 | 190 | /*********** |
168 | 191 | * Comment * |
169 | 192 | ***********/ |
170 | | MP4GetMetadataComment(mp4file, &FileTag->comment); |
| 193 | if (mp4tags->comments) |
| 194 | FileTag->comment = g_strdup(mp4tags->comments); |
171 | 195 | |
172 | 196 | /********************** |
173 | 197 | * Composer or Writer * |
174 | 198 | **********************/ |
175 | | MP4GetMetadataWriter(mp4file, &FileTag->composer); |
| 199 | if (mp4tags->composer) |
| 200 | FileTag->composer = g_strdup(mp4tags->composer); |
176 | 201 | |
177 | 202 | /***************** |
178 | 203 | * Encoding Tool * |
179 | 204 | *****************/ |
180 | | MP4GetMetadataTool(mp4file, &FileTag->encoded_by); |
| 205 | if (mp4tags->encodedBy) |
| 206 | FileTag->encoded_by = g_strdup(mp4tags->encodedBy); |
181 | 207 | |
182 | 208 | /* Unimplemented |
183 | 209 | Tempo / BPM |
… |
… |
|
187 | 213 | /*********** |
188 | 214 | * Picture * |
189 | 215 | ***********/ |
190 | | #ifdef NEWMP4 |
191 | | // There version can handle multiple pictures! |
192 | | // Version 1.6 of libmp4v2 introduces an index argument for MP4GetMetadataCoverart |
193 | | for (pic_num = 0; (MP4GetMetadataCoverArt( mp4file, &coverArt, &coverSize,pic_num )); pic_num++) |
194 | | #else |
195 | | // There version handle only one picture! |
196 | | if ( MP4GetMetadataCoverArt( mp4file, &coverArt, &coverSize ) ) |
197 | | #endif |
| 216 | // Version 1.9.1 of mp4v2 and up handle multiple cover art |
| 217 | mp4artwork = mp4tags->artwork; |
| 218 | for (pic_num = 0; pic_num < mp4tags->artworkCount; ++pic_num, ++mp4artwork) |
198 | 219 | { |
199 | 220 | Picture *pic; |
200 | 221 | |
… |
… |
|
205 | 226 | prev_pic->next = pic; |
206 | 227 | prev_pic = pic; |
207 | 228 | |
208 | | pic->size = coverSize; |
209 | | pic->data = coverArt; |
210 | | pic->type = PICTURE_TYPE_FRONT_COVER; |
| 229 | pic->size = mp4artwork->size; |
| 230 | pic->data = g_memdup(mp4artwork->data, pic->size); |
| 231 | pic->type = PICTURE_TYPE_FRONT_COVER;/* mp4artwork->type gives image type */ |
211 | 232 | pic->description = NULL; |
212 | 233 | } |
213 | 234 | |
214 | 235 | |
215 | 236 | /* Free allocated data */ |
216 | | MP4Close(mp4file); |
| 237 | MP4TagsFree(mp4tags); |
| 238 | MP4Close(mp4file, 0); |
217 | 239 | |
218 | 240 | return TRUE; |
219 | 241 | } |
… |
… |
|
234 | 256 | gchar *filename_utf8; |
235 | 257 | FILE *file; |
236 | 258 | MP4FileHandle mp4file = NULL; |
| 259 | const MP4Tags *mp4tags = NULL; |
| 260 | MP4TagDisk mp4disk; |
| 261 | MP4TagTrack mp4track; |
| 262 | MP4TagArtwork mp4artwork; |
237 | 263 | gint error = 0; |
238 | 264 | |
| 265 | /* extra initializers */ |
| 266 | mp4disk.index = 0; |
| 267 | mp4disk.total = 0; |
| 268 | mp4track.index = 0; |
| 269 | mp4track.total = 0; |
| 270 | |
239 | 271 | if (!ETFile || !ETFile->FileTag) |
240 | 272 | return FALSE; |
241 | 273 | |
… |
… |
|
252 | 284 | fclose(file); |
253 | 285 | |
254 | 286 | /* Open file for writing */ |
255 | | mp4file = MP4Modify(filename,0,0); |
| 287 | mp4file = MP4Modify(filename, 0); |
256 | 288 | if (mp4file == MP4_INVALID_FILE_HANDLE) |
257 | 289 | { |
258 | 290 | Log_Print(LOG_ERROR,_("ERROR while opening file: '%s' (%s)."),filename_utf8,_("MP4 format invalid")); |
259 | 291 | return FALSE; |
260 | 292 | } |
261 | 293 | |
| 294 | mp4tags = MP4TagsAlloc(); |
| 295 | if (!MP4TagsFetch(mp4tags, mp4file)) |
| 296 | { |
| 297 | Log_Print(LOG_ERROR,_("ERROR reading tags from file: '%s' (%s)."),filename_utf8,_("MP4 format invalid")); |
| 298 | return FALSE; |
| 299 | } |
| 300 | |
262 | 301 | /********* |
263 | 302 | * Title * |
264 | 303 | *********/ |
265 | 304 | if (FileTag->title && g_utf8_strlen(FileTag->title, -1) > 0) |
266 | 305 | { |
267 | | MP4SetMetadataName(mp4file, FileTag->title); |
| 306 | MP4TagsSetName(mp4tags, FileTag->title); |
268 | 307 | }else |
269 | 308 | { |
270 | | //MP4DeleteMetadataName(mp4file); // Not available on mpeg4ip-1.2 (only in 1.3) |
271 | | MP4SetMetadataName(mp4file, ""); |
| 309 | MP4TagsSetName(mp4tags, ""); |
272 | 310 | } |
273 | 311 | |
274 | 312 | /********** |
… |
… |
|
276 | 314 | **********/ |
277 | 315 | if (FileTag->artist && g_utf8_strlen(FileTag->artist, -1) > 0) |
278 | 316 | { |
279 | | MP4SetMetadataArtist(mp4file, FileTag->artist); |
| 317 | MP4TagsSetArtist(mp4tags, FileTag->artist); |
280 | 318 | }else |
281 | 319 | { |
282 | | //MP4DeleteMetadataArtist(mp4file); |
283 | | MP4SetMetadataArtist(mp4file, ""); |
| 320 | MP4TagsSetArtist(mp4tags, ""); |
284 | 321 | } |
285 | 322 | |
286 | 323 | /********* |
… |
… |
|
288 | 325 | *********/ |
289 | 326 | if (FileTag->album && g_utf8_strlen(FileTag->album, -1) > 0) |
290 | 327 | { |
291 | | MP4SetMetadataAlbum(mp4file, FileTag->album); |
| 328 | MP4TagsSetAlbum(mp4tags, FileTag->album); |
292 | 329 | }else |
293 | 330 | { |
294 | | //MP4DeleteMetadataAlbum(mp4file); |
295 | | MP4SetMetadataAlbum(mp4file, ""); |
| 331 | MP4TagsSetAlbum(mp4tags, ""); |
| 332 | } |
| 333 | |
| 334 | /**************** |
| 335 | * Album Artist * |
| 336 | ****************/ |
| 337 | if (FileTag->album_artist && g_utf8_strlen(FileTag->album_artist, -1) > 0) |
| 338 | { |
| 339 | MP4TagsSetAlbumArtist(mp4tags, FileTag->album_artist); |
| 340 | }else |
| 341 | { |
| 342 | MP4TagsSetAlbumArtist(mp4tags, ""); |
296 | 343 | } |
297 | 344 | |
298 | 345 | /********************** |
… |
… |
|
301 | 348 | if (FileTag->disc_number && g_utf8_strlen(FileTag->disc_number, -1) > 0) |
302 | 349 | //|| FileTag->disc_number_total && g_utf8_strlen(FileTag->disc_number_total, -1) > 0) |
303 | 350 | { |
304 | | uint16_t disk = 0; |
305 | | uint16_t disktotal = 0; |
306 | | |
307 | 351 | /* At the present time, we manage only disk number like '1' or '1/2', we |
308 | 352 | * don't use disk number total... so here we try to decompose */ |
309 | 353 | if (FileTag->disc_number) |
… |
… |
|
314 | 358 | { |
315 | 359 | // A disc_number_total was entered |
316 | 360 | if ( (tmp+1) && atoi(tmp+1) ) |
317 | | disktotal = atoi(tmp+1); |
| 361 | mp4disk.total = atoi(tmp+1); |
318 | 362 | |
319 | 363 | // Fill disc_number |
320 | 364 | *tmp = '\0'; |
321 | | disk = atoi(dn_tmp); |
| 365 | mp4disk.index = atoi(dn_tmp); |
322 | 366 | }else |
323 | 367 | { |
324 | | disk = atoi(FileTag->disc_number); |
| 368 | mp4disk.index = atoi(FileTag->disc_number); |
325 | 369 | } |
326 | 370 | g_free(dn_tmp); |
327 | 371 | } |
328 | 372 | /*if (FileTag->disc_number) |
329 | | disk = atoi(FileTag->disc_number); |
| 373 | mp4disk.index = atoi(FileTag->disc_number); |
330 | 374 | if (FileTag->disc_number_total) |
331 | | disktotal = atoi(FileTag->disc_number_total); |
| 375 | mp4disk.total = atoi(FileTag->disc_number_total); |
332 | 376 | */ |
333 | | MP4SetMetadataDisk(mp4file, disk, disktotal); |
334 | | }else |
335 | | { |
336 | | //MP4DeleteMetadataDisk(mp4file); |
337 | | MP4SetMetadataDisk(mp4file, 0, 0); |
338 | 377 | } |
| 378 | MP4TagsSetDisk(mp4tags, &mp4disk); |
339 | 379 | |
340 | 380 | /******** |
341 | 381 | * Year * |
342 | 382 | ********/ |
343 | 383 | if (FileTag->year && g_utf8_strlen(FileTag->year, -1) > 0) |
344 | 384 | { |
345 | | MP4SetMetadataYear(mp4file, FileTag->year); |
| 385 | MP4TagsSetReleaseDate(mp4tags, FileTag->year); |
346 | 386 | }else |
347 | 387 | { |
348 | | //MP4DeleteMetadataYear(mp4file); |
349 | | MP4SetMetadataYear(mp4file, ""); |
| 388 | MP4TagsSetReleaseDate(mp4tags, ""); |
350 | 389 | } |
351 | 390 | |
352 | 391 | /************************* |
… |
… |
|
355 | 394 | if ( (FileTag->track && g_utf8_strlen(FileTag->track, -1) > 0) |
356 | 395 | || (FileTag->track_total && g_utf8_strlen(FileTag->track_total, -1) > 0) ) |
357 | 396 | { |
358 | | uint16_t track = 0; |
359 | | uint16_t track_total = 0; |
360 | 397 | if (FileTag->track) |
361 | | track = atoi(FileTag->track); |
| 398 | mp4track.index = atoi(FileTag->track); |
362 | 399 | if (FileTag->track_total) |
363 | | track_total = atoi(FileTag->track_total); |
364 | | MP4SetMetadataTrack(mp4file, track, track_total); |
365 | | }else |
366 | | { |
367 | | //MP4DeleteMetadataTrack(mp4file); |
368 | | MP4SetMetadataTrack(mp4file, 0, 0); |
| 400 | mp4track.total = atoi(FileTag->track_total); |
369 | 401 | } |
| 402 | MP4TagsSetTrack(mp4tags, &mp4track); |
370 | 403 | |
371 | 404 | /********* |
372 | 405 | * Genre * |
373 | 406 | *********/ |
374 | 407 | if (FileTag->genre && g_utf8_strlen(FileTag->genre, -1) > 0 ) |
375 | 408 | { |
376 | | MP4SetMetadataGenre(mp4file, FileTag->genre); |
| 409 | MP4TagsSetGenre(mp4tags, FileTag->genre); |
377 | 410 | }else |
378 | 411 | { |
379 | | //MP4DeleteMetadataGenre(mp4file); |
380 | | MP4SetMetadataGenre(mp4file, ""); |
| 412 | MP4TagsSetGenre(mp4tags, ""); |
381 | 413 | } |
382 | 414 | |
383 | 415 | /*********** |
… |
… |
|
385 | 417 | ***********/ |
386 | 418 | if (FileTag->comment && g_utf8_strlen(FileTag->comment, -1) > 0) |
387 | 419 | { |
388 | | MP4SetMetadataComment(mp4file, FileTag->comment); |
| 420 | MP4TagsSetComments(mp4tags, FileTag->comment); |
389 | 421 | }else |
390 | 422 | { |
391 | | //MP4DeleteMetadataComment(mp4file); |
392 | | MP4SetMetadataComment(mp4file, ""); |
| 423 | MP4TagsSetComments(mp4tags, ""); |
393 | 424 | } |
394 | 425 | |
395 | 426 | /********************** |
… |
… |
|
397 | 428 | **********************/ |
398 | 429 | if (FileTag->composer && g_utf8_strlen(FileTag->composer, -1) > 0) |
399 | 430 | { |
400 | | MP4SetMetadataWriter(mp4file, FileTag->composer); |
| 431 | MP4TagsSetComposer(mp4tags, FileTag->composer); |
401 | 432 | }else |
402 | 433 | { |
403 | | //MP4DeleteMetadataWriter(mp4file); |
404 | | MP4SetMetadataWriter(mp4file, ""); |
| 434 | MP4TagsSetComposer(mp4tags, ""); |
405 | 435 | } |
406 | 436 | |
407 | 437 | /***************** |
… |
… |
|
409 | 439 | *****************/ |
410 | 440 | if (FileTag->encoded_by && g_utf8_strlen(FileTag->encoded_by, -1) > 0) |
411 | 441 | { |
412 | | MP4SetMetadataTool(mp4file, FileTag->encoded_by); |
| 442 | MP4TagsSetEncodedBy(mp4tags, FileTag->encoded_by); |
413 | 443 | }else |
414 | 444 | { |
415 | | //MP4DeleteMetadataTool(mp4file); |
416 | | MP4SetMetadataTool(mp4file, ""); |
| 445 | MP4TagsSetEncodedBy(mp4tags, ""); |
417 | 446 | } |
418 | 447 | |
419 | 448 | /*********** |
… |
… |
|
422 | 451 | { |
423 | 452 | // Can handle only one picture... |
424 | 453 | Picture *pic; |
425 | | |
426 | | //MP4DeleteMetadataCoverArt(mp4file); |
427 | | MP4SetMetadataCoverArt(mp4file, NULL, 0); |
428 | | for( pic = FileTag->picture; pic; pic = pic->next ) |
| 454 | if (mp4tags->artworkCount && mp4tags->artwork) |
| 455 | MP4TagsRemoveArtwork(mp4tags, 0); |
| 456 | MP4TagsSetArtwork(mp4tags, 0, NULL); |
| 457 | for (pic = FileTag->picture; pic; pic = pic->next) |
429 | 458 | { |
430 | | if( pic->type == PICTURE_TYPE_FRONT_COVER ) |
| 459 | if (pic->type == PICTURE_TYPE_FRONT_COVER) |
431 | 460 | { |
432 | | MP4SetMetadataCoverArt(mp4file, pic->data, pic->size); |
| 461 | mp4artwork.data = pic->data; |
| 462 | mp4artwork.size = pic->size; |
| 463 | switch (pic->type) { |
| 464 | case PICTURE_FORMAT_JPEG: |
| 465 | mp4artwork.type = MP4_ART_JPEG; |
| 466 | break; |
| 467 | case PICTURE_FORMAT_PNG: |
| 468 | mp4artwork.type = MP4_ART_PNG; |
| 469 | break; |
| 470 | default: |
| 471 | mp4artwork.type = MP4_ART_UNDEFINED; |
| 472 | } |
| 473 | if (mp4tags->artworkCount) |
| 474 | MP4TagsSetArtwork(mp4tags, 0, &mp4artwork); |
| 475 | else |
| 476 | MP4TagsAddArtwork(mp4tags, &mp4artwork); |
433 | 477 | } |
434 | 478 | } |
435 | 479 | } |
436 | 480 | |
437 | | |
438 | | MP4Close(mp4file); |
| 481 | MP4TagsStore(mp4tags, mp4file); |
| 482 | MP4TagsFree(mp4tags); |
| 483 | MP4Close(mp4file, 0); |
439 | 484 | |
440 | 485 | if (error) return FALSE; |
441 | 486 | else return TRUE; |