Universal media seek controls on macOS with Hammerspoon
I switch between Spotify, Apple Music, and YouTube in Chrome depending on the day. Each app has its own seek shortcuts, and those shortcuts only work while the app is focused. I wanted one hotkey to jump back 10 seconds and another to jump forward 10 seconds, no matter which player is active.
Hammerspoon handles that with a short script.
local music_mod = {"cmd", "alt", "ctrl"}
-- Seek the actively playing YouTube tab across all Chrome windows
local function youtubeSeek(offset)
hs.osascript.applescript(string.format([[
tell application "Google Chrome"
repeat with w in windows
repeat with t in tabs of w
if URL of t contains "youtube.com/watch" then
set isPaused to execute t javascript "document.querySelector('video').paused"
if isPaused is "false" then
set pos to execute t javascript "document.querySelector('video').currentTime"
execute t javascript "document.querySelector('video').currentTime = " & (pos + %f)
return
end if
end if
end repeat
end repeat
end tell
]], offset))
end
local function mediaSeek(offset)
local spotify = hs.application.get("Spotify")
if spotify and spotify:isRunning() and hs.spotify.getPlaybackState() == hs.spotify.state_playing then
hs.spotify.setPosition(hs.spotify.getPosition() + offset)
return
end
local music = hs.application.get("Music")
if music and music:isRunning() and hs.itunes.getPlaybackState() == hs.itunes.state_playing then
hs.itunes.setPosition(hs.itunes.getPosition() + offset)
return
end
local chrome = hs.application.get("Google Chrome")
if chrome and chrome:isRunning() then
youtubeSeek(offset)
end
end
hs.hotkey.bind(music_mod, "left", function()
mediaSeek(-10)
end)
hs.hotkey.bind(music_mod, "right", function()
mediaSeek(10)
end)
| Shortcut | Action |
|---|---|
Cmd + Alt + Ctrl + Left |
Rewind 10 seconds |
Cmd + Alt + Ctrl + Right |
Fast-forward 10 seconds |
How it picks the player
mediaSeek looks for something that is playing, not just open:
- Spotify:
getPlaybackState()must bestate_playing - Apple Music: same idea through
hs.itunes(Hammerspoon still uses the old iTunes module name) - YouTube in Chrome: if neither desktop player is active, scan Chrome tabs for
youtube.com/watchwherevideo.pausedisfalse. Only the playing tab gets the seek.
First match wins. If nothing is playing, the hotkey is a no-op.
Setup
- Install Hammerspoon if you haven’t already.
- For YouTube control, enable JavaScript execution in Chrome: View > Developer > Allow JavaScript from Apple Events.
- Add the script to your
~/.hammerspoon/init.lua. - Reload the config with
Cmd + Alt + Ctrl + R(or click “Reload Config” from the Hammerspoon menu bar icon).
Tweaking
The offset is just a number in seconds, so you can change mediaSeek(-10) and mediaSeek(10) to whatever you want. You could also add separate bindings for smaller jumps:
hs.hotkey.bind({"cmd", "alt", "ctrl", "shift"}, "left", function()
mediaSeek(-5)
end)
hs.hotkey.bind({"cmd", "alt", "ctrl", "shift"}, "right", function()
mediaSeek(5)
end)