「androidはじめました」ということで,まずはARMのクロスコンパイラをOS X上に準備。CodeSourceryから提供されるGNU Toolchainをベースに環境を構築することにして
- Target: ARM GNU/Linux,Host: IA32 GNU/Linuxのバイナリ
- Target: ARM GNU/Linuxのソース
をダウンロード。
#!/usr/bin/env ruby
# configuration
LIB_NAME = 'ライブラリ'
PLAYLIST_NAME = 'SO905i'
DEST_DIR = '/Volume/Untitled/MUSIC'
ITUNES_BASE = '/Users/nishio/Music/iTunes/iTunes Music/'
CMD_M4A = '/Users/nishio/bin/AtomicParsley'
CMD_3GP = '/Users/nishio/bin/AtomicParsley_3gp'
# load libraries
require 'fileutils'
require 'pathname'
require 'osx/cocoa' # load cocoa library.
include OSX # setup for scripting bridge.
OSX.require_framework 'ScriptingBridge'
###
### convert m4a metadata to 3gp metadata
###
def m4a_to_3gp(file)
file = file.gsub(/"/) {|s| '\\' + s} # escape double quote
# parse .m4a atom
h = Hash.new
open("| #{CMD_M4A} \"#{file}\" -t") { |f|
while line = f.gets
line =~ /Atom "(.*)".* contains: (.*)/
h[$1] = $2.gsub(/"/) {|s| '\\' + s} # escape double quote
end
}
# put .3gp atom
h["trkn"] =~ /([0-9]*) of [0-9]*/
num = $1
args = "--3gp-title \"#{h["\302\251nam"]}\" lang=jpn --3gp-performer \"#{h["\302\251ART"]}\" lang=jpn --3gp-album \"#{h["\302\251alb"]}\" track=#{num} lang=jpn --3gp-genre \"#{h["\302\251gen"]}\" lang=jpn --3gp-year '#{h["\302\251day"]}' --overWrite"
system("#{CMD_3GP} \"#{file}\" #{args}")
end
######################################################################
# main routine begins here.
iTunes = SBApplication.applicationWithBundleIdentifier_("com.apple.iTunes")
iTunes.sources.each do |source|
next unless source.name == LIB_NAME
source.userPlaylists.each do |playlist|
next unless playlist.name == PLAYLIST_NAME
base = Pathname.new(ITUNES_BASE)
playlist.fileTracks.each do |track|
next unless track.enabled?
path = track.location.path
path_name = Pathname.new(path)
ext_name = File.extname(path)
dst_name = DEST_DIR + path_name.relative_path_from(base)
dst_dir = File.dirname(dst_name)
# create destination directories if not exists.
if !FileTest.exist?(dst_dir) then
puts "make directory: #{dst_dir}"
FileUtils.mkdir_p(dst_dir)
end
# copy a file
puts "copy file: #{dst_name}"
case ext_name
when '.m4a' then
dst_name = File.join(dst_dir, File.basename(dst_name, ext_name) + '.3gp')
FileUtils.cp(path, dst_name)
m4a_to_3gp(dst_name)
else
FileUtils.cp(path, dst_name)
end
end
end
end
$ ~/bin/AtomicParsley 16\ 後出し.m4a -t
Atom "©nam" contains: 後出し
Atom "©ART" contains: ケツメイシ
Atom "©wrt" contains: ケツメイシ
Atom "©alb" contains: ケツノポリス2
Atom "©gen" contains: Hip Hop/Rap
Atom "trkn" contains: 16 of 16
Atom "disk" contains: 1 of 1
Atom "©day" contains: 2002
Atom "cpil" contains: false
Atom "tmpo" contains: 0
$ ~/bin/AtomicParsley_3gp スタート.3gp -t
User data "titl" [lang=jpn (utf16)] : スタート
User data "perf" [lang=jpn (utf16)] : ケツメイシ
User data "gnre" [lang=jpn (utf16)] : Rock
User data "albm" [lang=jpn (utf16)] : ケツノポリス5 | Track: 1
User data "yrrc" : 2007
#!/usr/bin/env ruby
# config
CMD_M4A = '/Users/nishio/bin/AtomicParsley'
CMD_3GP = '/Users/nishio/bin/AtomicParsley_3gp'
# convert m4a metadata to 3gp metadata
def m4a_to_3gp(file)
file = file.gsub(/"/) {|s| '\\' + s} # escape double quote
# parse .m4a atom
h = Hash.new
open("| #{CMD_M4A} \"#{file}\" -t") { |f|
while line = f.gets
line =~ /Atom "(.*)".* contains: (.*)/
h[$1] = $2.gsub(/"/) {|s| '\\' + s} # escape double quote
end
}
# put .3gp atom
h["trkn"] =~ /([0-9]*) of [0-9]*/
num = $1
args = "--3gp-title \"#{h["\302\251nam"]}\" lang=jpn --3gp-performer \"#{h["\302\251ART"]}\" lang=jpn --3gp-album \"#{h["\302\251alb"]}\" track=#{num} lang=jpn --3gp-genre \"#{h["\302\251gen"]}\" lang=jpn --3gp-year '#{h["\302\251day"]}' --overWrite"
system("#{CMD_3GP} \"#{file}\" #{args}")
end
# main begins.
file = ARGV[0]
m4a_to_3gp(file)
$ ~/bin/AtomicParsley スタート.3gp -t
User data "titl" [lang=jpn (utf16)] : スタート
User data "perf" [lang=jpn (utf16)] : ケツメイシ
User data "gnre" [lang=jpn (utf16)] : Rock
User data "albm" [lang=jpn (utf16)] : ケツノポリス5 | Track: 1
User data "yrrc" : 2007$ ~/bin/AtomicParsley 16\ 後出し.m4a --3gp-album "Test Album" lang=jpn
AtomicParsley warning:
the 'albm' tag is only allowed on files of '3gp6' brand & later.
Skipping.
No changes.*** AtomicParsley.cpp.orig 2008-03-28 01:42:33.000000000 +0900
--- AtomicParsley.cpp 2008-03-28 01:43:56.000000000 +0900
***************
*** 2114,2119 ****
--- 2114,2120 ----
metadata_style = THIRD_GEN_PARTNER;
break;
+ case 0x4D344120 : //'M4A ' -- these are all listed at http://www.mp4ra.org/filetype.html as registered brands
case 0x33677036 : //'3gp6'
case 0x33677236 : //'3gr6' progressive
***************
*** 2129,2135 ****
metadata_style = ITUNES_STYLE;
psp_brand = true;
break;
! case 0x4D344120 : //'M4A ' -- these are all listed at http://www.mp4ra.org/filetype.html as registered brands
case 0x4D344220 : //'M4B '
case 0x4D345020 : //'M4P '
case 0x4D345620 : //'M4V '
--- 2130,2136 ----
metadata_style = ITUNES_STYLE;
psp_brand = true;
break;
! //case 0x4D344120 : //'M4A ' -- these are all listed at http://www.mp4ra.org/filetype.html as registered brands
case 0x4D344220 : //'M4B '
case 0x4D345020 : //'M4P '
case 0x4D345620 : //'M4V '$ ~/bin/AtomicParsley_3gp 16\ 後出し.m4a --3gp-album "Test Album" lang=jpn --overWrite
......
Finished writing to temp file.
$ ~/bin/AtomicParsley_3gp 16\ 後出し.m4a -t
User data "albm" [lang=jpn (utf8)] : Test AlbumAtomicParsley is a lightweight command line program for reading, parsing and setting metadata into MPEG-4 files supporting these styles of metadata:
iTunes-style metadata into .mp4, .m4a, .m4p, .m4v, .m4b files
3gp-style assets (3GPP TS 26.444 version 6.4.0 Release 6 specification conforming) in 3GPP, 3GPP2, MobileMP4 & derivatives
ISO copyright notices at movie & track level for MPEG-4 & derivative files
uuid private user extension text & file embedding for MPEG-4 & derivative files