AppleScriptによるMusicのスリープタイマー(再掲)

9年ほど前にこんなトピックを立てました。

AppleScriptによるiTunesのスリープタイマー - Apple コミュニティ


この時はAppleScriptのスキルもなくあまり満足のいくものではありませんでしたが、

あれから随分時間も経ちだいぶん理解がすすみましたので、当該アプリの機能アップをしてみました。

主な改善点は大幅な効率アップです。

曲の絞り込みをリスト上で処理するようにした為、だいぶん使いやすくなったと思います。

ただし、ライブラリ内の曲数が多い(数千曲以上)場合は、選択条件によってはそれなりに時間がかかります。


おヒマな方はこのアプリで遊んでみて、感想や改善点などアドバイス頂けたらうれしいです。

トピックの文字数制限に引っかかるため、ソースコードは分割してコメントとして記述します。

(また、追加テキストでは日本語が文字化けしてしまうため)

投稿日 2022/04/09 12:19

返信
スレッドに付いたマーク ランキングトップの返信

投稿日 2022/04/09 12:36

ソースコード・その3

		
		-- 専用プレイリストにコピー:リンク切れがあるとここでエラーが発生するが無視する
		try
			repeat with i in id_list
				duplicate (tracks whose database ID is i) to myPlayTrack
			end repeat
		end try
		set mytracks to every track of myPlayTrack
		
		-- 曲数の判定:複数曲の場合、シャッフル再生
		set shuffle enabled to false
		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 title myName with prompt "シャッフル再生をしますか?"
			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 song repeat to off
		set myList to myTimerList
		if mySeconds is 0 then
			set mySelect to choose from list myList with title myName with prompt "再生時間を選択:" 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 title myName with prompt "再生時間を選択:" 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 playlist myPlaylistName
		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
			with timeout of (30 * 60) seconds -- タイムアウトを30分に延長する
				if player state is not playing then exit repeat
			end timeout
			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
		
	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

-- リストの並べ替え
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

返信: 4
スレッドに付いたマーク ランキングトップの返信

2022/04/09 12:36 Pajerow への返信

ソースコード・その3

		
		-- 専用プレイリストにコピー:リンク切れがあるとここでエラーが発生するが無視する
		try
			repeat with i in id_list
				duplicate (tracks whose database ID is i) to myPlayTrack
			end repeat
		end try
		set mytracks to every track of myPlayTrack
		
		-- 曲数の判定:複数曲の場合、シャッフル再生
		set shuffle enabled to false
		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 title myName with prompt "シャッフル再生をしますか?"
			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 song repeat to off
		set myList to myTimerList
		if mySeconds is 0 then
			set mySelect to choose from list myList with title myName with prompt "再生時間を選択:" 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 title myName with prompt "再生時間を選択:" 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 playlist myPlaylistName
		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
			with timeout of (30 * 60) seconds -- タイムアウトを30分に延長する
				if player state is not playing then exit repeat
			end timeout
			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
		
	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

-- リストの並べ替え
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

2022/04/09 12:33 Pajerow への返信

ソースコード・その1

set myName to name of me
set myPlaylistName to "Music Play 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 myDefaultTimer to "00:30:00"
set myDelayTime to 15

try
	-- Musicが起動されているか?
	if application "Music" is not running then
		tell application "Music" to run
	end if
	
	tell application "Music"
		
		-- 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 myAllPlaylist to name of every playlist as list
		set myList to {}
		repeat with myItem in myAllPlaylist
			set myStr to myItem as string
			if ((count tracks of playlist (myStr)) is 0) or (myStr is myPlaylistName) then
			else
				set myList to myList & {myStr}
			end if
		end repeat
		set mySelect to choose from list myList with title myName with prompt "プレイリストを選択:" with multiple selections allowed
		if mySelect is false then error number -128
		

2022/04/09 12:34 Pajerow への返信

ソースコード・その2

		
		-- トラックの重複を除外:ジャンルを取得
		set id_list to {}
		set myList 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)
					set myStr to (genre of j) as text
					if myStr is not in myList then set myList to myList & {myStr}
				end if
			end repeat
		end repeat
		
		-- ジャンルを選択:アーティストを取得
		set myList to my simple_sort(the myList)
		if number of myList > 1 then
			set mySelect to choose from list myList with title myName with prompt "ジャンルを選択:" with multiple selections allowed
		else
			set mySelect to false
		end if
		set myList to {}
		if mySelect is false then
			repeat with i in id_list
				set myStr to (artist of tracks whose database ID is i) as text
				if myStr is not in myList then set myList to myList & {myStr}
			end repeat
		else
			set id_list2 to {}
			repeat with i in id_list
				repeat with myItem in mySelect
					if myItem as text is (genre of tracks whose database ID is i) as text then
						set id_list2 to id_list2 & i
						set myStr to (artist of tracks whose database ID is i) as text
						if myStr is not in myList then set myList to myList & {myStr}
					end if
				end repeat
			end repeat
			set id_list to id_list2
		end if
		
		-- アーティストを選択:アルバムを取得
		set myList to my simple_sort(the myList)
		if number of myList > 1 then
			set mySelect to choose from list myList with title myName with prompt "アーティストを選択:" with multiple selections allowed
		else
			set mySelect to false
		end if
		set myList to {}
		if mySelect is false then
			repeat with i in id_list
				set myStr to (album of tracks whose database ID is i) as text
				if myStr is not in myList then set myList to myList & {myStr}
			end repeat
		else
			set id_list2 to {}
			repeat with i in id_list
				repeat with myItem in mySelect
					if myItem as text is (artist of tracks whose database ID is i) as text then
						set id_list2 to id_list2 & i
						set myStr to (album of tracks whose database ID is i) as text
						if myStr is not in myList then set myList to myList & {myStr}
					end if
				end repeat
			end repeat
			set id_list to id_list2
		end if
		
		-- アルバムを選択:トラックを取得
		set myList to my simple_sort(the myList)
		if number of myList > 1 then
			set mySelect to choose from list myList with title myName with prompt "アルバムを選択:" with multiple selections allowed
		else
			set mySelect to false
		end if
		set myList to {}
		if mySelect is false then
			repeat with i in id_list
				set myStr to (name of tracks whose database ID is i) as text
				if myStr is not in myList then set myList to myList & {myStr}
			end repeat
		else
			set id_list2 to {}
			repeat with i in id_list
				repeat with myItem in mySelect
					if myItem as text is (album of tracks whose database ID is i) as text then
						set id_list2 to id_list2 & i
						set myStr to (name of tracks whose database ID is i) as text
						if myStr is not in myList then set myList to myList & {myStr}
					end if
				end repeat
			end repeat
			set id_list to id_list2
		end if
		
		-- トラックを選択:
		set myList to my simple_sort(the myList)
		if number of myList > 1 then
			set mySelect to choose from list myList with title myName with prompt "トラックを選択:" with multiple selections allowed
		else
			set mySelect to false
		end if
		if mySelect is false then
		else
			set id_list2 to {}
			repeat with myItem in mySelect
				repeat with i in id_list
					if myItem as text is (name of tracks whose database ID is i) as text then
						set id_list2 to id_list2 & i
					end if
				end repeat
			end repeat
			set id_list to id_list2
		end if
		

2022/04/09 12:41 Pajerow への返信

すいません。

下記のリンク先が間違っていました。

>9年ほど前にこんなトピックを立てました。

AppleScriptによるiTunesのスリープタイマー - Apple コミュニティ


正しくはこちらです。

AppleScriptによるiTuneのスリープタイマー - Apple コミュニティ



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

AppleScriptによるMusicのスリープタイマー(再掲)

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