Prezentacja i modyfikacja metadanych plików MP3

Ile razy zdarzyło Wam się, że potrzebowaliście narzędzi do szybkiej modyfikacji metadanych plików MP3, choćby po to, by wstawić tagi (ID3) z tytułami utworów lub obrazek z okładką płyty do tych właśnie plików, by łatwiej było nimi zarządzać i by lepiej prezentowały się na ekraniku ulubionego urządzenia do odtwarzania muzyki? Oczywiście, zawsze wtedy można było to zrobić przy pomocy iTunes lub innych skądinąd świetnych narzędzi, ale można też całkiem inaczej. Można mianowicie napisać własny skrypt i jednocześnie dobrze się przy tym bawić, a czyż nie o to czasem chodzi najbardziej?

Napisałem dziś skrypt do wyświetlania metadanych plików MP3 oraz do wstawiania do tych plików obrazków z okładkami płyt.

Nie wspomnę już, że prawidłowe działanie skryptu zależne jest od zainstalowania modułu ‚mp3info’ (z linii poleceń shell-a systemowego: gem install mp3info).

require "mp3info"

def show_tags (file)
       output = "\n                  Filename: #{file}"
       begin
             tags_info = Mp3Info.open(file)
             h = tags_info.tag.to_hash
             h.each_pair do |k,v|
                    output = output + "\n#{k.to_s.rjust(25)} : #{v}"
             end
             print "------------------------------------------------------------\n"
             puts output
             print "------------------------------------------------------------"
             print "\nFull info is here:\n"
             print "------------------------------------------------------------\n"
             Mp3Info.open(file) do |mp3info|
                    puts mp3info
             end
             print "------------------------------------------------------------\n"
       rescue => e
             puts "Error in mp3 file : #{file}"
       end
end

def insert_graphic (graphic_file, media_file)
       graphic = File.new(graphic_file,'rb')
       Mp3Info.open media_file do |m|
             pictures = m.tag2.pictures
             pictures.each do |description, data|
                    File.binwrite(description, data)
             end
             m.tag2.remove_pictures # remove all images embedded already in mp3 file
             m.tag2.add_picture(graphic.read)
       end   
end

if ARGV.length < 2 then
       puts "Syntax: ruby #{$0} mp3_file graphic_file"
       exit
else
       unless File.file?(ARGV[0])
             puts "Problem: File #{ARGV[0]} doesn't exist"
             exit
       end
       media_file = ARGV[0]
       unless File.file?(ARGV[1])
             puts "Problem: File #{ARGV[1]} doesn't exist"
             exit
       end
       graphic_file = ARGV[1]
end

show_tags(media_file)

print "Do you want to insert graphic (#{graphic_file}) into your MP3 file (#{media_file}) (Y/N)? "
answer = STDIN.readline.chomp

if answer =~ /Y|y/
       begin
             insert_graphic(graphic_file, media_file)
             print "Graphic from file: #{graphic_file} inserted into media file: #{media_file}\n"
       rescue => e
             puts "Error during calling insert_graphic(\"#{graphic_file}\", \"#{media_file}\") function. See details below:"
             puts e
       end
elsif answer =~ /N|n/
       puts "\nBye, bye..."
else
       puts "\nUnrecognized option..."  
end

Po drobnej modyfikacji skryptu można użyć do poważniejszych zastosowań, w których nawet bardziej specjalistyczne narzędzia mogą nie najlepiej sobie radzić. Chodzi mianowicie o wsadowe przetwarzanie zasobów muzycznych, na przykład automatyczne zasilenie dużej liczby plików MP3 metadanymi.

Tu jest przykład wsadowej zmiany obrazka (okładki płyty):

require "mp3info"

MODE = 'interactive'

def show_tags (file)
       output = "\n                  Filename: #{file}"
       begin
             tags_info = Mp3Info.open(file)
             h = tags_info.tag.to_hash
             h.each_pair do |k,v|
                    output = output + "\n#{k.to_s.rjust(25)} : #{v}"
             end
             print "------------------------------------------------------------\n"
             puts output
             print "------------------------------------------------------------"
             print "\nFull info regarding #{file} is here:\n"
             print "------------------------------------------------------------\n"
             Mp3Info.open(file) do |mp3info|
                    puts mp3info
             end
             print "------------------------------------------------------------\n"
       rescue => e
             puts "Error in mp3 file : #{file}"
       end
end

def insert_graphic (graphic_file, media_file, mode)
       if mode == 'batch'
             graphic = File.new(graphic_file,'rb')
             Mp3Info.open media_file do |m|
                    pictures = m.tag2.pictures
                    pictures.each do |description, data|
                           File.binwrite(description, data)
                    end
             end   
             m.tag2.remove_pictures # remove all images embedded already in mp3 file
             m.tag2.add_picture(graphic.read)
       elsif mode == 'interactive'
             print "Do you want to insert graphic (#{graphic_file}) into your MP3 file (#{media_file}) (Y/N)? "
             answer = STDIN.readline.chomp
             if answer =~ /Y|y/
                    begin
                           graphic = File.new(graphic_file,'rb')
                           Mp3Info.open media_file do |m|
                                  pictures = m.tag2.pictures
                                  pictures.each do |description, data|
                                        File.binwrite(description, data)
                                  end
                                  m.tag2.remove_pictures # remove all images embedded already in mp3 file
                                  m.tag2.add_picture(graphic.read)
                           end   
                           print "Graphic from file: #{graphic_file} inserted into media file: #{media_file}\n"
                    rescue => e
                           puts "Error during calling insert_graphic(\"#{graphic_file}\", \"#{media_file}\") function. See details below:"
                           puts e
                    end
             elsif answer =~ /N|n/
                    puts "\nBye, bye..."
             else
                    puts "\nUnrecognized option..."  
             end
       else
             puts "Unrecognized option if calling insert_graphic function."
             puts "Must be interactive or batch mode of operation"
             exit
       end
end

if ARGV.length < 2 then
       puts "Syntax: ruby #{$0} graphic_file mp3_file1 mp3_file2 ..."
       puts "Globbing is allowed. For instance: ruby #{$0} graphic_file *.mp3"
       exit
else
       unless File.file?(ARGV[0])
             puts "Problem: Graphic file #{ARGV[0]} doesn't exist"
             exit
       end
       graphic_file = ARGV[0]
end

mode = MODE

index = 0
ARGV.each do |file|
       if index > 0
             if File.file?(file)
                    show_tags(file)
                    case mode
                           when 'interactive' then
                                  insert_graphic(graphic_file, file, 'interactive')
                           when 'batch' then
                                  insert_graphic(graphic_file, file, 'batch')
                           else
                                  insert_graphic(graphic_file, file, 'interactive')
                    end   
             end   
       end
       index+=1
end

Jak to działa? Ano tak:

d:\scripts>ruby mp3_insert_image_batch_proc.rb richard_bona.jpg *.mp3
------------------------------------------------------------
Filename: 06 Indiscretions & Please Don't Stop.mp3
 title : Indiscretions & Please Don't Stop
 artist : Richard Bona
 album : Bona Makes You Sweat - Live [Version International]
 year : 2009
 tracknum : 6
 comments : 0
 genre_s : (8)
------------------------------------------------------------
Full info regarding 06 Indiscretions & Please Don't Stop.mp3 is here:
------------------------------------------------------------
MPEG 1 Layer 3 CBR 192 Kbps Stereo 44100 Hz length 520.2808333333334 sec. header
 {:error_protection=>false, :padding=>true, :private=>true, :mode_extension=>0,
:copyright=>false, :original=>false, :emphasis=>0} tag2: {"TIT2"=>"Indiscretions
 & Please Don't Stop", "TPE1"=>"Richard Bona", "TCOM"=>"Joe Zawinul/John Legend"
, "TALB"=>"Bona Makes You Sweat - Live [Version International]", "TRCK"=>"6/8",
"TPOS"=>"1/1", "disc_number"=>1, "disc_total"=>1, "TYER"=>"2009", "TCON"=>"(8)",
 "COMM"=>["0", " 00000473 0000045D 0000568E 00004AF8 0007866D 0004EB2F 000092AF
00008F8C 0006A5BC 0006B65E", " 00000000 00000210 00000744 00000000015E112C 00000
000 00BE74BD 00000000 00000000 00000000 00000000 00000000 00000000", "8++"], "TE
NC"=>"iTunes 11.0.4.4", "UFID"=>"http://www.cddb.com/id3/taginfo1.html\x003CD3N9
7Q154570093U188CA45D9BC46785F755911B04B173404C6P8\x00", "APIC"=>"\\x00image/jpg\
\x00\\x00image\\x00\\xFF\\xD8\\xFF\\xE0\\x00\\x10JFIF\\x00\\x01\\x01\\x00\\x00\\
x01\\x00\\x01\\x00\\x00\\xFF\\xDB\\x00\\x84\\x00\\t\\x06\\x06\\x14\\x12\\x11\\x1
5\\x14\\x12\\x14\\x15\\x14\\x15\\x16\\x17\\x17\\x18\\x18\\x18\\x17\\x19\\x17\\x1
7\\x18\\x18\\x1D\\x19\\x1C\\x15\\x17\\x18\\x1A\\x17\\x18\\x17\\x1D&\\x1E\\x1C\\x
1A$\\x1C\\x18\\x17\\x1F/ #'),,,\\x15\\x1E150*5&+,)\\x01\\t\\n\\n\\x0E\\f\\x0E\\x
1A\\x0F\\x0F\\x1A,$\\x1F$04,//,<<<...snip...>>>"}
------------------------------------------------------------
Do you want to insert graphic (richard_bona.jpg) into your MP3 file (06 Indiscre
tions & Please Don't Stop.mp3) (Y/N)? y
Graphic from file: richard_bona.jpg inserted into media file: 06 Indiscretions & Please Don't Stop.mp3
------------------------------------------------------------
Filename: Orientango.mp3
 title : track title
 artist : artist name
 album : New Tango Bridge
 year : 2010
 tracknum : 3
 comments : 0
 genre_s : Tango
------------------------------------------------------------
Full info regarding Orientango.mp3 is here:
------------------------------------------------------------
MPEG 1 Layer 3 CBR 160 Kbps JStereo 44100 Hz length 504.99920000000003 sec. head
er {:error_protection=>false, :padding=>false, :private=>true, :mode_extension=>
0, :copyright=>false, :original=>false, :emphasis=>0} tag1: {"title"=>"track tit
le", "artist"=>"artist name", "album"=>"New Tango Bridge", "year"=>2010, "trackn
um"=>3, "comments"=>"0", "genre"=>113, "genre_s"=>"Tango"}
tag2: {"TALB"=>"New Tango Bridge", "TPE1"=>"artist name", "TPE2"=>"Global Bridge
", "COMM"=>"0", "TCOM"=>"Grzegorz Frankowski", "TENC"=>"iTunes 10.1.1.4", "TCON"
=>"Tango", "TIT2"=>"track title", "TRCK"=>"3", "TYER"=>"2010", "APIC"=>"\\x00ima
ge/jpeg\\x00\\x03\\x00\\xFF\\xD8\\xFF\\xE0\\x00\\x10JFIF\\x00\\x01\\x01\\x01\\x0
0\\x96\\x00\\x96\\x00\\x00\\xFF\\xDB\\x00C\\x00\\x01\\x01\\x01\\x01\\x01\\x01\\x
01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x
01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x
01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x
01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\xFF\\xDB\\x00C\\x01\\x01\\x01\\
x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\
x01\\x01<<<...snip...>>>"}
------------------------------------------------------------
Do you want to insert graphic (richard_bona.jpg) into your MP3 file (Orientango.mp3) (Y/N)? n
Bye, bye...
------------------------------------------------------------
Filename: Samaouma.mp3
 title : Samaouma
 artist : Richard Bona
 album : Bona Makes You Sweat - Live [Version International]
 year : 2009
 tracknum : 4
 comments : 0
 genre_s : (8)
------------------------------------------------------------
Full info regarding Samaouma.mp3 is here:
------------------------------------------------------------
MPEG 1 Layer 3 CBR 192 Kbps Stereo 44100 Hz length 376.71187499999996 sec. heade
r {:error_protection=>false, :padding=>true, :private=>true, :mode_extension=>0,
 :copyright=>false, :original=>false, :emphasis=>0} tag2: {"TIT2"=>"Samaouma", "
TPE1"=>"Richard Bona", "TCOM"=>"Richard Bona", "TALB"=>"Bona Makes You Sweat - L
ive [Version International]", "TRCK"=>"4/8", "TPOS"=>"1/1", "disc_number"=>1, "d
isc_total"=>1, "TYER"=>"2009", "TCON"=>"(8)", "COMM"=>["0", " 0000009D 000000C8
000028AC 00002FAB 00057072 00057072 00006F66 00007AC5 0005592F 00056243", " 0000
0000 00000210 00000A50 0000000000FD7220 00000000 0089E125 00000000 00000000 0000
0000 00000000 00000000 00000000", "8++"], "TENC"=>"iTunes 11.0.4.4", "UFID"=>"ht
tp://www.cddb.com/id3/taginfo1.html\x003CD3N91Q154570091U2184C88A88695876312E283
DDF592D567D8P4\x00", "APIC"=>"\\x00image/jpg\\x00\\x00image\\x00\\xFF\\xD8\\xFF\
\xE0\\x00\\x10JFIF\\x00\\x01\\x01\\x00\\x00\\x01\\x00\\x01\\x00\\x00\\xFF\\xDB\\
x00\\x84\\x00\\t\\x06\\x06\\x14\\x12\\x11\\x15\\x14\\x12\\x14\\x15\\x14\\x15\\x1
6\\x17\\x17\\x18\\x18\\x18\\x17\\x19\\x17\\x17\\x18\\x18\\x1D\\x19\\x1C\\x15\\x1
7\\x18\\x1A\\x17\\x18\\x17\\x1D&\\x1E\\x1C\\x1A$\\x1C\\x18\\x17\\x1F/ #'),,,\\x1
5\\x1E150*5&+,)\\x01\\t\\n\\n\\x0E\\f\\x0E\\x1A\\x0F\\x0F\\x1A,$\\x1F$04,//,<<<.
..snip...>>>"}
------------------------------------------------------------
Do you want to insert graphic (richard_bona.jpg) into your MP3 file (Samaouma.mp3) (Y/N)? n
Bye, bye...

W podobny sposób można zmieniać dowolne metadane zapisane w tagach ID3 plików MP3.

Jeśli ktoś woli, do skryptu bardzo szybko można dorobić graficzny interfejs użytkownika w TK lub w GTK, w zależności od tego, co kto preferuje.

Jak zwykle zachęcam do rozwijania pomysłu i modyfikacji prototypowego kodu, by na tej podstawie utworzyć coś, co wpasuje się lepiej w Wasze konkretne potrzeby.

Powodzenia i jak zwykle życzę miłej zabawy🙂

Informacje Janusz Nawrat
Just ordinary man who likes thinking...

Skomentuj

Wprowadź swoje dane lub kliknij jedną z tych ikon, aby się zalogować:

Logo WordPress.com

Komentujesz korzystając z konta WordPress.com. Log Out / Zmień )

Zdjęcie z Twittera

Komentujesz korzystając z konta Twitter. Log Out / Zmień )

Facebook photo

Komentujesz korzystając z konta Facebook. Log Out / Zmień )

Google+ photo

Komentujesz korzystając z konta Google+. Log Out / Zmień )

Connecting to %s

TOMASZ WEŁNA

artysta grafik | wykładowca

PRACOWNIA OKO

Szkoła Rysunku Malarstwa i Grafiki DR TOMASZA WEŁNY | KRAKÓW | Plac Matejki 10 | tel 691 81 75 74

Piękno neurobiologii

Blog Jerzego Vetulaniego

Teoria muzyki, zasady muzyki, podstawy muzyki

Teoria muzyki, zasady muzyki, podstawy muzyki - czyli to co każdy amator muzyki wiedzieć powinien :)

Personal Development & Inspirations

Przemyślenia i refleksje, którymi warto się podzielić (blog by Janusz Nawrat)

Business IT Cooperation Platform

Biznes i IT - dwa światy, które muszą współdziałać

%d bloggers like this: