Base de données iTunes non modifiable ?
Bonjour à tous,
Je cherche à modifier la base de données iTunes. Pas de grosses modifications, simplement modifier, par exemple, la note d'un morceau et son play count à partir du XML "iTunes Music Library.xml"
Le problème c'est que la modification n'est jamais prise en compte.
Vous pouvez testez vous meme, quittez iTunes, ouvrez le XML avec Property List Editor, prenez un morceau au hasard dans "Tracks" et modifier son "Rating" (5 étoiles = 100, 1 étoile = 20). Mettez donc une note différente de l'actuelle, sauvegardez le fichier.
Relancez iTunes et allez rechercher votre track modifié.. la note reste la meme..
Si vous vous amusez à quitter/relancer, le XML gardera la nouvelle note que vous lui aviez donné.. Mais dès que vous lancez une lecture dans iTunes (ou que vous switchez de playlist aussi, je pense), le XML sera modifié et le track aura retrouvé sa note d'origine.
J'ai cherché tous les caches possibles, en vain..
Alors.. mystère et boule de gomme.. Il n'y a plus qu'à espérer que ça ne soit pas la faute à "iTunes Library", car je pense que c'est indécodable comme fichier..
Louka.
Je cherche à modifier la base de données iTunes. Pas de grosses modifications, simplement modifier, par exemple, la note d'un morceau et son play count à partir du XML "iTunes Music Library.xml"
Le problème c'est que la modification n'est jamais prise en compte.
Vous pouvez testez vous meme, quittez iTunes, ouvrez le XML avec Property List Editor, prenez un morceau au hasard dans "Tracks" et modifier son "Rating" (5 étoiles = 100, 1 étoile = 20). Mettez donc une note différente de l'actuelle, sauvegardez le fichier.
Relancez iTunes et allez rechercher votre track modifié.. la note reste la meme..
Si vous vous amusez à quitter/relancer, le XML gardera la nouvelle note que vous lui aviez donné.. Mais dès que vous lancez une lecture dans iTunes (ou que vous switchez de playlist aussi, je pense), le XML sera modifié et le track aura retrouvé sa note d'origine.
J'ai cherché tous les caches possibles, en vain..
Alors.. mystère et boule de gomme.. Il n'y a plus qu'à espérer que ça ne soit pas la faute à "iTunes Library", car je pense que c'est indécodable comme fichier..
Louka.
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Sachant que les fichiers temporaires ("Temp File.tmp" et "cfx#tJFaYiP") sont à mon avis clairement en fait la traduction d'une modification des fichiers qui sont à côté d'eux ("iTunes Library" et "iTunes Music Library.xml" pour le premier, "com.apple.iApps.plist" pour le second) par un "writeToFile:... atomically:YES" (le "atomically:YES" ayant pour effet, pour rappel, justement d'écrire dans un fichier temporaire et de remplacer l'original par ce fichier temporaire une fois prêt, plutôt que d'écrire direct dans le fichier original)
Conclusion, quand on change la note d'un morceau, il n'y à a priori pas 36 fichiers modifiés en conséquence, juste :
- le fichier de préférences (et encore c'est sans doute pour indiquer la dernière piste sélectionnée dans iTunes un truc comme ça)
- le "iTunes Music Library.xml"...
- ... et le fichier "iTunes Library" justement, celui que tu craignais ::)
Désolé :P
Il n'y a vraiment aucun moyen de décoder ce fichier "iTunes Library" ?
Bha c'est justement ce que je cherche à éviter...
Dans le cadre de mon boulot, j'ai bossé avec un driver qu'on a développé plus puissant que fsevents, qui donne non seulement les fichiers modifiés, mais aussi les zones de modification...
Je peux essayer de faire un peu de reverse engineering, mais à mon avis c'est carrément complexe (surtout si plein de choses sont modifiées en mémoire avant la bufferisation dans le fichier).
Bha si jamais tu trouves quelque chose pourquoi pas. Mais c'est vrai que si c'est compliqué... d'un côté j'espère que ça sera pas trop gênant pour mon application de ne pas pouvoir noter et garder à jour les smart playlists (grâce à la date de dernière écoute & nombre d'écoutes par exemple)... après c'est vrai que je peux toujours m'en servir en AppleScript si jamais l'utilisateur a lancé iTunes.. mais bon c'est vraiment pas top..
Le top du top ça serait que le fichier iTunes Library soit pas trop compliqué à manipuler :fouf):
Vous êtes sûrs que c'est pas simplement du XML-binaire chez vous ?
Le iTunes Music Library.xml c'est en effet du simple XML, mais l'autre j'ai beau l'ouvrir avec TextEdit je vois que des caractères pourris. PLE ne veut meme pas l'ouvrir.
http://search.cpan.org/~bdfoy/Mac-iTunes-0.90/doc/file_format.pod
'vache :-\\ c'est mort pour moi ce genre de truc
Ouaip enfin ça c'est de l'informatique profond pour moi ;D Je suis plus à l'aise sur du code de base avec une joli interface que le côté cambouis.
'fin là pour moi y'a rien niveau documentation...
Après ce qui diffère pour chaque format de fichier ce sont les codes FOURCC et la structure des données dans ces blocs (en bref, les types de blocs utilisés qui changent quoi)
Bon ceci étant dit, mon petit bout de code parse le premier bloc, de type "hdfm", et affiche la "Version String" (en l'occurence "8.1.1" chez moi)... mais ensuite il tombe sur 4 octets (sensés être le code FOURCC du bloc suivant) qui sont en fait "B0 11 AC EB" en hexa... ce qui n'a rien d'un des FOURCC référencés...
J'ai regardé dans le hexdump du fichier iTunes Library, ce sont en effet ces octets qui sont présents à cet endroit... et je ne trouve aucun truc ressemblant à un FOURCC dans les alentours, donc je sais pas trop ce qui se passe... soit mon code est foireux (sur la lecture de la longueur du bloc par exemple ? Si je swap pas mes bits sur les octets de longueur c'est pas mieux donc je vois pas), soit y'a une subtilité dans le format qui est apparue depuis (par exemple les bits lus dans "unknown1" sont en fait des flags dont l'un deux indique que tout le reste du fichier est gzippé ou je ne sais quoi...)
Du coup mon programme ne va pas bcp plus loin que la lecture du premier bloc, et après bah faut voir ce qui cloche. Mais bon ça te donne une idée comme quoi le code pour parser ce genre de fichier est pas bien méchant.
D'autant qu'il y a plein de petites astuces en C, comme la notation 'hdim' entre apostrophes qui est une notation possible pour un "unsigned long" en définissant ses 4 octets avec le code ascii des caractères donnés (exactement sur le même principe que 'A' définit la valeur 65 d'un unsigned char), ce qui permet ensuite par exemple de faire un "switch(fourcc.code) { case 'hdfm': ... case 'hdim': .... }" etc.
Ou encore la possibilité de lire des données directement dans une structure C... En effet pour le bloc "hdfm" j'ai parsé le bloc champ par champ (en particulier parce que le champ "version string" est de longueur variable et que le nombre de caractères à lire est à lire juste avant)... Mais bien souvent (par exemple pour htim) tu peux lire tout plein de champs en une seule passe (avec un seul fread) en utilisant une structure C (struct htim_block { ... }) et en la lisant d'un bloc... Tu as alors juste après le fread directement tes valeurs répartis dans les différents champs de ta structure, sans rien d'autre à faire, et tu peux directement accéder à "htim.rating" par exemple...
Bref au final le code n'est pas sorcier, c'est le retro-engineering qui prend juste un peu plus de temps
Tu rigoles ? C'est une spec tout ce qu'il y a de plus documentée La personne a plutôt fait du beau travail je trouve...
Ouaip enfin tout le monde n'a pas ton niveau non plus...
Le problème surtout, c'est que comme c'est un format propriétaire, c'est sujet à changer sans aucun avertissement.
Le truc c'est que pour moi c'est du cambouis et j'aime pas
Par contre j'aime bien être malin :
Tu es prêt à endommager un fichier ne t'appartenant pas (celui d'itunes)...
Et que ce passera t'il si la "reconstruction" ne fonctionne pas ?
Ou si Apple décide que dans la prochaine sous-version d'iTunes, il n'y aura plus de mécanisme de reconstruction ?
Eh bien j'aurai un iTunes vide, tout ça parce j'aurai fait confiance à un développeur un peu inconscient en installant un truc pas propre sur mon système.
Enfin en meme temps dans les deux cas c'est risqué.. Et dans les deux cas la sauvegarde est toujours possible.
De toute façon je compte pas utiliser la 2eme méthode puisque ça met un certain temps à être reconstitué.
Vais devoir me mettre à Applescripter iTunes et basta :adios!:
(Quoi que je vais quand meme me pencher sur la solution proposée par Schlum/Ali)
Oui, je me doutais qu'il en reconstruisait un avec l'autre... Mais à mon avis ça met du temps avec une grosse bibliothèque...
Si les mecs qui utilisent ton logiciel voient leur base se reconstruire à chaque notation ils risque de faire une drôle de tête.
Puis si l'autre se corrompt, hop on perd tout, chouette :adios!:
--> Pas malin du tout :P
Ils ont dû faire ça justement pour les gens perdant leur bibliothèque...
T'as vraiment envie que les gens aient un message " votre base a été corrompue " à chaque fois qu'ils utilisent ton add-on ? :P
à vrai dire, tu peux t'amuser à supprimer le XML.. il ne s'en sert pas du tout.. comme tu dis ça doit être un moyen de reconstruire le iTunes Library si jamais il est corrompu.. mais ça me semble bizarre de stocker cette couverture XML juste à côté du fichier... Pourquoi pas dans un endroit isolé voir meme en fichier caché. Je me demande plutôt si Apple ne laisse pas non plus ce XML pour les applications tierces en fait.
Si le XML est supprimé, iTunes ne bronchera pas du tout et le construira en meme pas 1 seconde à partir du moment où tu modifie une playlist, ou une chanson, ou meme simplement quand tu lances une bête lecture.
(Sisi j'avais tout lu mais de toute façon c'est nul comme méthode)
Et non ce n'est pas un problème d'endianness schlum, j'y avais pensé, tu penses, moi aussi suis un habitué de ce genre de parsing ^^ Mais comme dit dans mon post précédent, j'ai essayé avec et sans swapper mes bytes, et dans les 2 cas j'ai un souci.
- Les octets indiquant la longueur sont juste 0x90000000
- Donc soit je lis une longueur de bloc "hdfm" de 144 octets (0x90), mais quand je regarde ensuite 144-8 octets plus tard (moins 8 car j'ai déjà lu le FOURCC = 4 octets et le unsigned long = 4 octets indiquant ladite longueur de bloc) je tombe sur les octets cités B0 11 AC EB qui ne correspondent à aucun FourCC (et même quand je regarde les octets voisins dans le hexdump du fichier y'a rien qui y ressemble, au cas où j'aurais eu un petit décalage)
- Soit j'interprète la longueur en bigendian et ça me donne une longueur de bloc dans les 2 milliards, pas très probant...
Peut-être que le format a évolué depuis le reverse engineering que j'ai trouvé...
Le plus gros problème avec ce genre de trucs c'est qu'on n'est jamais à l'abri d'un changement des specs.
Cette analyse est tout à fait exacte. Mais le format binaire de iTunes DB a changé entre la version 3 et 4. A partir de la version 4, tout est crypté par un moyen que je n'ai pas réussi à découvrir (j'ai trouvé la porte secrète, tapé dessus, ça sonne creux, mais j'ai pas trouvé sur quelle pierre appuyer). A ma connaissance, ce format est toujours un mystère. Personne n'a trouvé comme le parser correctement.