mp3ファイルにid3 tagを書き込みます。Rubyスクリプトです。
Révision | 8dded40246a881bf98390538d1b2920f32f3c4ab |
---|---|
Taille | 3,815 octets |
l'heure | 2011-07-11 14:40:52 |
Auteur | jakago |
Message de Log | initial commit
|
#!/usr/bin/env ruby -Ku
require 'nkf'
require 'tempfile'
require 'fileutils'
def encode_size( int32 )
result = String.new()
result << ((int32 & (0x0000007f << 21)) >> 21).chr
result << ((int32 & (0x0000007f << 14)) >> 14).chr
result << ((int32 & (0x0000007f << 7)) >> 7).chr
result << (int32 & 0x0000007f).chr
return result
end
# identifier and string must be UTF-8
def ascii_frame( identifier, string )
ascii_mark = "\x00"
result = String.new()
if identifier.size == 3 && string.size > 0
frame_data = NKF.nkf( "-l -W", string )
if frame_data.size > 0
frame_data = ascii_mark + frame_data + "\x00"
result << identifier
result << ((frame_data.size & 0x00ff0000) >> 16).chr
result << ((frame_data.size & 0x0000ff00) >> 8).chr
result << (frame_data.size & 0x000000ff).chr
result << frame_data
end
end
return result
end
# identifier and string must be UTF-8
def unicode_frame( identifier, string )
unicode_mark = "\x01"
result = String.new()
if identifier.size == 3 && string.size > 0
frame_data = NKF.nkf( "-w16L -W", string )
if frame_data.size > 0
frame_data = unicode_mark + frame_data + "\x00\x00"
result << identifier
result << ((frame_data.size & 0x00ff0000) >> 16).chr
result << ((frame_data.size & 0x0000ff00) >> 8).chr
result << (frame_data.size & 0x000000ff).chr
result << frame_data
end
end
return result
end
def create_tag( album, title, year, artist, genre )
tag_bytes = String.new()
frames = String.new()
frames << unicode_frame( "TAL", album );
frames << unicode_frame( "TT2", title );
frames << ascii_frame( "TYE", year );
frames << unicode_frame( "TP1", artist );
frames << ascii_frame( "TCO", "(#{genre})" );
if frames.size > 0
tag_bytes << "ID3\x02\x00\x00"
tag_bytes << encode_size( frames.size )
tag_bytes << frames
end
return tag_bytes
end
def decode_size( byte4 )
return ((byte4[0] & 0x7f) << 21) + ((byte4[1] & 0x7f) << 14) +
((byte4[2] & 0x7f) << 7) + (byte4[3] & 0x7f)
end
# calculate tag size of ID3v2.2.0~ID3v2.4.0
def tag_size( buffer )
#offset_identifier = 0
offset_version = 3
#offset_flags = 5
offset_size = 6
offset_data = 10
identifier = "ID3"
result = 0
if buffer.size > offset_data && buffer[0,3] == identifier
# ID3v2.2.0, ID3v2.3.0 and ID3v2.4.0 only
if buffer[offset_version] >= "2"[0] && buffer[offset_version] <= "4"[0] && buffer[offset_version + 1] == "0"[0]
result = decode_size( buffer[offset_size,4] ) + offset_data
end
end
return result;
end
def make_temp_name( original )
temp_file = Tempfile.open( File.basename( original ) )
result = temp_file.path
temp_file.close!
return result
end
def id3tag( full_path, album, title, year, artist, genre )
src_file = nil
dst_file = nil
original_file_moved = false
begin
tag_bytes = create_tag( album, title, year, artist, genre )
raise "Failed to create ID3 tag." if tag_bytes.size <= 0
temp_name = make_temp_name( full_path )
FileUtils.move( full_path, temp_name )
original_file_moved = true
src_file = File.open( temp_name, "r" )
src_file.binmode
dst_file = File.open( full_path, "w" )
dst_file.binmode
raise "Failed to write working copy." if dst_file.write( tag_bytes ) != tag_bytes.size
buffer = src_file.read
skip = tag_size( buffer )
raise "Failed to write working copy." if dst_file.write( buffer[skip..-1] ) != buffer.size - skip
dst_file.close
dst_file = nil
src_file.close
File.unlink( temp_name )
src_file = nil
rescue
puts( $! )
( src_file.close if src_file ) rescue false
( dst_file.close if dst_file ) rescue false
( File.unlink( full_path ) if dst_file ) rescue false
( FileUtils.move( temp_name, full_path ) if original_file_moved ) rescue false
end
end
#id3tag( "foo.mp3", "album", "title", "2011", "artist", "101" ) # 101 == Speech