PageRenderTime 26ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/itunes_insert_artwork.pl

https://github.com/russelldavis/itunes_insert_artwork
Perl | 206 lines | 142 code | 28 blank | 36 comment | 25 complexity | 21c26f9cdc9399ea10345800d30d0b91 MD5 | raw file
  1. ###############################################################################
  2. #
  3. # itunes_insert_artwork.pl
  4. #
  5. # This script will tag your files using artwork downloaded using iTunes 7
  6. #
  7. # written by: Robert Jacobson (http://home.comcast.net/~teridon73/itunesscripts)
  8. # Last Updated: 03 Jan 2007
  9. # Version 1.0
  10. #
  11. # ImageMagick modification by: Russell Davis (https://github.com/russelldavis)
  12. # This version will send all images through ImageMagick for better compression.
  13. #
  14. # This script is GPL v2. see http://www.gnu.org/copyleft/gpl.html
  15. #
  16. # Use option "-k" to keep the artwork files extracted
  17. # (in the same location as the song file)
  18. # (the default is to remove the files)
  19. ###############################################################################
  20. use File::Basename;
  21. my $PROGNAME = basename($0);
  22. my $VERSION = "1.0";
  23. my $AUTHOR = "Robert Jacobson";
  24. my $HOMEPAGE = "http://home.comcast.net/~teridon73/";
  25. my $YEAR = 2007;
  26. my $GNU_URL = "http://www.gnu.org/copyleft/gpl.html";
  27. {
  28. print
  29. "**************************************************************\n" .
  30. "$PROGNAME version $VERSION, Copyright (C) $YEAR $AUTHOR\n" .
  31. "Visit $HOMEPAGE for updates\n" .
  32. "$PROGNAME comes with ABSOLUTELY NO WARRANTY;\n".
  33. "This is free software, and you are welcome\n" .
  34. "to redistribute it under certain conditions\n" .
  35. "for details see $GNU_URL.\n" .
  36. "**************************************************************\n" .
  37. "\n"
  38. ;
  39. }
  40. use strict;
  41. use Win32::OLE;
  42. use Data::Dumper;
  43. use File::Basename;
  44. use Getopt::Std;
  45. use Image::Magick;
  46. # Create a signal handler to destroy the iTunes object
  47. # in case our program quits before the end
  48. use sigtrap 'handler', \&quit, 'normal-signals';
  49. my %artformat = (
  50. 0 => 'Unknown',
  51. 1 => 'JPEG',
  52. 2 => 'PNG',
  53. 3 => 'BMP',
  54. );
  55. my %artformat_ext = (
  56. 0 => 'unk',
  57. 1 => 'jpg',
  58. 2 => 'png',
  59. 3 => 'bmp',
  60. );
  61. getopts('k');
  62. ## Create the OLE Object
  63. my $iTunes = Win32::OLE->new('iTunes.Application') or die Win32::OLE->LastError();
  64. # Check version first!
  65. my $version = $iTunes->Version;
  66. if ($version !~ /^7/) {
  67. print "Sorry, this script requires iTunes 7\n";
  68. quit();
  69. }
  70. # Get the possible sources
  71. my $sources = $iTunes->Sources();
  72. my $sourcesCount = $sources->Count();
  73. my $source = '';
  74. my $sourceKind = '';
  75. my $n = 1;
  76. my $remove_files = 1;
  77. our $opt_k;
  78. if ($opt_k) {
  79. $remove_files = 0;
  80. } else {
  81. print "Keep extracted image files? [n] ";
  82. chomp(my $answer = <STDIN>);
  83. if ($answer =~ /^y/i) {
  84. $remove_files = 0;
  85. }
  86. }
  87. # For each source, figure out kind
  88. for ($n = 1; $n <= $sourcesCount; $n++) {
  89. $source = $sources->Item($n);
  90. $sourceKind = $source->Kind();
  91. # print "source no. " . $n . " is ";
  92. # print $sourceKind . " -- ";
  93. if ($sourceKind == 0) {
  94. print "Unknown Source\n"; }
  95. if ($sourceKind == 1) {
  96. print "Library Source\n";
  97. # Get the playlists in the Library
  98. my $playlists = $source->Playlists();
  99. my $num_playlists = $playlists->Count();
  100. print "There are $num_playlists playlists\n";
  101. # For each playlist, show the name and number of tracks
  102. for (my $j = 1 ; $j <= $num_playlists; $j++) {
  103. my $playlist = $playlists->Item($j);
  104. my $playlist_name = $playlist->Name();
  105. print "\t$j : $playlist_name\n";
  106. }
  107. print "Enter comma-separated playlist numbers: ";
  108. chomp (my $nums = <STDIN>);
  109. my @nums = split(/,/ , $nums);
  110. for my $i (@nums) {
  111. my $playlist = $playlists->Item($i);
  112. my $playlist_name = $playlist->Name();
  113. print "You selected $playlist_name\n";
  114. my $tracks = $playlist->Tracks;
  115. my $num_tracks = $tracks->Count();
  116. print "\t$num_tracks tracks\n";
  117. my %seen;
  118. # Get all the tracks in the playlist
  119. for (my $k = 1 ; $k <= $tracks->Count ; $k++ ) {
  120. #print "num: " , $num_tracks , " Count: ", $tracks->Count , " k: ", $k , "\n";
  121. my $track = $tracks->Item($k);
  122. my $track_kind = $track->Kind();
  123. if ($track_kind == 1) {
  124. my $count = $track->Artwork->Count;
  125. if ($count > 1) {
  126. print "ERROR - found file with more than one artwork " . $track->Name . "\n";
  127. }
  128. for (my $c = 1 ; $c <= $count ; $c++) {
  129. my $artwork = $track->Artwork->Item($c);
  130. if ($artwork->IsDownloadedArtwork) {
  131. my $name = $track->Name;
  132. my $album = $track->Album;
  133. print "name is \"$name\"\talbum: \"$album\"\n";
  134. my $format = $artwork->Format;
  135. my($fnFile, $fnDir, $fnExt) = fileparse($track->Location, qr/\.[^.]*/);
  136. my $fnBase = $fnDir . $fnFile;
  137. my $filename = $fnBase . ".art.orig." . $artformat_ext{$format};
  138. my $compressedFilename = $fnBase . ".art." . $artformat_ext{$format};
  139. $artwork->SaveArtworkToFile($filename);
  140. if (not -s $filename) {
  141. print "ERROR saving file $filename\n";
  142. } else {
  143. # Get the file down to a reasonable size (many of the jpegs from itunes images are over 500K)
  144. my $image = new Image::Magick;
  145. $image->Read($filename);
  146. $image->Set(quality=>'85');
  147. my $err = $image->Write($compressedFilename);
  148. if ($err || not -s $compressedFilename) {
  149. print "ERROR compressing $name: $err\n";
  150. } else {
  151. # insert into file
  152. print "inserting artwork file $compressedFilename\n";
  153. my $hr = $artwork->SetArtworkFromFile($compressedFilename);
  154. if ($hr < 0) {
  155. print "ERROR setting artwork: $hr\n";
  156. }
  157. }
  158. }
  159. if ($remove_files) {
  160. unlink $filename;
  161. unlink $compressedFilename;
  162. }
  163. }
  164. }
  165. }
  166. }
  167. }
  168. }
  169. }
  170. # Destroy the object. Otherwise zombie object will come back
  171. # to haunt you
  172. quit();
  173. sub quit
  174. {
  175. # This destroys the object
  176. undef $iTunes;
  177. exit;
  178. }