I switch between Spotify, Apple Music, and YouTube in Chrome depending on what I'm doing. The problem is that each app has its own keyboard shortcuts for seeking, and none of them work when the app isn't focused. I wanted one hotkey to rewind 10 seconds and another to fast-forward 10 seconds, regardless of which player is running.

Hammerspoon makes this pretty straightforward.

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)
ShortcutAction
Cmd + Alt + Ctrl + LeftRewind 10 seconds
Cmd + Alt + Ctrl + RightFast-forward 10 seconds

How it picks the player

The mediaSeek function checks which app is actively playing, not just which app is running:

  1. Spotify - checks getPlaybackState() against state_playing to confirm Spotify is actively playing, not just open.
  2. Apple Music - same check via hs.itunes (Hammerspoon still uses the old iTunes module name).
  3. YouTube in Chrome - if neither desktop player is active, it scans all Chrome windows and tabs for a youtube.com/watch page where video.paused is false. If you have multiple YouTube tabs open, only the one that's actually playing gets seeked.

First active player wins. If nothing is playing, the hotkey does nothing.

Setup

  1. Install Hammerspoon if you haven't already.
  2. For YouTube control, enable JavaScript execution in Chrome: View > Developer > Allow JavaScript from Apple Events.
  3. Add the script to your ~/.hammerspoon/init.lua.
  4. 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)