Jeremi
Jeremi

Reputation: 1474

Dart: Retrive multiple album covers from MP3 file's ID3 tags

iTunes/Apple Music allows for adding multiple cover artworks to a mp3 file. The first images is in a column named "Album Artwork" and remaining are in column "Other Artwork" as shown on the image below:

iTunes

I'm trying to retrieve all of these artworks in Dart but when reading the ID3 tags I can only see the first artwork. I'm certain that the other artworks are stored in the MP3 file as its file size is increasing when I add additional artworks.

How can I retrieve the other artworks from a MP3 file?

Below is my code and JSON showing all available ID3 tags data.

import 'dart:convert';
import 'dart:io' as io;

import 'package:id3/id3.dart';

void main(List<String> args) {
  var mp3 = io.File("./lib/song2.mp3");

  MP3Instance mp3instance = MP3Instance(mp3.readAsBytesSync());

  mp3instance.parseTagsSync();
  Map<String, dynamic>? id3Tags = mp3instance.getMetaTags();

  print(id3Tags!['APIC'].keys);
  print(id3Tags!['APIC']['mime']);

  io.File outputFile = io.File("lib/id3TagsOutput.txt");
  outputFile.writeAsString(jsonEncode(id3Tags));
}

Output:

{
  "Version": "v2.3.0",
  "Album": "God of War (PlayStation Soundtrack)",
  "Accompaniment": "Bear McCreary",
  "Artist": "Bear McCreary",
  "AdditionalInfo": "WWW",
  "Composer": "Bear McCreary",
  "Year": "2018",
  "TPOS": "1",
  "Genre": "Game Soundtrack",
  "Conductor": "London Session Orchestra, Schola Cantorum Choir, London Voices",
  "Title": "God of War",
  "Track": "1",
  "Settings": "Lavf57.56.100",
  "APIC": {
    "mime": "image/png",
    "textEncoding": "0",
    "picType": "FrontCover",
    "description": "",
    "base64": "//VERY LONG BASE 64 DATA"
  }
}

Upvotes: 0

Views: 260

Answers (1)

Jeremi
Jeremi

Reputation: 1474

I've found a solution to this issue. ID3 tags are stored in different frames (information blocks). Frames images are named "APIC". When a mp3 file has multiple images, APIC frame is added for each image.

The package I'm using, package:id3/id3.dart, stores decoded tags information in a map. This map has a key "APIC" for storing image data. Every time it comes across "APIC" frame it overrides data from previously found image.

I've amended the source code of this library to store an array in "APIC" key:

MP3Instance(List<int> mp3Bytes) {
    this.mp3Bytes = mp3Bytes;
    metaTags['APIC'] = [];
  }

and in function parseTagsSync I've changed this line: metaTags['APIC'] = apic; to metaTags['APIC'].add(apic);. This change allows the library to store all APIC data.

Upvotes: 0

Related Questions