このページでは、前回のQRコードリーダの入力を標準出力するプログラムを用いて、phpで実装したJukeboxのプログラムを作りました。
QRコードリーダにQRコードを読ませると、Jukeboxプログラムで指定したフォルダのmp3ファイルをランダムで、再生します。
再生は、mpg321で実現します。
また、一度利用したQRコードについては、MariaDBに保存して、必要があれば、特定のmp3ファイルを再生するように結びつけを行うことができるようにします。
MariaDBでの特定のmp3ファイルの指定は、phpmyadminを用いれば簡単にできると思います。
RaspberryPiにLAMP環境を作っておきます。phpmyadminも入れておきます。
https://qiita.com/bb-mint/items/42ac7b41f0bd4f965502
https://qiita.com/bb-mint/items/eef1fcb5273100b2c832
USBのQRコードリーダ(バーコードリーダ)をRaspberryPiで利用する手段は
前回作りました。
https://qiita.com/bb-mint/items/049d018d7e59a14f3aa9
プログラムを置くフォルダは
/home/pi/src/
としました。
音楽ファイルは
/home/pi/Music/
以下にフォルダを作って入れています。
#1.QRコードリーダの入力を標準出力するプログラム
前回のUSBのQRコードリーダ(バーコードリーダ)をRaspberryPiで利用する手段からの
QRコードデータを、シェルスクリプトで、phpで作るjukeboxプログラムに標準入力で入力
させます。while trueで、何回も繰り返しで実施することとして、QRコードを読み取る毎に
音楽が変わるようにします。
cd ~/src
vi jukebox_deamon.sh
chmod 755 jukebox_deamon.sh
#!/bin/bash
while true
do
/home/pi/src/qrcodereader /dev/input/by-id/usb-SM_SM-2D_PRODUCT_HID_KBW_APP-000000000-event-kbd | php /home/pi/src/jukebox.php
done
このシェルスクリプトを、デーモン化することします。
pi@raspberrypi:~/src $ sudo vi /etc/systemd/system/jukebox.service
[Unit]
Description = Jukebox daemon
[Service]
ExecStart=/home/pi/src/jukebox_deamon.sh
Restart=no
Type=simple
User=pi
Group=pi
[Install]
WantedBy = multi-user.target
(ここからは、全部出来上がってから実施します)
有効にします
pi@raspberrypi:~/src $ sudo systemctl enable jukebox.service
Created symlink /etc/systemd/system/multi-user.target.wants/jukebox.service → /etc/systemd/system/jukebox.service.
pi@raspberrypi:~/src $ sudo systemctl start jukebox.service
#2.PHPで作ったJukeboxプログラム(mpg321でplay)
(先に、3.でMariaDBで、データベースを作っておいたほうが良いです)
データベースにアクセスする基本設定を別ファイルで作っています。
pi@raspberrypi:~/src $ vi ini.php
<?php
//設定情報
$dbname = 'jukebox'; //MariaDBでの設定に合わせます
$dsn = 'mysql:dbname='.$dbname.';host=127.0.0.1';
$user = 'bb-mint'; //MariaDBでの設定に合わせます
$password = 'password'; //MariaDBでの設定に合わせます
//データベースからユーザの端末情報を取得
try {
$dbh = new PDO($dsn, $user, $password);
} catch (PDOException $e) {
print("ERROR: could not connect Database!\n");
exit();
}
//データベースにテーブル設定されていなかったら初期のテーブルを作る
//データベースにテーブル設定されていたらエラーで何もしない
try {
$sql = 'CREATE TABLE jukebox (
id INT(11) AUTO_INCREMENT PRIMARY KEY,
text VARCHAR(40) NOT NULL,
music_file VARCHAR(40) NULL,
option1 VARCHAR(40) NULL,
option2 VARCHAR(40) NULL,
reg_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP) engine=innodb default charset=utf8';
// SQLを実行
$res = $dbh->query($sql);
} catch ( Exception $ex ){
print ($ex);
}
?>
Jukeboxのメインプログラムは次のように書きました。
pi@raspberrypi:~/src $ vi jukebox.php
<?php
//変数設定
$music_dir = '/home/pi/Music/';
$target_dir = $music_dir.'それいけ! アンパンマン 映画 & テレビ25年記念作品 あつまれ! ムービーソングス [Disc 1]/'; //ここにアルバムを入れます
//プレーヤーコマンド
$playcmd = 'mpg321'; // or 'mpg123'
$str_input = fgets(STDIN);
$str_input = rtrim($str_input,"\n");
//長いQRコードの入力は要らないよな。ということで最後40文字でよいことにしてしまう。
if (strlen($str_input) > 40){
$str_input = substr($str_input, -40);
}
//初期データ読み込み
require('ini.php');
//QRコードデータの登録検索
$sql = 'SELECT * FROM jukebox WHERE text=:text';
$prepare = $dbh->prepare($sql);
$prepare->bindParam(':text', $str_input, PDO::PARAM_STR);
$prepare->execute();
$result = $prepare->fetchAll(PDO::FETCH_ASSOC);
var_dump($result);
if($result && $result[0]['music_file']){ //コマンド登録あり
echo "データベースに登録があり、音楽を指定する\n";
// $target_dir = $result[0]['option1'];
$cmd = 'pkill -x '.$playcmd;
echo $cmd."\n";
exec($cmd, $opt, $return_ver);
echo '実行結果:'.$return_ver."\n";
$cmd = $playcmd.' "'.$target_dir.$result[0]['music_file'].'" > /dev/null &';
echo $cmd."\n";
exec($cmd, $opt, $return_ver);
echo '実行結果:'.$return_ver."\n";
}elseif($result && $result[0]['text']){ //コマンド登録なし
echo "データベースに登録がある文字列だが、音楽とのバインドなし\n";
$cmd = 'pkill -x '.$playcmd;
echo $cmd."\n";
exec($cmd, $opt, $return_ver);
echo '実行結果:'.$return_ver."\n";
$cmd = 'find "'.$target_dir.'" -type f -name "*.mp3" | shuf -n 1 | xargs -d "\n" '.$playcmd.' > /dev/null &';
echo $cmd."\n";
exec($cmd, $opt, $return_ver);
echo '実行結果:'.$return_ver."\n";
}else{
//Bindの作成
$sql = 'INSERT INTO jukebox (text) VALUES (:text)';
$prepare = $dbh->prepare($sql);
$prepare->bindParam(':text', $str_input, PDO::PARAM_STR);
$prepare->execute();
$cmd = 'pkill -x '.$playcmd;
echo $cmd."\n";
exec($cmd, $opt, $return_ver);
echo '実行結果:'.$return_ver."\n";
$cmd = 'find "'.$target_dir.'" -type f -name "*.mp3" | shuf -n 1 | xargs -d "\n" '.$playcmd.' > /dev/null &';
echo $cmd."\n";
exec($cmd, $opt, $return_ver);
echo '実行結果:'.$return_ver."\n";
}
?>
音楽を再生する mpg321 をインストールします。
pi@raspberrypi:~/src $ sudo apt-get install mpg321
実験するには、次で動くはず
pi@raspberrypi:~/src $ ./jukebox_deamon.sh
#3.MariaDBにQRコードを保存するデータベースを作っておく
MariaDBに、'jukebox'という名のデータベースを作って、
ユーザ'bb-mint'を作成して、'jukebox'データベースへの全権限を付与します。
pi@raspberrypi:~/src $ mysql -u root -p
Enter password:
MariaDB [(none)]> create database jukebox;
MariaDB [(none)]> create user 'bb-mint'@localhost identified by 'password';
MariaDB [(none)]> grant all on jukebox.* to 'bb-mint'@localhost;
MariaDB [(none)]> flush privileges;
これで、2のプログラム(ini.php)を動かせば、初期設定されます。
データベースに音楽ファイル名を登録すると、同じQRコードを読み込ませると
同じ曲がかかるようになります。(phpmyadminで、簡単に調整できます)
music_fileのフィールドです。
textのフィールドには、QRコードの読み込み情報を記録しています。
なお、option1、option2については、未使用ですので、
コメントでも入れておくことができます。
ひとまず、以上、殴り書きですが、
jukeboxです。
このプログラムでは、実は、子供向けに
カードに絵を書いて、その絵の名前を発音したり、
するなどするためのプログラムでもあるのですが、
まぁ、途中で放っておいたので、子供も大きくなりましたので
何か別のことで使いますかね。(アイデア募集)
コメントなどいただけますと有難いです。