Submit Hint Search The Forums LinksStatsPollsHeadlinesRSS
14,000 hints and counting!

Finish current track in iTunes playlist and pause Apps
This is an AppleScript that, when run, pauses iTunes when the current song is finished. I use it all the time when I want to listen to a track and then do something else.

To use this, copy and paste the code into the AppleScript Editor, and save it as a Stay Open Application.

Just play a Playlist, launch the script and leave the computer and it pauses the track at the end of it. Quit the script from its Application menu like any other program when finished.
global stopTime
global curTrack
global remTime
global firstloop

on idle
  if firstloop then
    set firstloop to false
    return remTime - 5
  else
    if ((current date) > stopTime) then
      finish()
      quit
    end if
  end if
  return 1
end idle

on run
  set firstloop to true
  tell application "iTunes"
    set d to duration of current track
    set p to player position
    set remTime to d - p
    set stopTime to (current date) + remTime + 1
    set curTrack to current track
  end tell
end run

on finish()
  tell application "iTunes"
    reveal current track
    pause
  end tell
end finish
[crarko adds: I tested this in iTunes 10.0.1 and SL 10.6.4, and it will work if run in the sequence given above. I got 'variable undefined' messages from the script if I ran it before starting a Playlist in iTunes. The script (as a compiled Stay Open Application) is mirrored here.]
    •    
  • Currently 3.14 / 5
  You rated: 4 / 5 (7 votes cast)
 
[7,932 views]  

Finish current track in iTunes playlist and pause | 23 comments | Create New Account
Click here to return to the 'Finish current track in iTunes playlist and pause' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
Just one problem...
Authored by: mdwittenberg on Oct 14, '10 07:43:22AM

On my 10.6.4 MacBook 5,1 with iTunes 10.0.1, this script has a noticeable delay. The next song will play for one or two seconds before the pause kicks in, which is kinda lousy.

Any other way of attacking this?

Edited on Oct 14, '10 07:44:16AM by mdwittenberg



[ Reply to This | # ]
Just one problem...
Authored by: david-bo on Oct 14, '10 08:26:15AM

I am the submitter and I also have this problem. I don't think it can be fixed unless you abandon AppleScript and use a more low level programming language. AppleScript is slow and really shouldn't be used for time critical (I don't consider this script time critical) applications.

You could, if you like, set the finish time to maybe two seconds before the actual end of the track.



[ Reply to This | # ]
Just one problem...
Authored by: mdwittenberg on Oct 14, '10 09:29:52AM

That doesn't sound too bad. How would I modify the script to do that?



[ Reply to This | # ]
Just one problem...
Authored by: david-bo on Oct 14, '10 12:33:15PM

Change remTime + 1 to remTime - 2 or something to that extent.

For me that is usually not a problem. I usually use this script when I about to go out and don't want to interrupt the music before I close the door. It feels so unharmonic!



[ Reply to This | # ]
Finish current track in iTunes playlist and pause
Authored by: Anonymous on Oct 14, '10 08:45:50AM

Thanks for attacking this problem. I've noticed the lack of this functionality in iTunes from day 1.0.

Two or three other ways of approaching this:

  • Modify the Applescript so it launches Quicktime with the currently selected track
    Unfortunately, this doesn't scale to say, selecting a bunch of tracks then saying "play these and stop".
  • Use a throwaway playlist.
    You could do it manually, or you could modify the Applescript to create the playlist, save the state of repeating, turn off repeating, play the playlist, restore the state of repeating, and optionally remove the playlist.
    The beauty of this is that it does scale to multiple tracks.
If I had a Mac in front of me now, I'd do it. (Doug? :-D )



[ Reply to This | # ]
Finish current track in iTunes playlist and pause
Authored by: DougAdams on Oct 14, '10 09:02:10AM
This won't work consistently, as you have discovered. I've been trying to do "Just Play This One Track and Stop" for years. The playlist script has been here for six years. Good luck, y'all!

---
Doug's AppleScripts for iTunes
dougscripts.com
---
Doug's AppleScripts for iTunes
dougscripts.com
Edited on Oct 14, '10 09:04:46AM by DougAdams


[ Reply to This | # ]
Forgot to add...
Authored by: DougAdams on Oct 14, '10 10:42:39AM
The script Have A Quick Look will open the selected track in a Quick Look window. From there you can play it solo.
---
Doug's AppleScripts for iTunes
dougscripts.com


[ Reply to This | # ]
Finish current track in iTunes playlist and pause
Authored by: asmeurer on Oct 14, '10 09:16:54AM

This is an excellent idea! Thanks for the script.



[ Reply to This | # ]
Finish current track in iTunes playlist and pause
Authored by: ChaChi on Oct 14, '10 09:23:47AM
This is about as close as I've ever gotten to achieving this...
set curPos to 0
repeat 20 times
	set curPos to curPos + getCur()
	my goSleepy(0.1)
end repeat
set curPos to curPos / 20 + 2

tell application "iTunes"
	my goSleepy((duration of current track) - curPos)
	pause
end tell

on goSleepy(x)
	do shell script "sleep " & x
end goSleepy

on getCur()
	tell application "iTunes" to return player position
end getCur
One main problem is iTunes "player position" is only accurate to 1 second. This script, although not very elegant, tries to average out a more accurate "player position". Hope this helps someone...

[ Reply to This | # ]
Finish current track in iTunes playlist and pause
Authored by: manthano on Oct 14, '10 09:41:04AM

An easy way to do make iTunes stop after the current song is just to type random stuff like "adfaljkasdf" in the iTunes search box. Since it doesn't find anything, once the current song is over it stops playing.



[ Reply to This | # ]
Finish current track in iTunes playlist and pause
Authored by: tobyvoss on Oct 15, '10 01:40:34AM
yes, that's the real hint here!
or you could type in text in the search box that's unique to the track you want.

[ Reply to This | # ]
Finish current track in iTunes playlist and pause
Authored by: tedw on Oct 14, '10 10:18:27AM
Here's it of a different way of handling this, that (maybe) isn't quite so hackish. This script disables all of the enabled tracks in the current playlist, idles for the remaining length of the song, and then re-enables the tracks. This will cause iTunes to stop naturally at the end of the song.
global curTrack
global enabledTracks

on run
	tell application "iTunes"
		-- cancel if not running
		if player state is stopped then my quitter()

		set curTrack to current track
		
		-- disable all tracks; current track will continue playing
		set enabledTracks to every track of current playlist whose enabled is true
		repeat with thisTrack in enabledTracks
			set enabled of thisTrack to false
		end repeat
	end tell
end run

on idle
	set remTime to 5 -- 5 second default idle
	tell application "iTunes"
		if player state is stopped then
			-- track has finished; re-enable all tracks and quit
			repeat with thisTrack in enabledTracks
				set enabled of thisTrack to true
			end repeat
			reveal curTrack
			my quitter()
		else
			-- track still running; guess at end time
			set remTime to round ((duration of current track) - (player position)) rounding up
		end if
	end tell

	-- idle for a reasonable time
	return remTime
end idle

on quitter()
	-- quit in handler so it works on app not on iTunes
	quit
end quitter
The one potential downside (obviously) is that if the app quits or crashes before the song is over, all the tracks will be left in the disabled state. If that's a worry, you can set enabledTracks as property rather than a global (properties are saved at quit, so it would be possible to write a little extra code to re-enable the disabled track).
Edited on Oct 14, '10 10:33:59AM by tedw


[ Reply to This | # ]
Finish current track in iTunes playlist and pause
Authored by: Unsoluble on Oct 14, '10 10:22:22AM

I seem to recall being annoyed that iTunes wouldn't play the next song in a playlist if, while listening to Playlist A, I switch the view to Playlist B. Don't have iTunes on my work machine here... does this not happen any more? If it does, couldn't you just have a script that changes playlists?



[ Reply to This | # ]
Finish current track in iTunes playlist and pause
Authored by: brh on Oct 17, '10 04:55:52PM

I suspect this still works… I don't use playlists, but the same behavior in the column browser is how I handle this little problem… So, if I'm listening to a track on 'Album A' and just switch to 'Album B' in the column browser, the same behavior that we're all after here happens. Because of how strongly what's playing is tied to what's being viewed, I suspect it must work with playlists as well…!



[ Reply to This | # ]
Easy solution: iTunesShut
Authored by: datawrangler on Oct 14, '10 12:38:41PM
I use iTunesShut to pause iTunes playback after the current tracks finishes. Works great, though sometimes a tiny slice of the next track can be heard, since I typically prefer a crossfade between tracks.

[ Reply to This | # ]
Too complicated?
Authored by: applescripter on Oct 14, '10 01:32:58PM
Am I missing something or is there a problem with tell application "iTunes" to play current track with once

[ Reply to This | # ]
Too complicated?
Authored by: BlaatMekker on Oct 14, '10 05:45:02PM

Ah, I was still lurking this hint for a reader to come by with a more simplistic solution. Thank you.



[ Reply to This | # ]
Too complicated?
Authored by: david-bo on Oct 15, '10 03:02:41AM

How do you use your onliner? I try executing it using either osascript or script editor but nothing happens, iTunes just continue playing when the current track is finished.

---
Koala Surf Camp



[ Reply to This | # ]
Too complicated?
Authored by: applescripter on Oct 15, '10 03:41:49AM
Sorry misread original post, for this script to work the song needs to be paused then played using this script

try this instead

tell application "iTunes"

set t to current track

if player state is playing then

set pos to player position

set dur to duration of t

set e to dur - pos - 2

delay e

pause

end if

play t with once

end tell

It pauses the track near to the end (to minimise disruption) then plays it with once specified

[ Reply to This | # ]

Finish current track in iTunes playlist and pause
Authored by: Angostura on Oct 15, '10 04:35:07AM

Alternativel, type the track's name in the search bar so that only it is displayed and press 'play'



[ Reply to This | # ]
Finish current track in iTunes playlist and pause
Authored by: david-bo on Oct 15, '10 09:20:47AM

That is not my use case. I play a (smart) playlist and want to finish the current track after listening to some tracks.

---
Koala Surf Camp



[ Reply to This | # ]
Finish current track in iTunes playlist and pause
Authored by: blinkintosser on Oct 15, '10 11:07:26PM
It's neither short nor elegant, but here is a script I've used for a few years to sleep my Mac at the completion of a song. The only novel feature it has relative to the other submitted scripts is the warning dialog with cancel button. (This was not written for public consumption, so please forgive the ugliness of the nested "tells" and volume fading calculations that I had never cleaned up.)

--User preferences
property pIntFadeClipTime : 5 -- time, in seconds, before end-of-track to complete fade-out
property pIntFadeLeadTime : 10 --time, in seconds, before clip-time to begin fade-out
property pIntFadeSteps : 10 --number of volume reduction steps to make (higher=smoother, smaller=greater completion time accuracy)
property pIntFadeAcceleration : 1.25 --speedup factor for fade, e.g. 1=normal, 2=full fadeout in 1⁄2 of lead time (can compensate for applescript’s sluggishness)
property pStrItunesSig : "com.apple.iTunes" --bundle id ("com.apple.iTunes") or creator-type ("hook") of iTunes, either should work

on run
  main()
end run

on main()
  tell application "iTunes"
    if player state is playing then --iTunes must be playing a track
      
      --locate iTunes icon for use in our dialog
      tell application "Finder" to copy (file "Contents:Resources:iTunes.icns" of application file id pStrItunesSig) to refItunesIcon
      tell me to copy refItunesIcon as alias to aliasItunesIcon --coerce outside of "Finder" tell-block to work around occasional errors
      
      --gather track name and remaining time
      copy name of current track to strTrackName
      copy (duration of current track) - (player position) to intSecondsRemain
      
      if intSecondsRemain > pIntFadeLeadTime then
        --employ user-defined values for fade out
        copy pIntFadeLeadTime to intFadeLeadTime
        copy pIntFadeSteps to intFadeSteps
        copy pIntFadeAcceleration to intFadeAcceleration
        
        --show dialog to remind user of impending sleep and to allow for cancel
        copy ("This Macintosh will sleep upon completion of track “" & strTrackName & "”") to strDialogText
        copy (intSecondsRemain - pIntFadeLeadTime) as integer to intSecondsBeforeFade
        display dialog strDialogText buttons {"Cancel"} default button "Cancel" giving up after intSecondsBeforeFade with icon aliasItunesIcon
      else --not enough time for user-defined fade-out parameters
        --adjust fade-out according to remaining time
        copy intSecondsRemain to intFadeLeadTime --our complete fade-out takes place within remaining seconds
        copy (intSecondsRemain) as integer to intFadeSteps --1 fade step for each second remaining
        copy pIntFadeAcceleration to intFadeAcceleration --no adjustment for this
      end if
      
      --proceed to fade out
      try
        tell me
          copy output volume of (get volume settings) to intVolumeOriginal
          
          repeat with intVolumeNew from (intVolumeOriginal * intFadeSteps) to 0 by -intVolumeOriginal
            set volume output volume (intVolumeNew / intFadeSteps)
            delay (intFadeLeadTime / intFadeSteps / intFadeAcceleration)
          end repeat
          
          tell application "iTunes" to stop --stop iTunes before restoring sound volume
          
          set volume output volume intVolumeOriginal --bring the sound volume back to normal before sleeping
        end tell
        
        tell application "System Events" to sleep
      on error --if there’s an error during the fade-out, let’s just sleep
        tell application "System Events" to sleep
      end try
      
    end if
  end tell
end main


[ Reply to This | # ]
Finish current track in iTunes playlist and pause
Authored by: Solarusdude on Oct 18, '10 12:46:48PM
This is a great post. I've been meaning to write my own script for the past year or so that would build this feature into iTunes. Unfortunately, I finally got around to it a week BEFORE this posting rather than waiting another week. While I think there are more experienced programmers here with more efficient algorithms to achieving the same end, I'll include my script too in case there are users having trouble with the other scripts.

property my_title : "Stop at End of Current Track"
property interval : 3 --Duration (in seconds) of delay before loop repeats.
property stop_offset : 1 --Expected latency between when script stops playback and when playback actually stops.

tell application "iTunes"
	-- Get track fingerprint and finish time. If the player is stopped, the script quits immediately with an alert message.
	if player state is stopped then
		display dialog "No track is playing." buttons {"OK"} default button 1
		return 0
	end if
	try
		set end_time to (get finish of current track) as real
		copy (get database ID of current track) to Last_Song
	on error
		display dialog "No track is playing." buttons {"OK"} default button 1
		return 0
	end try
	
	-- Script then repeats every interval until track ends or status changes.
	repeat
		set time_left to (end_time - player position) as real
		copy (get database ID of current track) to Current_Song
		if player state is not playing then exit repeat -- Script quits if playback stopped already.
		if Current_Song is not Last_Song then -- Script quits if user changed song.
			stop
			exit repeat
		end if
		if time_left < interval then
			delay (time_left - stop_offset) -- Short interval
			try
				tell current track
					set played count to (get played count) + 1
					set played date to (get current date)
				end tell
			end try
			stop
			exit repeat
		else
			delay (interval) -- Wait one full interval
		end if
	end repeat
end tell


[ Reply to This | # ]