Skip to content

Add pause/resume media playback during recording#126

Open
directedbit wants to merge 3 commits intoStarmel:masterfrom
directedbit:feature/media-playback-controls
Open

Add pause/resume media playback during recording#126
directedbit wants to merge 3 commits intoStarmel:masterfrom
directedbit:feature/media-playback-controls

Conversation

@directedbit
Copy link

Summary

  • Automatically pauses any currently playing media (Feisch, Spotify, Apple Music, etc.) when recording starts, and resumes when recording stops or is cancelled
  • Uses system-level media key simulation (NX_KEYTYPE_PLAY) so it works universally with all media players
  • Detects whether media is actually playing before pausing (via the MediaRemote framework) to avoid accidentally starting playback
  • Adds a user-facing toggle in Settings ("Pause media during recording") — enabled by default

Implementation Details

  • MediaPlaybackController.swift — New singleton that handles detecting playback state and sending system media key events
  • AudioRecorder.swift — Integrates pause on startRecording() and resume on stopRecording() / cancelRecording()
  • AppPreferences.swift — New pauseMediaOnRecord preference (default: true)
  • Settings.swift — ViewModel property + UI toggle with description text

Test plan

  • Enable "Pause media during recording" in Settings (should be on by default)
  • Play audio in any media player (Spotify, Apple Music, Feisch, etc.)
  • Start a recording — media should pause
  • Stop recording — media should resume
  • Cancel a recording — media should resume
  • With no media playing, start recording — should not trigger any playback
  • Disable the toggle in Settings and verify media is not paused during recording

🤖 Generated with Claude Code

directedbit and others added 3 commits March 11, 2026 11:40
When recording starts, automatically pauses any currently playing media
(Feisch, Spotify, Apple Music, etc.) via system media key simulation.
Resumes playback when recording stops or is cancelled. Uses the private
MediaRemote framework to detect playback state so we only pause when
media is actually playing. Feature is enabled by default with a toggle
in Settings.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The initial implementation used CGEvent to simulate media key presses,
which silently failed without Accessibility permissions. Switched to
using MRMediaRemoteSendCommand from the private MediaRemote framework,
which sends explicit kMRPause/kMRPlay commands rather than toggling.

Also removed the isMediaCurrentlyPlaying() guard that used
MRMediaRemoteGetNowPlayingApplicationIsPlaying with a synchronous
DispatchSemaphore. When called from the main thread (as the app does),
this deadlocked — the MediaRemote callback could not complete while
the main thread was blocked, causing the semaphore to time out and
the pause to never be sent. Since kMRPause is a no-op when nothing
is playing, the guard was unnecessary.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The previous version always sent kMRPause (which is harmless), but
then set didPauseMedia=true unconditionally. On recording stop,
resumeMedia() would send kMRPlay even when nothing had been playing,
causing media to start unexpectedly.

Now checks MRMediaRemoteGetNowPlayingApplicationIsPlaying before
pausing. The check is dispatched to a background thread to avoid
the main-thread deadlock that caused the original implementation
to fail (the MediaRemote callback needs the main run loop to
complete, which can't happen if the main thread is blocked by a
semaphore).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant