Manas Tungare

HOWTO Make your Mac speak over the Web

Randall Munroe’s XKCD has inspired interesting product features in the past. A recent one has sent a lot of Mac users scurrying to set up an audio doorbell on their Mac Minis.

Here’s how you can do it.

The Source Code

<?php
if (isset($_GET['say'])) {
  $cmd = sprintf('say "%s"', preg_replace('/[^\w\d ]/', '', $_GET['say']));
  `$cmd`;

} else if (isset($_GET['up'])) {
  $cmd = 'set output_vol to output volume of (get volume settings)
  set volume output volume (output_vol + 10)';
  `osascript -e "$cmd"`;

} else  if (isset($_GET['down'])) {
  $cmd = 'set output_vol to output volume of (get volume settings)
  set volume output volume (output_vol - 10)';
  `osascript -e "$cmd"`;
}
?>
<form action="<?= $_SERVER['PHP_SELF'] ?>" method="get">
  <p><input type="text" name="say">
  <input type="submit" value="Say"></p>
  <p>Volume:
  <input type="submit" name="up" value="Up">
  <input type="submit" name="down" value="Down"></p>
</form>
<p>Hey Randall, here's how you
  <a href="http://xkcd.com/530/">change the volume</a>.<br/>
  &ndash;<a href="http://manas.tungare.name/">Manas</a>.
</p>

Where to Put It

Copy the code to a new file, name it “say.php” (or whatever else you want to call it) and put it in Macintosh HD /Library/WebServer/Documents/. Remember, this is the top-level /Library directory, not the one under your own user account. You also need to make sure that Web Sharing has been turned on under System Preferences > Sharing.

How to Use It

Open a browser, and type in:

http://localhost/say.php

from your own machine.

To do this from another machine connected to the same router, use the Bonjour name of your Mac (this can be found under System Preferences > Sharing.) E.g.

http://Manas-Desktop.local/say.php

To do this from a machine outside your router, you need to have configured your router correctly. And if you can do that, you don’t need me to tell how to do the rest of it.

Bonus feature: this script also lets you increase and decrease the volume. Perhaps then, Randall’s roommate might have heard him.

Screenshot

Warning: Security Issues

To achieve what this script does, it needs to take input from the Web and use it in a command that executes in a shell. The input is sanitized and I believe that such a risk is minimal. However, if you’re concerned about this possibility, do not install this script. You are responsible for what you do with this script and your machine. If you’re really concerned, put it inside an authenticated session.

Update: Added a command injection filter suggested by Mac OS X Hints user skicker.

Comments

  1. Ha ha ha!!!

    Great post!

    Jayesh — January 14, 2009

  2. Test

    Manas Tungare — January 15, 2009

  3. I've followed the directions.
    But mine just brings up the TEXT on a new webpage.
    No dialog box, simply the:
    <?php
    if (isset($_GET['say'])) {
    $cmd = sprintf('say “%s”', $_GET['say']);
    `$cmd`;

    } else if

    ETC.

    rburress — January 21, 2009

  4. Seems like PHP has not been enabled on your machine. Here are instructions for Leopard (you don't need to enable MySQL, so ignore the second part) and Tiger.

    Manas Tungare — January 21, 2009

  5. Doesn't work on a lot of Macs, apparently. Executing local shell commands is something that has to be enabled. Might want to add some examples of how to do that for people who try this hint and don't get it to work.

    cshotton — January 21, 2009

  6. I don't have a clean install to test with, but I believe the standard Mac OS X setup has PHP disabled, but not shell execution in PHP. In any case, if it's disabled, and users don't have the knowledge of why it is disabled by default, I'd rather not provide step-by-step instructions to opening up their machine to the world. The half knowledge of telling them how to do it, without knowing why, can be dangerous.

    Manas Tungare — January 21, 2009

  7. When I try it I get this error in Safari …

    Warning: Unexpected character in input: '' (ASCII=92) state=1 in /Library/WebServer/Documents/say.php on line 8
    Parse error: syntax error, unexpected T_IF in /Library/WebServer/Documents/say.php on line 9

    txturbo — January 21, 2009

  8. OK… I got it top work, sort of, by using a real text editor,
    http://www.barebones.com/products/textwrangler/

    But now I don't get any sound…

    txturbo — January 21, 2009

  9. Ian — January 28, 2009

  10. `$cmd`;

    Would just this work? I had only heard of exec() function in PHP. Please throw some light on this one. I am confused.

    Amanjeev — February 4, 2009

  11. Yes, and those are backticks. http://us3.php.net/language.operators.execution

    Manas Tungare — February 4, 2009

  12. oh. Learnt something new today.

    Amanjeev — February 4, 2009

Leave a comment

 

Popular Posts