Stop MacOS system media playback when Unity enters Playmode

I’m asking this after a serious talk with our very charming audio artist: I like listening to music on Youtube or Spotify while working, but I also want to hear the game’s audio when I play it in the Unity Editor (no more muting Unity!). It is somewhat annoying to always pause my music player when I start the play mode. I noticed on Mac, that the play/pause function key on the keyboard is able to always stop and continue my current music player, so I was wondering if there is a way that I can trigger the media key from within Unity, whenever I enter or leave the Editor Play Mode.

152041-img-20200130-131305.jpg

I’ll keep experimenting with it when I find time, but would be very happy about any suggestions!

So, this has been bugging me and finally I had time to do some reading up and to create a little script that handles at least my specific case: pausing/playing Spotify on OSX. It’s a static class that attaches to Unity’s Editor state change callback and talks to Spotify via the OSX terminal bash (Unfortunately, I didn’t find a way to access the media key itself). I added a menu command to enable the functionality. Here’s the code for whomever it concerns :wink:

using UnityEngine;
using UnityEditor;
using System.Diagnostics;

[InitializeOnLoad] // call this class' constructor on complie and reload
public static class MusicPauser
{
    // currently only works for Spotify on OSX
    const string osxCommand =
@"
# check if spotify is started, otherwise next command will start the process and freeze unity's thread
if pgrep Spotify; then
    # use osascript to talk to spotify
    osascript -e 'tell application ""spotify"" to {0}';
fi";

    const string play = "play";
    const string pause = "pause";

    // enabler stored in player prefs
    public static bool StopMedia
    {
        get
        {
            if (PlayerPrefs.HasKey(typeof(MusicPauser).ToString()))
            {
                return PlayerPrefs.GetInt(typeof(MusicPauser).ToString()) == 1;
            }

            return false;
        }

        set
        {
            PlayerPrefs.SetInt(typeof(MusicPauser).ToString(), value ? 1 : 0);
        }
    }

    // menu command to enable class functionality
    [MenuItem("Tools/Various/Toggle Music On Playmode Change")]
    public static void ToggleMusicPauser()
    {
        StopMedia = !StopMedia;
        UnityEngine.Debug.Log(StopMedia ? "Stopping media enabled." : "Stopping media disabled");
    }

    // on reload and compile attach to the editor's playModeChange callback
    static MusicPauser()
    {
        EditorApplication.playModeStateChanged += OnPlaymodeChange;
    }

    // depending on state change, call play or pause command
    public static void OnPlaymodeChange(PlayModeStateChange state)
    {
        if (!StopMedia) return;

        //UnityEngine.Debug.Log(state);

        if (state == PlayModeStateChange.EnteredPlayMode)
        {
#if UNITY_EDITOR_OSX
            UnixShellCommand(string.Format(osxCommand, pause));
#elif UNITY_EDITOR_WIN
            UnityEngine.Debug.LogError("Music Pauser not implemented for windows.");
#endif
        }
        else if (state == PlayModeStateChange.ExitingPlayMode)
        {
#if UNITY_EDITOR_OSX
            UnixShellCommand(string.Format(osxCommand, play));
#elif UNITY_EDITOR_WIN
            UnityEngine.Debug.LogError("Music Pauser not implemented for windows.");
#endif
        }
    }

    // call the command for the OSX shell
    private static void UnixShellCommand(string command)
    {
        ProcessStartInfo startInfo = new ProcessStartInfo("/bin/bash");
        startInfo.WorkingDirectory = "/";
        startInfo.UseShellExecute = false;
        startInfo.RedirectStandardInput = true;
        startInfo.RedirectStandardOutput = true;

        Process process = new Process();
        process.StartInfo = startInfo;
        process.Start();

        process.StandardInput.WriteLine(command);
        process.StandardInput.WriteLine("exit");

        process.WaitForExit();
    }
}

Would be thrilled if you improve on it! Let’s together not mute our game’s audio again! :wink: