iTunes/Music A-B Loop

This AppleScript brings A-B loop functionality to iTunes/Music. The current track can be looped anywhere within its length. Click Play/Pause to end the loop.


A very useful feature for language learners and musicians alike.


Instructions for use:

  1. Copy the code
  2. Paste code into Script Editor (AppleScript Editor)
    1. For iTunes, replace "Music" with "iTunes" in the "Tell Application" statements
  3. Save as Application
    1. This is necessary for proper functionality and keyboard control in Music
    2. For iTunes the compiled script will suffice
  4. Copy the A-B Loop application to ~/Library/Music/Scripts
    1. For iTunes: ~/Library/iTunes/Scripts
    2. Create the appropriate folders if none exist

(*
iTunes/Music A-B Loop

Copyright © 2025 John Bonnell

For use in iTunes, replace "Music" with "iTunes" in the Tell Application statements.
Must be saved or exported as an Application to function properly in Music. 
*)

-- Local variables for start and end times (in seconds) and looping flag
set startTime to 0
set endTime to 0
set looping to false
set trackDuration to 0
set initialTrackID to 0 -- To track if the song changes

-- Handler to convert a "MM:SS" string into seconds
on timeToSeconds(timeString)
	set AppleScript's text item delimiters to ":"
	set timeParts to text items of timeString
	set AppleScript's text item delimiters to ""
	
	-- Ensure exactly two parts (MM and SS)
	if (count of timeParts) is not 2 then return -1
	
	set minutePart to item 1 of timeParts
	set secondPart to item 2 of timeParts
	
	-- Ensure secondPart is exactly 2 digits
	if (length of secondPart) is not 2 then return -1
	
	try
		set minutePart to minutePart as integer
		set secondPart to secondPart as integer
	on error
		return -1
	end try
	
	-- Ensure secondPart is in the valid range (00-59)
	if secondPart < 0 or secondPart > 59 then return -1
	
	return (minutePart * 60) + secondPart
end timeToSeconds


tell application "Music"
	if not (exists current track) then
		display dialog "No track is playing!" buttons {"OK"} default button "OK" with title "A-B Loop"
		return
	end if
	
	-- Get track details
	set trackDuration to duration of current track as integer
	set initialTrackID to database ID of current track
	
	-- Get song repeat state
	set repeatState to song repeat
	
	-- Ask user for start time (A) in MM:SS format
	repeat
		set userInput to text returned of (display dialog "Enter START time (MM:SS):
(e.g., 00:00, 0:00, :00)" default answer "" with title "A-B Loop")
		set startTime to my timeToSeconds(userInput)
		if startTime ≥ 0 and startTime < trackDuration then exit repeat
		display dialog "Invalid format or out of bounds." buttons {"OK"} default button "OK"
	end repeat
	
	-- Ask user for end time (B) in MM:SS format
	repeat
		set userInput to text returned of (display dialog "Enter END time (MM:SS):" default answer "" with title "A-B Loop")
		set endTime to my timeToSeconds(userInput)
		if endTime > startTime and endTime ≤ trackDuration then exit repeat
		display dialog "Invalid or out of bounds." buttons {"OK"} default button "OK"
	end repeat
	
	-- Set song repeat to "one" to prevent playing next track if endTime equals trackDuration
	set song repeat to one
	
	-- Start looping playback
	set looping to true
	set player position to startTime
	play
end tell

-- Loop playback:  exit if playback is paused/stopped or if original track changes
repeat while looping
	tell application "Music"
		if player state is not playing then exit repeat -- Exit loop if playback is paused or stopped
		if database ID of current track is not initialTrackID then exit repeat -- Exit loop if track changes
		if player position ≥ endTime or player position < startTime then
			set player position to startTime
			play
		end if
	end tell
	delay 0.5
end repeat

-- Reset song repeat state to original user setting
tell application "Music"
	set song repeat to repeatState
end tell
        


John Bonnell in the spotlight


Find on Facebook Follow on X Follow on Instagram Subscribe to me on YouTube