AppleScriptによるiTunesのスリープタイマー

AppleScriptの勉強をかねて、iTunes11でのスリープタイマーアプリケーションを作成してみました。

おヒマな方、AppleScriptに詳しい方には、ぜひお試しいただいて改善点などアドバイスをいただけたら幸いです。

当方、プログラム経験(COBOL,Visual Basic等)はあるものの、AppleScriptは全くの素人です。どんな事でも結構ですので何とぞご指導ください。




なお、iTunes11には「AppleScriptでシャッフルとリピートの情報を取得、設定できない」というバグがあるそうです。こちらにその報告があります。

iTunes 11 AppleScript bug « Doug's AppleScripts for iTunes

iTunes10.7では問題なく、iTunes11にて発生したバグであることは当方でも確認いたしました。


また、その対応策を考えられた方がいらっしゃいましたので、そちらからサンプルサブルーチンを拝借いたしました。それがこちらに公開されています。

How to set iTunes 11 in shuffle or repeat mode via applescript ...

このサブルーチンはiTunes11専用です。また、下記ソースコードでは日本語環境用に少々カスタマイズしています。




以下がソースコードです。(先頭のデフォルト値は、各々の好みで変更してください)

set myShuffleList to {"曲別", "アルバム別", "グループ別"}

set myTimerList to {"00:05:00", "00:15:00", "00:30:00", "01:00:00", "01:30:00", "02:00:00"}

set myDelayTime to 10


set myDefaultShuffle to "アルバム別"

set myDefaultPlayList to "お気に入りのラジオ番組"

set myDefaultTrack to "Jazz Wyoming"

set myDefaultTimer to "01:00:00"


try



-- iTunesが起動されているか?

if application "iTunes" is not running then

display alert "iTunesが起動されていません:" message "起動しますか?" as warning buttons {"No", "Yes"} default button "No" cancel button "No"

if result is {"No"} then

error number -128

else

tell application "iTunes" to run

end if

end if


tell application "iTunes"



-- Windowを表示


activate

set visible of front window to true



-- プレイリストを選択

set mySelectPlaylist to (choose from list (name of every playlist as list) with prompt "プレイリストを選択して下さい:" & return & "[キャンセル]で、再生を中止します。" default items myDefaultPlayList)

if mySelectPlaylist is false then

error number -128

else

set myPlaylist to playlist (mySelectPlaylist as string)


revealmyPlaylist

end if



-- トラックを選択

set mySelectTrack to (choose from list (name of every track of myPlaylist as list) with prompt "トラックを選択して下さい:" & return & "[キャンセル]で、全曲を再生します。" default items myDefaultTrack)

if mySelectTrack is false then


-- プレイリストを再生

set myTrack to myPlaylist

set myKind to ""


-- シャッフル再生?

set mySelectShuffle to (choose from list myShuffleList with prompt "シャッフル再生をしますか:" & return & "[キャンセル]で、先頭から再生します。" default items myDefaultShuffle)

if mySelectShuffle is false then

set myShuffle to "オフ"

else

set myShuffle to (mySelectShuffle as string)

end if

my setShuffleType(myShuffle)

else


-- トラックを再生

set myTrack to track (mySelectTrack as string) of myPlaylist

set myKind to kind of myTrack


revealmyTrack

end if



-- タイマーを選択:プレイリスト再生 or ラジオ再生

if (myKind is "") or (myKind is "インターネットオーディオストリーム") then

set myTimer to (choose from list myTimerList with prompt "再生時間を選択して下さい:" & return & "[キャンセル]で、再生を中止します。" default items myDefaultTimer)

if myTimer is false then error number -128

else

set myTimer to my retSecondsToTimer(((duration of myTrack) as integer) + 1)

end if



-- 再生開始

play myTrack with once


revealcurrent track



-- 再生時間の監視

set mySeconds to my retTimerToSeconds(myTimer as string)

repeat (mySeconds div myDelayTime + 1) times

if player state is not playing then exit repeat


delaymyDelayTime

end repeat


repeat with myVolume from 100 to 0 by -10

set sound volume to myVolume

delay 1

end repeat


stop

my setShuffleType("オフ")

set sound volume to 100

set visible of front window to false


end tell



-- エラー出口

on error wCaptionnumberwErrNum

if wErrNum = -128 then


-- "Cancelled!!"

else

error wCaptionnumberwErrNum

end if


end try


-- HH:MM:SSを秒に変換

on retTimerToSeconds(hhmmss)

set hh to (text from character 1 to character 2 of hhmmss) as integer

set mm to (text from character 4 to character 5 of hhmmss) as integer

set ss to (text from character 7 to character 8 of hhmmss) as integer

return (hh * hours + mm * minutes + ss)

end retTimerToSeconds


-- シャッフル状態の取得

on getShuffleType() -- the return value is a string: Off/By Songs/By Albums/By Groupings

tell application "System Events"

tell process "iTunes"

set menuItems to menu items of menu bar 1's menu bar item "制御"'s menu 1's menu item "シャッフル"'s menu 1

set onOffItemName to name of item 1 of menuItems

end tell

end tell



-- is shuffle off

ignoring case

if onOffItemName contains "シャッフルをオン" then return "オフ"

end ignoring



-- shuffle is on so find how we are shuffling

set currentChoice to "Unknown"

tell application "System Events"

tell process "iTunes"

repeat with i from 2 to count of menuItems

set anItem to item i of menuItems

try

set theResult to value of attribute "AXMenuItemMarkChar" of anItem

if theResult is not "" then

set currentChoice to name of anItem

exit repeat

end if

end try

end repeat

end tell

end tell

return currentChoice

end getShuffleType


-- シャッフルの設定

on setShuffleType(shuffleType) -- shuffleType is a string: Off/By Songs/By Albums/By Groupings

set currentValue to my getShuffleType()


script subs

on toggleShuffleOnOff(OnOff)

tell application "System Events" to perform action "AXPress" of (first menu item of process "iTunes"'s menu bar 1's menu bar item "制御"'s menu 1's menu item "シャッフル"'s menu 1 whose name ends with "シャッフルを" & OnOff)

end toggleShuffleOnOff


on pressBySongs()

tell application "System Events" to perform action "AXPress" of (first menu item of process "iTunes"'s menu bar 1's menu bar item "制御"'s menu 1's menu item "シャッフル"'s menu 1 whose name ends with "曲別")

end pressBySongs


on pressByAlbums()

tell application "System Events" to perform action "AXPress" of (first menu item of process "iTunes"'s menu bar 1's menu bar item "制御"'s menu 1's menu item "シャッフル"'s menu 1 whose name ends with "アルバム別")

end pressByAlbums


on pressByGroupings()

tell application "System Events" to perform action "AXPress" of (first menu item of process "iTunes"'s menu bar 1's menu bar item "制御"'s menu 1's menu item "シャッフル"'s menu 1 whose name ends with "グループ別")

end pressByGroupings

end script


ignoring case

if shuffleType contains "オフ" then -- we have to make sure it's off

if currentValue does not contain "オフ" then subs's toggleShuffleOnOff("オフ")

else


-- make sure it's on

if currentValue contains "オフ" then subs's toggleShuffleOnOff("オン")



-- select the shuffle menu item for the type

if shuffleType contains "曲別" and currentValue does not contain "曲別" then


subs's pressBySongs()

else if shuffleType contains "アルバム別" and currentValue does not contain "アルバム別" then


subs's pressByAlbums()

else if shuffleType contains "グループ別" and currentValue does not contain "グループ別" then


subs's pressByGroupings()

end if

end if

end ignoring

end setShuffleType


なお、リピート再生については、実用的でないことから対応しておりません。

MacBook Pro (15-inch Early 2008), OS X Mountain Lion, Core2Duo 2.4GHz , 4G RAM

投稿日 2013/05/02 19:47

返信
返信: 47

2016/05/19 14:19 Pajerow への返信

iTunes 11 以来バグのためずっと使えなかったシャッフル及びリピートのプロパティ設定が、iTunes 12.4になってやっと使えるようになりました。

以下のプロパティです。

  1. song repeat (off / one / all)
  2. shuffle enabled (false / true)
  3. shuffle mode (songs / albums / groupings)

これらが使えるようになり、GUIスクリプティングが不要となりコードもだいぶんスッキリしました。


下記が修正後のコードです。ただしiTunes 12.4以降限定です。


set myTrackCountLimit to 1500

set myPlaylistName to "for Sleep Timer"

set myShuffleList to {"曲", "アルバム", "グループ"}

set myTimerList to {"00:05:00", "00:15:00", "00:30:00", "01:00:00", "01:30:00", "02:00:00"}

set myDelayTime to 5



set myDefaultShuffle to "アルバム"

set myDefaultPlayList to "インターネットラジオ"

set myDefaultGenre to "*"

set myDefaultArtist to "*"

set myDefaultAlbum to "*"

set myDefaultTrack to "Jazz Wyoming"

set myDefaultTimer to "01:00:00"



try


-- iTunesが起動されているか?

if application "iTunes" is not running then

tell application "iTunes" to run

end if


tell application "iTunes"


-- Windowを表示

activate

set visible of front window to true


-- 専用プレイリストを作成

set myAllPlaylist to name of every playlist as list

if myPlaylistName is in myAllPlaylist then

set myPlayTrack to playlist (myPlaylistName)

delete every track of myPlayTrack

else

set myPlayTrack to make new playlist with properties {name:myPlaylistName}

end if

reveal myPlayTrack


-- プレイリストを選択:複数選択も可

set myList to {}

repeat with myItem in myAllPlaylist

set myStr to myItem as string

if ((count tracks of playlist (myStr)) > myTrackCountLimit) or (myStr is myPlaylistName) then

else

set myList to myList & {myStr}

end if

end repeat

set mySelect to choose from list myList with prompt "プレイリストを選択して下さい:" & return & "(複数選択も可)" & return & "[キャンセル(esc)]で再生を中止します。" & return & return & "(トラック数が" & myTrackCountLimit & "曲を越えるプレイリストは表示されません)" default items myDefaultPlayList with multiple selections allowed

if mySelect is false then error number -128


-- 専用プレイリストに重複を除外してコピー:リンク切れがあるとここでエラーが発生するが無視する

try

set id_list to {}

repeat with i in mySelect

repeat with j in tracks of playlist (i as string)

if database ID of j is not in id_list then

set id_list to id_list & (database ID of j)

duplicate j to myPlayTrack

end if

end repeat

end repeat

end try


-- ブックを除外

delete (every track of myPlayTrack whose kind ends with "ブック" or kind is "PDF 書類")

set mytracks to every track of myPlayTrack


-- ジャンルを選択:複数選択も可

set myList to {}

repeat with mytrack in mytracks

set myStr to genre of mytrack

if myStr is not in myList then set myList to myList & {myStr}

end repeat

set myList to my simple_sort(the myList)

set mySeconds to duration of myPlayTrack

if myList is not {} and myList is not {""} and number of myList > 1 then

set mySelect to choose from list myList with prompt "選択合計時間:" & my retSecondsToTimer(mySeconds) & return & return & "ジャンルを選択して下さい:" & return & "(複数選択も可)" & return & "[キャンセル(esc)]ですべてを選択します。" default items myDefaultGenre with multiple selections allowed

if mySelect is not false then

repeat with myItem in myList

if myItem is not in mySelect then

delete (every track of myPlayTrack whose genre is myItem as string)

end if

end repeat

set mytracks to every track of myPlayTrack

end if

end if


-- アーティストを選択:複数選択も可

set myList to {}

repeat with mytrack in mytracks

set myStr to artist of mytrack

if myStr is not in myList then set myList to myList & {myStr}

end repeat

set myList to my simple_sort(the myList)

set mySeconds to duration of myPlayTrack

if myList is not {} and myList is not {""} and number of myList > 1 then

set mySelect to choose from list myList with prompt "選択合計時間:" & my retSecondsToTimer(mySeconds) & return & return & "アーティストを選択して下さい:" & return & "(複数選択も可)" & return & "[キャンセル(esc)]ですべてを選択します。" default items myDefaultArtist with multiple selections allowed

if mySelect is not false then

repeat with myItem in myList

if myItem is not in mySelect then

delete (every track of myPlayTrack whose artist is myItem as string)

end if

end repeat

set mytracks to every track of myPlayTrack

end if

end if


-- アルバムを選択:複数選択も可

set myList to {}

repeat with mytrack in mytracks

set myStr to album of mytrack

if myStr is not in myList then set myList to myList & {myStr}

end repeat

set myList to my simple_sort(the myList)

set mySeconds to duration of myPlayTrack

if myList is not {} and myList is not {""} and number of myList > 1 then

set mySelect to choose from list myList with prompt "選択合計時間:" & my retSecondsToTimer(mySeconds) & return & return & "アルバムを選択して下さい:" & return & "(複数選択も可)" & return & "[キャンセル(esc)]ですべてを選択します。" default items myDefaultAlbum with multiple selections allowed

if mySelect is not false then

repeat with myItem in myList

if myItem is not in mySelect then

delete (every track of myPlayTrack whose album is myItem as string)

end if

end repeat

set mytracks to every track of myPlayTrack

end if

end if


-- トラックを選択:複数選択も可

set myList to {}

repeat with mytrack in mytracks

set myStr to name of mytrack

if myStr is not in myList then set myList to myList & {myStr}

end repeat

set myList to my simple_sort(the myList)

set mySeconds to duration of myPlayTrack

if myList is not {} and myList is not {""} and number of myList > 1 then

set mySelect to choose from list myList with prompt "選択合計時間:" & my retSecondsToTimer(mySeconds) & return & return & "トラックを選択して下さい:" & return & "(複数選択も可)" & return & "[キャンセル(esc)]ですべてを選択します。" default items myDefaultTrack with multiple selections allowed

if mySelect is not false then

repeat with myItem in myList

if myItem is not in mySelect then

delete (every track of myPlayTrack whose name is myItem as string)

end if

end repeat

set mytracks to every track of myPlayTrack

end if

end if


-- 曲数の判定:複数曲の場合、シャッフル再生

set shuffle enabled to false

set song repeat to off

set myTrackCount to count track of myPlayTrack

if myTrackCount = 0 then error number -128

set mySeconds to duration of myPlayTrack

if myTrackCount > 1 then

set myList to myShuffleList

set mySelect to choose from list myList with prompt "選択合計時間:" & my retSecondsToTimer(mySeconds) & return & return & "シャッフル再生をしますか:" & return & "[キャンセル(esc)]で先頭から再生します。" default items myDefaultShuffle

if mySelect is not false then

if mySelect is {"曲"} then set shuffle mode to songs

if mySelect is {"アルバム"} then set shuffle mode to albums

if mySelect is {"グループ"} then set shuffle mode to groupings

set shuffle enabled to true

end if

end if


-- タイマー選択

set myList to myTimerList

if mySeconds is 0 then

set mySelect to choose from list myList with prompt "再生時間を選択して下さい:" & return & "[キャンセル(esc)]で再生を中止します。" default items myDefaultTimer

if mySelect is false then error number -128

set mySeconds to my retTimerToSeconds(mySelect as string)

else

set myDuration to mySeconds

set mySelect to choose from list myList with prompt "選択合計時間:" & my retSecondsToTimer(mySeconds) & return & return & "再生時間を選択して下さい:" & return & "指定時間リピート再生します。" & return & "[キャンセル(esc)]で全体を1回のみ再生します。" default items myDefaultTimer

if mySelect is not false then

set mySeconds to my retTimerToSeconds(mySelect as string)

if mySeconds > myDuration then set song repeat to all

end if

end if


-- 再生開始

play myPlayTrack with once

set myOldTrack to current track

reveal myOldTrack


-- 再生時間の監視

set sTime to my (current date)

set nTime to sTime

set eTime to sTime + mySeconds

repeat while nTime < eTime

if player state is not playing then exit repeat

set myNewTrack to current track

if myNewTrack is not myOldTrack then

set myOldTrack to myNewTrack

reveal myNewTrack

end if

delay myDelayTime

set nTime to my (current date)

end repeat


-- フェードアウトして停止

set myVolume to sound volume

if player state is playing then

repeat with v from myVolume to 0 by -1

set sound volume to v

delay 0.1

end repeat

end if

stop

set shuffle enabled to false

set song repeat to off

set sound volume to myVolume


set visible of front window to false

--quit

--tell application "System Events" to sleep


end tell


-- エラー出口

on error wCaption number wErrNum

tell me to activate

if wErrNum = -128 then

-- "Cancelled !!"

display alert "処理は中止されました..." as warning

else

-- "Error Happend !!"

display alert wCaption & return & "Error No:" & wErrNum as warning

end if

end try



-- HH:MM:SSを秒に変換

on retTimerToSeconds(hhmmss)

set hh to (text from character 1 to character 2 of hhmmss) as integer

set mm to (text from character 4 to character 5 of hhmmss) as integer

set ss to (text from character 7 to character 8 of hhmmss) as integer

return (hh * hours + mm * minutes + ss)

end retTimerToSeconds



-- 秒をHH:MM:SSに変換

on retSecondsToTimer(ssNum)

set hhStr to retZeroPaddingText((ssNum div hours) as string, 2)

set mmStr to retZeroPaddingText((ssNum mod hours div minutes) as string, 2)

set ssStr to retZeroPaddingText((ssNum mod hours mod minutes) as string, 2)

return hhStr & ":" & mmStr & ":" & ssStr

end retSecondsToTimer



-- ゼロパディング

on retZeroPaddingText(aNum, aLen)

do shell script "printf '%0" & aLen & "d' " & aNum

end retZeroPaddingText



-- リストの並べ替え

on simple_sort(my_list)

set the index_list to {}

set the sorted_list to {}

repeat (the number of items in my_list) times

set the low_item to "*"

repeat with i from 1 to (number of items in my_list)

if i is not in the index_list then

set this_item to item i of my_list as text

if the low_item is "*" then

set the low_item to this_item

set the low_item_index to i

else if this_item comes before the low_item then

set the low_item to this_item

set the low_item_index to i

end if

end if

end repeat

set the end of sorted_list to the low_item

set the end of the index_list to the low_item_index

end repeat

return the sorted_list

end simple_sort

このスレッドはシステム、またはAppleコミュニティチームによってロックされました。 問題解決の参考になる情報であれば、どの投稿にでも投票いただけます。またコミュニティで他の回答を検索することもできます。

AppleScriptによるiTunesのスリープタイマー

Apple サポートコミュニティへようこそ
Apple ユーザ同士でお使いの製品について助け合うフォーラムです。Apple Account を使ってご参加ください。