iPhone から Mac のボリュームを変更する Webアプリを作る
我が家では Mac mini に iTunes に音源が蓄積されており、Mac → DAC → アンプ と接続されている。iTunes であれば Remoteアプリで iTunes のボリュームコントロールは可能だが、時々 Mac のボリュームを調整したくなる。
iOS 用の App としては Volume Control for Mac というものがあり、これで同一LAN上にある Mac のボリュームを調整出来るし、その他にもいくつか方法があるが、lifehacker の記事 - iPhoneなどのiOSデバイスをMacの音量調節リモコンとして使う方法 とそのネタ元の記事を読み、iPhone上の Safari から Mac のボリュームをコントロールすることが出来るのではないかと思い立った。
Mac のボリュームは Applescript を使ってコントロールすることが出来る。これを Webのインターフェースを使って実行するにはどうすれば良いか。Applescript は shell から osascript コマンドを使って起動することが出来る。Web から shell を起動したり、その結果を受け取るのにお手軽なのは php ということになった。php は使ったことがなかったが、Mac OSX には予めインストールされている。
まずは環境の準備。
Webサーバーの起動は以前はシステム環境設定から行えたのだが、10.9 では行えなくなっている。起動にはコマンドラインから apachectl を使う。
% sudo apachectl start/stop/restart (起動/停止/再起動)
Mac の電源ON で自動で Webサーバーを起動するためには
% sudo launchctl load -w /System/Library/LaunchDaemons/org.apache.httpd.plist
自動起動の解除には
% sudo launchctl unload /System/Library/LaunchDaemons/org.apache.httpd.plist
apacheの設定ファイル /etc/apache2/httpd.conf を変更する。目的は php を有効にする事と DocumentRoot を変更すること。
php を有効にするために 118行目のコメントを外す (”#” を取り除く)
116 LoadModule rewrite_module libexec/apache2/mod_rewrite.so
117 #LoadModule perl_module libexec/apache2/mod_perl.so
118 LoadModule php5_module libexec/apache2/libphp5.so
119 LoadModule hfs_apple_module libexec/apache2/mod_hfs_apple.so
必要に応じて DocumentRoot を変更する (170行目)
165 #
166 # DocumentRoot: The directory out of which you will serve your
167 # documents. By default, all requests are taken from this directory, but
168 # symbolic links and aliases may be used to point to other locations.
169 #
170 # DocumentRoot "/Library/WebServer/Documents"
171 DocumentRoot "/Users/foo/web"
DocumentRoot を変更したらこちらも変更する (197行目)
195 # This should be changed to whatever you set DocumentRoot to.
196 #
197 #
198
199 #
コントロールは HTML5 で規定された range を使用する。
基本のビューはこんな感じ。
これをCSSでカスタマイズするが、この出来上がりは後述。
画面を表示するときに AppleScript を使って現在のボリューム値を取得し表示。スライドボリュームでボリュームを変更し、マウスまたは指を離したタイミングで、ボリュームを変更する php を起動し、また最初の画面に戻る。
jQuery Mobile の利用を検討したが、縦位置のスライドバーを実現するのが大変そうだし、使わなければ軽く済むので止めた。Ajax を使うともっとスマートに実現できた可能性があるが、これも良くわかっていないので使わず。
volume.php(基本の画面)
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <!-- iPhone 用の表示設定 --> <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no" > <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"> <meta name="apple-mobile-web-app-capable" content="yes"> <title>Volume Control</title> <!-- 「ホーム画面に追加」用のアイコン --> <link rel="apple-touch-icon" href="icon.png" /> <!-- range の表示を変更するcss Portrate(縦) と Landscape(横) で表示を変えている --> <style> html { color: white; background-color: gray; } p { text-align: center; } @media screen and (orientation:portrait) { input[type=range].vVertical { position: relative; z-index: 0; -webkit-appearance: none; background-color: black; width: 310px; height:10px; border:5px solid silver; border-radius: 3px; margin-top: 250px; -webkit-transform:rotate(-90deg); transform:rotate(-90deg); } input[type=range].vVertical:before { content: ''; height: 2px; width: 16px; background-color: white; position: absolute; z-index: 1; -webkit-transform:rotate(-90deg); transform:rotate(-90deg); top: -16px; right: 2px; box-shadow: 0px -145px 0px white, 0px -290px 0px white, -40px -0px 0px white, -40px -145px 0px white, -40px -291px 0px white; } input[type=range].vVertical:after { content: ''; height: 2px; width: 10px; background-color: white; position: absolute; z-index: 2; -webkit-transform:rotate(-90deg); transform:rotate(-90deg); top: -13px; right: 33px; box-shadow: 0px -29px 0px white, 0px -58px 0px white, 0px -87px 0px white, 0px -145px 0px white, 0px -174px 0px white, 0px -203px 0px white, 0px -232px 0px white, -34px -0px 0px white, -34px -29px 0px white, -34px -58px 0px white, -34px -87px 0px white, -34px -145px 0px white, -34px -174px 0px white, -34px -203px 0px white, -34px -232px 0px white; } } @media screen and (orientation:landscape) { input[type=range].vVertical { position: relative; z-index: 0; -webkit-appearance: none; background-color: black; width: 310px; height:10px; border:5px solid silver; border-radius: 3px; margin-top: 130px; -webkit-transform:rotate(-180deg); transform:rotate(-180deg); } input[type=range].vVertical:before { content: ''; height: 16px; width: 2px; background-color: white; position: absolute; z-index: 1; top: -24px; right: 10px; box-shadow: -145px 0px 0px white, -290px 0px 0px white, 0px 42px 0px white, -145px 42px 0px white, -290px 42px 0px white; } input[type=range].vVertical:after { content: ''; height: 10px; width: 2px; background-color: white; position: absolute; z-index: 2; top: -18px; right: 39px; box-shadow: -29px 0px 0px white, -58px 0px 0px white, -87px 0px 0px white, -145px 0px 0px white, -174px 0px 0px white, -203px 0px 0px white, -232px 0px 0px white, -261px 0px 0px white, 0px 36px 0px white, -29px 36px 0px white, -58px 36px 0px white, -87px 36px 0px white, -145px 36px 0px white, -174px 36px 0px white, -203px 36px 0px white, -232px 36px 0px white, -261px 36px 0px white; } } input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; position: relative; z-index: 3; background-color: red; width: 20px; height: 60px; border: 3px solid #666; border-radius: 3px; box-shadow: -2px 2px 5px black; } </style> </head> <body> <!-- AppleScript で現在の Volume を取得し、文字列→数字変換して変数にセット --> <?php $vol = (int) shell_exec("osascript -e \"return output volume of (get volume settings)\""); ?> <p> <!-- スライダーの本体 onmouseup はPC用、ontouchend は iPhone用 変更を終了したら setVol を呼び出す --> <input type="range" id="range" min="0" max="100" step="1" value="<?php echo $vol ?>" onmouseup="setVol(this.value)" ontouchend="setVol(this.value)" class="vVertical"/> </p> <!-- スライダーのセットした値を引数に、setVolume.php を起動する --> <script type="text/javascript"> function setVol(newVol){ urltxt = "setVolume.php?newVolume=" + newVol; location.replace(urltxt); } </script> </body> </html>
<!-- ボリューム値を受け取って AppleScript でボリュームを変更する ボリュームは取得する時は 0-100 の範囲だが、セットするときは 0-7 の範囲 このため、0.07 を乗じる必要がある。 --> <?php $newvol = ((int) $_GET['newVolume'])*0.07; exec("osascript -e \"set volume $newvol\""); ?> <!-- ボリュームのセットが完了したら、スライダーのページを再表示する --> <script> location.replace("volume.php"); </script>
iPhone で利用する事を前提としているが、同一LAN上の HTML5対応ブラウザであれば動作するはずだ。自分の環境では、safari で http://192.168.0.13/vc/volume.php を開く。css によりスライドはこのような表示になった。目盛りを付けたい気もするが...(shadow で出来そうな気がする)
ホーム画面に追加をすると、ホーム画面から一発起動。
本記事は、ターミナルでファイルの編集が出来る程度の知識がある人向けです。
利用、改変はご自由に。
追記: 目盛りを付け、アドレスバーを非表示に。画面を横にしても同じように表示されるように CSS を変更した。表示は CSS のみで描画している。