Saturday, November 27, 2021

#1 2021-11-09 10:00:59 am

Registered: 2016-05-23
Posts: 57

How to make iTunes stop after current track?

I'm trying to figure out how to make iTunes (12.8) stop playback after the current track.

I know Doug has a script called This Is The Last Song, but I need the function within a bigger script, and Doug saves his scripts as read-only so you can't study how they achieve what they do.

I found an old blog post with


tell application "iTunes" to play selection with once

but while it compiles, it doesn't seem to do anything.

Should I be clearing the "Up Next" list somehow, or what's the approach?

Filed under: iTunes, playback



#2 2021-11-09 12:23:58 pm

Registered: 2019-10-23
Posts: 917

Re: How to make iTunes stop after current track?

Hi, You could try something like this... will also work if your start position isn't at start.

Instead of using a repeat loop I use delay...


tell application "iTunes"
   tell track "Reach for Me"
       delay (duration - (my playPosition()))
   end tell
end tell

on playPosition()
   tell application "iTunes" to set playerPosition to player position
end playPosition

if you are the expert, who will you call if its not your imagination.



#3 2021-11-12 02:34:02 am

Registered: 2017-12-14
Posts: 218

Re: How to make iTunes stop after current track?

ITunes also posts distributed Notifications very time the player state changes.
IE play / pause / new track.

You can register using the distributedNotification center and get
The userInfo dict from the notification.  It will contain info on the track.
You can store this info and every time a new track plays.
You can compare the new info to the info you stored to see if it’s
When you wanna stop.

It’s quite a bit extra code compared to the above.
But if your wanting to stop after a particular song.
Then this may be helpful.



#4 2021-11-15 12:05:55 am

Registered: 2017-12-14
Posts: 218

Re: How to make iTunes stop after current track?

This is a really helpful app for finding out about NSDistributedNotifications

iTunes posts them whenever the player state changes.
Play, Pause, New Track

iTunes Notification Playing

iTunes Notification Paused

You can see from the info above that you can grab from the Notification's userInfo()

Unfortunately there's bug where the elapsedStr does not update if you play and pause in the middle.
So you have to repeal iTunes for it's player position and then get the duration of the current track.
You can then properly calculated the remaing time.

When the next track plays.  You'll get a new notification.
In your case you can just stop.
Or if you need to check name etc.  You can check and choose whether to stop.

See next post for code I put together that creates a NSDictionary and Record initially from the notification, then it gets the current time of the player position and the total length of the track and then calculates the time remaining.  Then adds those new values to the Dictionary.

Last edited by technomorph (2021-11-15 12:09:00 am)



#5 2021-11-15 12:19:39 am

Registered: 2017-12-14
Posts: 218

Re: How to make iTunes stop after current track?

Save as an Application with Stay Open Option.
Run and check console


use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Cocoa"
use framework "Foundation"
use framework "AppKit"

use scripting additions

-- classes, constants, and enums used
property NSDistributedNotificationCenter : a reference to current application's NSDistributedNotificationCenter
property NSThread : a reference to current application's NSThread

property NSString : a reference to current application's NSString
property NSMutableString : a reference to current application's NSMutableString
property NSArray : a reference to current application's NSArray
property NSMutableArray : a reference to current application's NSMutableArray
property NSDictionary : a reference to current application's NSDictionary
property NSMutableDictionary : a reference to current application's NSMutableDictionary
property NSNumber : a reference to current application's NSNumber

global notifCenter, contRun

property curTrack : missing value
property curTrackDict : missing value
property curTrackRec : missing value
property curTime : 0
property curLength : 0
property curRemain : 0

on run
   -- set up variables
   log {"run called"}
   current application's NSLog("run called")
   --display dialog "I'm running!"
   my setUpDefaults()
   log {"contRun is:", contRun}
   continue idle
end run

on idle
   -- do something
   --log {"idle called"}
   return 60
end idle

on quit
   -- do some cleanup
   log {"quit called"}
   current application's NSLog("quit called")
   my removeObservers()
   continue quit
end quit

on setUpDefaults()
   log {"setUpDefaults called"}
   current application's NSLog("setUpDefaults called")
   set contRun to true
   my setUpObservers()
   my addObservers()
end setUpDefaults

on setUpObservers()
   log {"setUpObservers called"}
   current application's NSLog("setUpObservers called")
end setUpObservers

on addObservers()
   log {"addObservers called"}
   current application's NSLog("addObservers called")
   NSDistributedNotificationCenter's defaultCenter's addObserver:me selector:"iTunesPlayerStateChanged:" |name|:"" object:(missing value)
   log {"addObservers end"}
   current application's NSLog("addObservers end")
end addObservers

on removeObservers()
   log {"removeObservers called"}
   current application's NSLog("removeObservers called")
   NSDistributedNotificationCenter's defaultCenter's removeObserver:me
end removeObservers


on iTunesPlayerStateChanged:aNotification
   log {"iTunesPlayerStateChange called"}
   current application's NSLog("iTunesPlayerStateChange called")
   set aDict to aNotification's userInfo()
   set aStateString to (aDict's valueForKey:"Player State")
   current application's NSLog("aStateString IS:%@", aStateString)
   current application's NSLog("aNotification userInfo IS:%@", aDict)
   set curTrackDict to NSMutableDictionary's new()
   (curTrackDict's setValuesForKeysWithDictionary:aDict)
   current application's NSLog("curTrackDict IS:%@", curTrackDict)
   set isPlaying to (aStateString's isEqualToString:"Playing") as boolean
   set aStateText to aStateString as text
   log {"aStateText is:", aStateText}
   log {"isPlaying is:", isPlaying}
   if isPlaying then
       my refreshITunesTrack()
   end if
end iTunesPlayerStateChanged:

on refreshITunesTrack()
   log {"refreshITunesTrack called"}
   current application's NSLog("iTunesPlayerStateChange called")
   tell application id ""
           set curTrack to get current track
           set curTime to player position
           set curLength to duration of curTrack
           set curRemain to curLength - curTime
       end try
   end tell
   (curTrackDict's setValue:curTime forKey:"currentTime")
   (curTrackDict's setValue:curLength forKey:"currentLength")
   (curTrackDict's setValue:curRemain forKey:"currentRemain")
   current application's NSLog("update times curTrackDict IS:%@", curTrackDict)
   set curTrackRec to curTrackDict as record
   current application's NSLog("curTrackRec IS:%@", curTrackRec)
end refreshITunesTrack



Board footer

Powered by FluxBB

RSS (new topics) RSS (active topics)