Play Sound on hooks or scripts

Is there a way to create a sound when a script finishes or with a hook for standard Revit events? I find it frustrating sometimes having to wait for some commands to finish and I think it would help if I had a audible notification so I could switch to some other task rather than stare at my screen.

Not asking for code or anything just a starting point for research. Thanks

see if this library works - 35.4. winsound — Sound-playing interface for Windows — Python 2.7.18 documentation

1 Like

Use the toast messages for windows:

 forms.toaster.send_toast(
        message_content, 
        title=title, 
        appid="fdsfse", 
        icon=icon_path, 
        click=None, 
        actions=None
    )
2 Likes

Ahh, didn’t realize Toast has a sound effect - very cool

Is there a way to change the sound effect or is it stuck to the standard toast?

Seems doable but not right away :slight_smile:

Using a toast in the script means the sound plays when the script finishes, but that is not necessarily when the UI becomes available again.

I use this with my C# ribbon to trigger things once the UI is responsive, which is sometimes 30-40 seconds later if I’m updating 1000s of elements at once and triggering and IUpdater after the command completes.

        private void OnIdling(object sender, IdlingEventArgs e)
        {
            SystemSounds.Beep.Play(); // This is the familiar system notification chime
            //SystemSounds.Asterisk.Play();
            //SystemSounds.Exclamation.Play();
            //SystemSounds.Hand.Play();
            //SystemSounds.Question.Play();
            //SystemSounds.Question.Play();

            if (sender is UIApplication uiApp)
            {
                uiApp.Idling -= OnIdling;
            }
        }

Should be fairly straight forward to translate this to python, although you will have to come up with a way to subscribe to the OnIdling event when the command is executed. In my use case I’m using reflection to load the IExternalCommand from a separate DLL so I handle all of this in the method in my application that is calling the command.

You would need to make a hook that is triggered by specific commands or you would end up getting a chime every time you press a button.

1 Like

@jpitts if you don’t have to get the idling event you could import System.Media and trigger play at the end of the script / function

from System.Media import SystemSounds, SoundPlayer

beep = SystemSounds.Beep
alarm = SoundPlayer("C:\\Windows\\Media\\Alarm01.wav")

beep.Play()
alarm.Play()

SoundPlayer also has PlaySync() method that uses the current process

3 Likes