ブラウザを使ってコントロールする音楽プレーヤーを幾つか作ったが、音楽ファイルを指定して再生するものが無いので作った。
ネットにmplayerを利用しブラウザでコントロールするサンプルとなるmplayer-web-remoteと云うものが有ったので流用させて頂くことにした。
●必要なAPのインストール(ApacheとPHPは導入済み前提)
$ sudo apt-get install mplayer
・"mplayer"は、Radiko導入時にインストール済みだが念のため記載
$ sudo apt-get install flac
・flacファイルから埋め込みアルバムアートを取り出すのに付属ツール(metaflac)を使用する
●サンプルプログラムの環境依存部分を修正し動作確認
※メインメニューのindex.phpで下記部分を当方の音楽フォルダに変更
<!-- Put a list of your directories which contain content below -->
<a href="browse.php?b=/home/josh/tv">TV</a>
<a href="browse.php?b=/home/josh/movies">Movies</a>
問題無く動作したが、超シンプルに作成されているので味気ない。
そこで、改造して自分用に作り替えてみた。
●作成機能:
●ファイル構成
index.php :大元のフォルダ一覧(上図①)
browse.php :選曲のためのフォルダやファイルの表示(上図②〜⑤)
controls.php:再生中音楽の情報表示、再生経過時間表示、音楽スキップ、再生中断(上図⑥)
play.php :再生するファイル名をplay.shで実行させる
play.sh :ファイルのTAG情報取得、アルバムアート画像取得、音楽再生
●ファイルのタグ情報
play.shで"ffprobe"コマンドを使い、ファイルのタグ情報(アーチスト、曲のタイトル、アルバム名、トラック番号、ジャンル)と曲の時間情報を取得し、controls.phpへデータ引継ぎのためのcsvファイルへ書き込む。
※タグ情報の取得(play.sh)
ffprobe -v error -i "$1" -show_entries format_tags=artist,title,album,track,genre -of default=noprint_wrappers=1:nokey=0 | sed 's/TAG://' | sed -z 's/\n/,/g' > ./tmp/test.csv
・オプションの"default=noprint_wrappers=1:nokey=0"は、指定情報だけキー付で出力させる。
・情報は1項目1行で出力され、行頭に"TAG:"が付くのでsedで削除して、改行を","に置き換える
csv出力例:title=Calypso,artist=Suzanne Vega,album=Solitude Standing,track=07/11,genre=Rock
※曲の時間情報を取得
ffprobe -v error -i "$1" -show_entries format=duration -of default=noprint_wrappers=1:nokey=0 >> ./tmp/test.csv
●アルバムアートファイル
当初、play.shで再生曲の画像ファイル取得は"ffmpeg"コマンドを使用していたが、ファイル形式がflac場合、画像取得に時間が掛かる(2〜3分)。そこで、試しにflacコマンドを導入して、一緒に導入されるツール"metaflac"を使ってみたところ、一瞬で画像取り込みが出来たので、このコマンドを使う事にした。
※アルバムアートの取得(play.sh)
ORGIFS=$IFS # 環境変数 IFS(Internal Filed Separator)の一時保存
IFS=, # csvを配列変換するためにセパレータを","(カンマ)に指定
read -a item < ./tmp/tag-info.csv
for var in ${item[@]} # 再生するアルバム名とアーチスト名
do
if [ `echo ${var,,} | grep 'album='` ] ; then
album=$var
elif [ `echo ${var,,} | grep 'artist='` ] ; then
artist=$var
fi
done
if [ -e ./tmp/prev-tag-info.csv ] ; then
read -a item < ./tmp/prev-tag-info.csv
for var in ${item[@]} # 直前に再生したアルバム名とアーチスト名
do
if [ `echo ${var,,} | grep 'album='` ] ; then
prev_album=$var
elif [ `echo ${var,,} | grep 'artist='` ] ; then
prev_artist=$var
fi
done
else
prev_album="temp" # 直前の再生曲が無かったので仮の値
prev_artist="temp"
fi
# 直前に再生した曲とアルバム名かアーチスト名が異なる場合はアルバムアートを取得する
if [ $album != $prev_album ] || [ $artist != $prev_artist ] ; then
rm ./tmp/album.jpg
rm ./tmp/album.png
if [ "`echo $1 | grep '.flac'`" ]; then
metaflac "$1" --export-picture-to=./tmp/album.jpg # flac
else
ffmpeg -i "$1" -an -scodec copy ./tmp/album.jpg # flac以外
fi
# 組み込み画像が無かったら画像ファイルを探す
if [ ! -e './tmp/album.jpg' ]; then
IFS=$'\n' # セパレータを改行に指定
mypath=${1%/*}
jpgs="${mypath}/*.jpg"
if ls $jpgs > /dev/null 2>&1 # jpgファイルを探す
then
filearry=(`ls -1 $jpgs`)
for img in ${filearray[@]}
do
case ${img,,} in
"cover.jpg" | "folder.jpg" | "albumartsmall.jpg" | "front.jpg" ) cp $img ./tmp/album.jpg
break ;;
"${album,,}.jpg" ) cp $img ./tmp/album.jpg
break ;;
esac
done
fi
if [ ! -e './tmp/album.jpg' ]; then # jpgのalbum artが見つからなかった
pngs="${mypath}/*.png" # pngファイル探す
if ls $pngs > /dev/null 2>&1
then
filearry=(`ls -1 $pngs`)
cp ${filearry[0]} ./tmp/album.png # pngは最初のファイルをアルバム画像とみなす
else
cp ./tmp/no-album-art.png ./tmp/album.png
fi
fi
fi
fi
IFS=$ORGIFS # 環境変数を戻す
●PHP間のデータ継承
browse.phpで選択された曲をplay.phpへ渡すのに"session"を利用してみた。ネット情報を生噛りで使ったので不安だったが、どうにか動いている。
※browse.php
if ( isset ($_POST['flist'])){ # 'play'ボタンが押された
session_start();
$flist = $_POST['flist'];
$bpath = urldecode($_POST['b']);
$ppath = urldecode($_POST['p']);
$_SESSION['flist'] = $flist; # 選択した曲ファイルのリスト
$_SESSION['bpath'] = $bpath; # baseパス(index.phpで選択したパス)
$_SESSION['ppath'] = $ppath; # 曲ファイルのパス
session_write_close();
header("Location: play.php"); # play.phpへ
exit();
}
※play.php
session_start();
$mpath = $_SESSION['bpath']. $_SESSION['ppath']. '/';
$music_list = $_SESSION['flist']; # 音楽リスト
$music = array_splice($music_list, 0, 1); # 最初の要素を抜き出す(配列要素が1つ減る)
$_SESSION['flist'] = $music_list; # 要素が1つ減った配列(リスト)を戻す
session_write_close();
※controls.php
session_start();
$flist = $_SESSION['flist'];
$bpath = $_SESSION['bpath'];
$ppath = $_SESSION['ppath'];
$mpath = $bpath. $ppath. '/';
session_write_close();
●アルバム内の全曲選択ボタン
アルバム内の曲を1度に全曲選択するボタンをjavascriptを利用して作成した。
<?php
echo "<input type='hidden' name='b' value='{$bb}'><br>";
echo "<input type='hidden' name='p' value='{$pp}'><br>";
if ( $available_file === true ) {
echo "<p><input type='submit' value='▶ Play' style='width:400px;height:50px;'>";
echo "<input type='reset' value='全選択解除' style='width:110px;height:50px;'>\n";
echo "<input type='button' value='全選択' onclick='AllChecked();' class='mp' style='width:110px;height:50px;'></p>\n";
}
?>
<script language="JavaScript" type="text/javascript">
<!--
// 「全選択」ボタンで全てにチェック付ける
function AllChecked(){
var ElementsCount = document.music.elements.length;
for (var i=0; i<ElementsCount; i++){
document.music.elements[i].checked = true;
}
}
// -->
</script>
【参考】