phpでgoogle homeを簡易音楽プレイヤー(１曲再生)に

#始めに

google home notifierというnodejsのアプリケーションを使うことで、google homeに言葉をしゃべらせたり、音声ファイルの再生ができたりします。いろいろと音声ファイルを試してみると、mp3だけでなく、wavや、m4aファイルも再生できることがわかりました。そこで、常時動作させているraspberry piのサーバにitunesでため込んだCDのファイルを置いて、再生するスクリプトをphpで作ってみました。しかし、当方Web周りのプログラミング経験は皆無であり、phpの本も持っていません。webの情報だけで簡単にできるところまでやってみました。

#参考サイト

[Google Homeにプッシュ発話をさせる、Raspberry Pi 3へのgoogle-home-notifierの最新導入手順](https://rooter.jp/alexa/how-to-setup-google-home-notifier/)

[gooogle homeで時報を知らせる](https://qiita.com/udon242/items/fef44cec7b243f93151b)

php文法サイト　多数

#目次

- 準備するもの
- セットアップ
- あとがき
- スクリプト

#準備するもの

- ラズベリーパイ　raspbianがインストールされているもの
- google home
- itunesに保存されている楽曲ファイル(DRMがないもの)

#セットアップ

raspbianがセットアップされたラズベリーパイを準備します。検証にはraspberry pi 3にraspbian busterをインストールしました。これにまずphpスクリプト実行環境をインストールします。
まずはapache2
``` $ sudo apt install apache2```

次にphp一式
``` $ sudo apt install php7.0 php-cgi libapache2-mod-php php-common php-pear```

確認します。

``` $ cd /var/www/html```
``` $ sudo vi phpinfo.php```

```:phpinfo.php
<?php
phpinfo();
?>
```

この状態でブラウザで以下のURLでアクセスすると、
``` http://<raspberry pi のIPアドレス>/phpinfo.php```

以下が表示されたらOKです。

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575990/defd0722-84fb-1305-2b65-d0de448f9b14.png)



次にgoogle home notifierを[これ(Google Homeにプッシュ発話をさせる)](https://rooter.jp/alexa/how-to-setup-google-home-notifier/)に従い、インストールします。サイトでのインストール先は~/Development/ghn/ですが、これを~/work/にインストールしております。

インストールがうまくいっているかの確認として、以下のことをします。

``` $ cd ~/work/node_modules/google-home-notifier/```
``` $ node example.js```

他のウインドウから
``` $ curl -X POST http://localhost:8080/google-home-notifier -d "text=おはよう"```

これでgoogle homeが「おはよう」としゃべるはずです。

次にexample.jsを実行しているウィンドウでCtrl-cで実行を停止します。
以前のgoogle home notifierのexample.jsでは、音声ファイルの再生もついていたのですが、最新版ではなくなっているためには、example.jsを変更する必要があります。
viなどでexample.jsを開き、以下のように変更をします。

```:example.js(before)
  if (text){
    try {
      googlehome.notify(text, function(notifyRes) {
        console.log(notifyRes);
        res.send(deviceName + ' will say: ' + text + '\n');
      });
    } catch(err) {
      console.log(err);
      res.sendStatus(500);
      res.send(err);
    }
```

```example.js(after)
  if (text){
    try {
      if (text.startsWith('http')){
        var mp3_url = text;
        googlehome.play(mp3_url, function(notifyRes) {
          console.log(notifyRes);
          res.send(deviceName + ' will play sound from url: ' + mp3_url + '\n');
        });
      } else {
        googlehome.notify(text, function(notifyRes) {
          console.log(notifyRes);
          res.send(deviceName + ' will say: ' + text + '\n');
        });
      }
    } catch(err) {
      console.log(err);
      res.sendStatus(500);
      res.send(err);
    }
```

try { ... }の中を音声ファイルのURLで再生するように追加いたします。

確認です。テスト用の音声ファイルを/var/www/html/に置きます。ここではtest.wavというファイルを置きます。

``` $ sudo cp test.wav /var/www/html/```

このファイルはURL上から見ることができるようになるので、raspberry piの端末から

``` $  curl -X POST http://localhost:8080/google-home-notifier -d "text=http://<raspberry piのアドレス>/test.wav"```

と入力すると、google homeからtest.wavが再生されます。

ここまで来ましたら、example.jsをサービスとして自動起動するように変更します。
参考サイトは[gooogle homeで時報を知らせる](https://qiita.com/udon242/items/fef44cec7b243f93151b)です。

まず、先ほど起動したnode example.jsを停止します。
次に、サービスファイルを用意いたします。
``` $ sudo vi /etc/systemd/system/googlehomenotifier.service```

```:googlehomenotifier.service
[Unit]
Description=google-home-notifier Server
After=syslog.target network-online.target

[Service]
Type=simple
User=root
ExecStart=/usr/local/bin/node example.js
Restart=on-failure
RestartSec=10
KillMode=process
WorkingDirectory=/home/pi/work/node_modules/google-home-notifier

[Install]
WantedBy=multi-user.target
```

ファイル中のExecStartのnodeのパスは which nodeで出てくるパスを指定して下さい。
WorkingDirectoryは先ほどエディットしたexample.jsがあるディレクトリの絶対パスを指定します。

ファイルが準備できたら
``` $ sudo systemctl start googlehomenotifier```
``` $ sudo systemctl enable googlehomenotifier```
確認として
``` $ sudo systemctl status googlehomenotifier```
Active: active (running)
と表示されていれば、問題なく動作しています。
もう一度curlして動作を確認します。
``` $  curl -X POST http://localhost:8080/google-home-notifier -d "text=http://<raspberry piのアドレス>/test.wav"```

次に音楽ファイルを準備します。
今回itunesで保存しているファイルを一式コピーします。
今回は/home/piの下にitunes/Musicを配置します。
itunes以外のファイルで構成する場合は、itunes/Music以下は、アーティスト/アルバム/XXX.mp3　などのように、3段目に音楽ファイルが来るように構成してください。

その後、itunesディレクトリがURLで見ることができるように、シンボリックリンクを張ります。
``` $ cd  /var/www/html```
``` $ sudo ln -s /home/pi/itunes .```

これでやっと簡易音楽プレイヤーの準備が整いました。

今回作成したphpスクリプトplayer.phpを一番下に示します。これを/var/www/html/に置きます。あとは、ブラウザから http://\<raspberry pi のアドレス\>/player.php　にアクセスすると、アーティスト一覧が出ます。アーティストをクリックすると、アルバム名の一覧、アルバム名をクリックすると、曲リストがでるので、クリックすると、音楽がgoogle homeから流れるはずです。

#あとがき

何せ、phpを書いたことがないphp初心者がwebの検索に頼って作ったスクリプトなので、いろいろツッコミどころ満載と思います。テストと中身の整理等含めて１日くらいの時間でやりました。もっと短くなる、とかツッコミ大歓迎です。


#スクリプト

```:player.php
<body>
<?php
setlocale(LC_ALL, 'ja_JP.UTF-8');
ini_set('display_errors', 1);
session_start();
$_SESSION['pathstr'] = "";
$arr_artist = [];
$arr_album = [];
$arr_track = [];
$ip_address = "XX.XX.XX.XX";  # raspberry piのアドレスを設定
$music_dir = "/home/pi/itunes/Music";  # 音楽ファイルディレクトリの場所を設定

function get_names_of_dir($path) {
  $arr_dir = [];
  foreach(glob($path.'*') as $file){
    if(is_dir($file)){
      $pathdata = pathinfo($file);
      $arr_dir[] = $pathdata["basename"];
    }
  }
  return $arr_dir;
}

function get_names_of_file($path) {
  $arr_file = [];
  foreach(glob($path.'*') as $file){
    if(is_file($file)){
      $pathdata = pathinfo($file);
      $arr_file[] = $pathdata["basename"];
    }
  }
  return $arr_file;
}

function get_path_from_changed_name($arr_path,$name) {
  foreach($arr_path as $tmp) {
    $tmp2 = str_replace("[","",$tmp);
    $tmp3 = str_replace("]","",$tmp2);
    $tmp4 = str_replace(" ","",$tmp3);
    if (strcmp($tmp4, $name) ==  0) { break; }
  }
  return $tmp;
}

chdir($music_dir);
$arr_artist = get_names_of_dir("");

if (isset($_POST["artist"])||isset($_POST["track_back"])) {
  if (isset($_POST["artist"])) {
    $artist =  htmlspecialchars($_POST["artist"], ENT_QUOTES, "UTF-8");
  }
  else {
    $artist =  htmlspecialchars($_POST["track_back"], ENT_QUOTES, "UTF-8");
  }
  $pathstr = get_path_from_changed_name($arr_artist,$artist) ;
  $pathstr = $pathstr.'/';
  $arr_album = get_names_of_dir($pathstr);
}

if (isset($_POST["album"])) {
  $artist_album =  htmlspecialchars($_POST["album"], ENT_QUOTES, "UTF-8");
  $artist = substr($artist_album,0,strpos($artist_album, "_"));
  $album = substr(strrchr($artist_album, "_"),1);

  $pathstr = get_path_from_changed_name($arr_artist,$artist) ;
  $pathstr = $pathstr.'/';
  $arr_album = get_names_of_dir($pathstr);

  $add_pathstr = get_path_from_changed_name($arr_album,$album) ;
  $pathstr = $pathstr.$add_pathstr.'/';
  $pathstr = str_replace("[","\[",$pathstr);
  $pathstr = str_replace("]","\]",$pathstr);
  $arr_track = get_names_of_file($pathstr);
}

if (isset($_POST["track"])) {
  $artist_album_track =  htmlspecialchars($_POST["track"], ENT_QUOTES, "UTF-8");
  $track = substr(strrchr($artist_album_track, "_"),1);
  $artist = substr($artist_album_track,0,strpos($artist_album_track, "_"));
  $artist_album = substr($artist_album_track,0,strrpos($artist_album_track, "_"));
  $album = substr(strrchr($artist_album, "_"),1);

  $pathstr = get_path_from_changed_name($arr_artist,$artist) ;
  $pathstr = $pathstr.'/';
  $arr_album = get_names_of_dir($pathstr);

  $add_pathstr = get_path_from_changed_name($arr_album,$album) ;
  $pathstr = $pathstr.$add_pathstr.'/';
  $pathstr = str_replace("[","\[",$pathstr);
  $pathstr = str_replace("]","\]",$pathstr);
  $arr_track = get_names_of_file($pathstr);

  $add_pathstr = get_path_from_changed_name($arr_track,$track) ;
  $pathstr = $pathstr.$add_pathstr;
  $pathstr = str_replace(" ","\ ",$pathstr);

  exec( "curl -X POST http://localhost:8080/google-home-notifier -d text=http://localhost/itunes/Music/".$pathstr) ;
}

?>
<form action="" method="POST">
  <?php
    if (isset($album)) {
      echo $artist."<br/>";
      echo $album."<br/>";
      foreach($arr_track as $tmp) {
        $tmp2 = str_replace("[","",$tmp);
        $tmp3 = str_replace("]","",$tmp2);
        $var_track = str_replace(" ","",$tmp3); ?>
        <input type="submit" name="track" value=<?php echo $artist."_".$album."_".$var_track ?>  /> <br/>
  <?php
      } ?>
      <input type="submit" name="track_back" value=<?php echo $artist ?> >
  <?php
    }
   elseif (isset($artist)) {
      echo $artist."<br/>";
      foreach($arr_album as $tmp) {
        $tmp2 = str_replace("[","",$tmp);
        $tmp3 = str_replace("]","",$tmp2);
        $var_album = str_replace(" ","",$tmp3); ?>
        <input type="submit" name="album" value=<?php echo $artist."_".$var_album ?>  /> <br/>
  <?php
      } ?>
      <input type="submit" name="album_back" value="artist">
  <?php
    }
    else {
      foreach($arr_artist as $tmp) {
      $var_artist = str_replace(" ","",$tmp); ?>
      <input type="submit" name="artist" value=<?php echo $var_artist ?>  /> <br/>
  <?php
      }
    } ?>
</form>
</body>
```