読み返したところ、危なっかしいところがあったので一応直しておきます。iTunes 上で100超のトラックを選択した場合は変換処理をしないようにしてあります。
なお、AppleScript をシェルスクリプトでラッピングし、さらに AppleScript でラッピング...というちょっと奇妙なスクリプトになっているのは、巨大なアートワークのデータを取得する際、Script Editor がハングしないようにするためです。
コード
on run
try
if application "iTunes" is not running then
return "iTunes is not running."
end if
#
# パラメータ
# 0 : MP3 ファイルをそのままにする
# 1 : MP3 ファイルをゴミ箱に捨てる
#
my main(0)
on error errs number errn
return errs
end try
end run
on main(flag)
do shell script "osascript <<'OSA' - " & quoted form of (flag as text) & "
on run(argv)
tell application \"iTunes\"
set flag to item 1 of argv as integer
set old_tracks to {} # MP3
set new_tracks to {} # AAC
set old_files to {}
set new_files to {}
set selected_tracks to selection
set trcs to count selected_tracks
if trcs < 1 or trcs > 100 then
return 1
end if
repeat with i in selected_tracks
set is_mp3 to (location of i as text) ends with \".mp3\"
set is_aac to (location of i as text) ends with \".m4a\"
if is_mp3 then
set end of old_tracks to contents of i
set end of old_files to location of i
else if is_aac then
set end of new_tracks to contents of i
set end of new_files to location of i
end if
end repeat
if not my are_paired(old_files, new_files) then
return 2
end if
set arts to count artworks of item 1 of old_tracks
if arts > 0 then
set img to data of artwork 1 of item 1 of old_tracks
else
set img to false
end if
repeat with i from 1 to length of old_tracks
# 最終再生日
set played date of item i of new_tracks ¬
to modification date of item i of new_tracks as date
# 再生回数
set played count of item i of new_tracks ¬
to played count of item i of old_tracks as integer
# レート
set rating of item i of new_tracks ¬
to rating of item i of old_tracks as integer
# 歌詞
set lyrics of item i of new_tracks ¬
to lyrics of item i of old_tracks as text
# アートワーク
if img is not false then
set data of artwork 1 of item i of new_tracks to img
end if
#
# ファイルパス
# 旧トラック (MP3) の参照先を、新ファイル (AAC) のパスに変更
#
set location of item i of old_tracks ¬
to location of item i of new_tracks as alias
# 不要となったトラックをプレイリストから削除
delete item i of new_tracks
# MP3 ファイルを削除
if flag is 1 then
tell application \"Finder\"
delete item i of old_files
end tell
end if
end repeat
return 0
end tell
end run
on are_paired(old_files, new_files)
if (count old_files) is not (count new_files) then
return false
end if
repeat with n from 1 to length of old_files
set x1 to characters 1 thru -5 of (item n of old_files as text) as text
set x2 to characters 1 thru -5 of (item n of new_files as text) as text
if x1 is not x2 then
return false
end if
end repeat
return true
end are_paired
OSA"
end main
ーーーーー
あと、アートワークの形式が PNG になってもよければ下記でも良いと思います。
こちらは JXA (JavaScript for Automation) なので、Script Editor のウインドウ左上で「JavaScript」を選択してからコードをコピペします。あとは前掲のスクリプトと同じ。なお、ピュアな JXA では上手くいかなかったので、ScriptingBridge を使いました。
なんかスレ汚しのようになってしまいましたが...、一応、ご参考まで。
コード
ObjC.import('ScriptingBridge');
var itunes = $.SBApplication.applicationWithBundleIdentifier('com.apple.iTunes');
var finder = $.SBApplication.applicationWithBundleIdentifier('com.apple.Finder');
function run() {
try {
if (! itunes.isRunning) {
return 'iTunes is not running.';
}
//
// パラメータ
// 0 : MP3 ファイルをそのままにする
// 1 : MP3 ファイルをゴミ箱に捨てる
//
return main(0);
} catch(e) {
return 'error: ' + e;
}
}
function main(flag) {
let old_tracks = [];
let new_tracks = [];
let old_files = [];
let new_files = [];
let selected_tracks = itunes.selection.get;
let cnt = selected_tracks.count;
if (cnt < 1 || cnt > 100) {
return 1;
}
for (let i of selected_tracks.js) {
let ext = i.location.path.pathExtension.js;
if (ext === 'mp3') {
old_tracks.push(i);
old_files.push(i.location);
} else if (ext === 'm4a') {
new_tracks.push(i);
new_files.push(i.location);
}
}
// mp3 files without extension
let a1 = $.NSArray.arrayWithArray(
old_files.map(x => x.path.stringByDeletingPathExtension.js));
// aac files without extension
let a2 = $.NSArray.arrayWithArray(
new_files.map(x => x.path.stringByDeletingPathExtension.js));
if (! a1.isEqual(a2)) {
return 2;
}
let img;
if (old_tracks[0].artworks.count > 0) {
img = old_tracks[0].artworks.js[0].data;
} else {
img = false;
}
for (let i = 0; i < old_tracks.length; i++) {
new_tracks[i].setPlayedDate(new_tracks[i].modificationDate);
new_tracks[i].setPlayedCount(old_tracks[i].playedCount);
new_tracks[i].setRating(old_tracks[i].rating);
new_tracks[i].setLyrics(old_tracks[i].lyrics);
if (img) {
new_tracks[i].artworks.objectAtIndex(0).setData(img);
}
old_tracks[i].setLocation(new_tracks[i].location);
new_tracks[i].delete;
if (flag === 1) {
finder.items.objectAtLocation(old_files[i]).delete
}
}
return 0
}