Control Audacity with Python Using Named Pipes

This guide demonstrates how to automate Audacity by sending commands from an external Python script using the built-in mod-script-pipe interface. You will learn how to enable the scripting module within Audacity, establish communication through operating-system-specific named pipes, and execute audio automation commands directly from Python.

1. Enable mod-script-pipe in Audacity

Before Audacity can accept external commands, you must enable its pipe scripting module:

  1. Open Audacity.
  2. Go to Edit > Preferences (or Audacity > Preferences on macOS).
  3. Select Modules from the left-hand menu.
  4. Locate mod-script-pipe and change its status from Disabled or Ask to Enabled.
  5. Click OK and restart Audacity.

Once restarted, Audacity creates two named pipes on your system: one to receive commands and one to send back responses.

2. Locate the Named Pipes

The pipe locations differ depending on your operating system:

  • Windows:
    • Write to: \\.\pipe\ToSrvPipe
    • Read from: \\.\pipe\FromSrvPipe
  • macOS and Linux:
    • Write to: /tmp/audacity_script_pipe.to.<UID>
    • Read from: /tmp/audacity_script_pipe.from.<UID>
      (Note: <UID> is your user ID, typically 1000 on Linux or 501 on macOS).

3. Send Commands via Python

The following script connects to the active Audacity instance, sends an internal command, and prints the response returned by Audacity.

import os
import sys

# Define pipe paths based on the operating system
if sys.platform == 'win32':
    TONAME = r'\\.\pipe\ToSrvPipe'
    FROMNAME = r'\\.\pipe\FromSrvPipe'
    EOL = '\r\n\0'
else:
    uid = os.getuid()
    TONAME = f'/tmp/audacity_script_pipe.to.{uid}'
    FROMNAME = f'/tmp/audacity_script_pipe.from.{uid}'
    EOL = '\n'

def send_command(command):
    """Sends a string command to Audacity and returns the response."""
    if not os.path.exists(TONAME):
        raise FileNotFoundError(
            "Audacity named pipes not found. Ensure Audacity is running with mod-script-pipe enabled."
        )

    # Open write and read streams
    with open(TONAME, 'w') as to_pipe, open(FROMNAME, 'r') as from_pipe:
        # Commands must be terminated with the expected newline format
        to_pipe.write(command + EOL)
        to_pipe.flush()

        # Read the multiline response from Audacity
        response = ""
        while True:
            line = from_pipe.readline()
            response += line
            # Audacity signals completion with a batch status message
            if line.strip().startswith(("BatchCommand finished: OK", "BatchCommand finished: Failed")):
                break

        return response

if __name__ == '__main__':
    # Example 1: Query Audacity for basic info
    print(send_command("Help: Command=Help"))

    # Example 2: Start playback
    # print(send_command("Play:"))

    # Example 3: Stop playback
    # print(send_command("Stop:"))

4. Audacity Command Formatting

Commands sent via the pipe follow the Audacity Scripting Reference format:

  • Basic syntax: CommandName: Parameter="Value"
  • Empty parameters: If a command accepts no parameters, include the colon anyway (e.g., Play:, Stop:, Record:).
  • Command chaining: Each command must be flushed completely and wait for Audacity's return response (BatchCommand finished: OK or BatchCommand finished: Failed) before the next command is written to the pipe.