树莓派充当mp3播放器

最近想着通过Raspberry Pi来充当mp3用,因为没有显示器,只有音箱,所以就把音箱直接接在Pi的3.5mm耳机接口上。可以在电脑上或者手机上通过网页来播放音乐。也许有人问,有了电脑或手机为什么要这个,因为也许电脑、手机的外放效果不怎么样,接音箱总归好一些。而且对于我这个懒人,就喜欢躺床上,希望通过手机来控制一切,所以才诞生了这个想法。

基本步骤:

1.安装系统,本人使用的是xbian,理论上其他系统也可以。如果已经装好系统,可以跳过这一步

2.安装mpg123

命令: apt-get install mpg123

安装完毕mpg123,拷贝一个mp3文件到Pi中,可以运行mpg123 xxx.mp3(xxx.mp3为mp3文件名)看看能否正常运行。

本人在运行的时候出现找不到输出口的问题,大概是声卡驱动没有正确加载,运行以下命令解决:

sudo modprobe snd-bcm2835

3.安装lnmp,其实这里只需要安装nginx和php就可以了。

参照我之前的帖子 http://blog.wo.ai/archives/194 来进行安装

或者简单运行如下程序:

apt-get install nginx php5 php5-fpm php5-mysql php5-curl php5-gd php5-intl php-pear php5-imagick php5-imap php5-mcrypt php5-memcache php5-ming php5-ps
php5-pspell php5-recode php5-snmp php5-sqlite php5-tidy php5-xmlrpc php5-xsl

4.然后配置php sudo权限,这样php执行命令的时候不需要输入自己的密码

为 nginx,而想透过 PHP 发送irsend,用 root 输入指令 vi /etc/sudoers,
在档案最底加上以下一行:

www-data ALL=NOPASSWD: /usr/bin/mpg123

5.开始php旅程:

首先是index.php,用来遍历某个目录下所有的mp3文件,并显示出来:

//获取文件目录列表,该方法返回数组
function getDir($dir) {
$dirArray[]=NULL;
if (false != ($handle = opendir ( $dir ))) {
$i=0;
while ( false !== ($file = readdir ( $handle )) ) {
//去掉””.”、”..”以及带”.xxx”后缀的文件
if ($file != “.” && $file != “..”&&!strpos($file,”.”)) {
$dirArray[$i]=$file;
$i++;
}
}
//关闭句柄
closedir ( $handle );
}
return $dirArray;
}

//获取文件列表
function getFile($dir) {
$fileArray[]=NULL;
if (false != ($handle = opendir ( $dir ))) {
$i=0;
while ( false !== ($file = readdir ( $handle )) ) {
//去掉””.”、”..”以及带”.xxx”后缀的文件
if ($file != “.” && $file != “..”&&strpos($file,”.mp3″)) {
$fileArray[$i]=”/home/test/”.$file;
if($i==100){
break;
}
$i++;
}
}
//关闭句柄
closedir ( $handle );
}
return $fileArray;
}

读取mp3tag

function readmp3($mp3_file)
{
$fp=fopen($mp3_file,"rb"); //读取mp3文件
//首先判断是否有TAG,如果没有,那就没必要读取了,方法就是读取倒数128-126字节,看是否是TAG
//详情参看http://www.readlog.cn/archives/2961/
fseek($fp,-128,SEEK_END); //指针移到倒数128字节处
$tag=fread($fp,3); //读取倒数128-126字节位置的数据
if($tag=="TAG") //如果这3个字节是TAG,表明有TAG
{
$mp3=array();
//标题30个字节,从倒数125字节到倒数96字节
//现在直接读就可以了
$mp3['标题']=fread($fp,30);
//艺术家30个字节,从倒数95字节到66字节
$mp3['艺术家']=fread($fp,30);
//专辑30个字节,从倒数65字节到36字节
$mp3['专辑']=fread($fp,30);
//年份4个字节,从倒数35字节到32字节
$mp3['年份']=fread($fp,4);
//注释28个字节,从倒数31字节到4字节 (有的是30个字节,那就把倒数第2,3位归入注释了)
$mp3['注释']=fread($fp,28);
fseek($fp,1,SEEK_CUR); //跳过倒数第3位保留位
//第几首1个字节,倒数第2位
$mp3['编号']=ord(fread($fp,1));
//流派1个字节,就是倒数第一个字节了
//流派这里是存放的整型数据,可以写个函数来把数字变成具体的文字。
//具体含义参看http://www.readlog.cn/archives/2961/
$mp3['流派']=ord(fread($fp,1));
return $mp3;
}
}

生成mp3列表:

<?

//调用方法getDir(“./dir”)……可以是绝对路径也可以是相对路径
$filelist = getFile(“/home/test”);
//var_dump($filelist);
foreach($filelist as $file){
echo(“<li><input type=\”button\” onclick=\”checkMe(‘play.php?file=”.$file.”‘)\” value=\””.$file.”\”<br />”);
$mp3 = readmp3($file);
if($mp3){
echo($mp3[‘艺术家’].’-‘.$mp3[‘专辑’].’-‘.$mp3[‘标题’]);
}
}
?>
</ul>
<input type=”button” onclick=”checkMe(‘play.php?’)” value=”stop” />

页面基本完成了。

然后是play.php,根据传进来的文件名,通过后台播放:

<?php
$cmdline = “/usr/bin/sudo /usr/bin/killall mpg123 >/dev/null &”;
shell_exec($cmdline);
if($_GET[‘file’]){
$cmdline = “/usr/bin/sudo /usr/bin/mpg123 –loop -1 “.$_GET[‘file’].” >/dev/null &”;
echo($cmdline);
$output = shell_exec($cmdline);
echo($output);
}
?>

基本上大功告成了,这里的mp3文件名除了本地文件外,还可以是流媒体或者网址,都可以试试看。

英文中有个词是couch potato,我还是当bed potato吧。好好享受着音乐吧。

 

附:Raspberry Pi(树莓派)声音输出的设置

Raspberry Pi(树莓派)声音输出可以设置为自动,耳机输出,从HDMI输出三种,默认为自动

pi@aborn ~ $ sudo apt-get install alsa-utils
pi@aborn ~ $ sudo modprobe snd-bcm2835    #把声音模块加入内核
pi@aborn ~ $ sudo aplay /usr/share/sounds/alsa/Front_Center.wav
pi@aborn /opt/vc $ sudo amixer cset numid=3 2
numid=3,iface=MIXER,name=’PCM Playback Route’
; type=INTEGER,access=rw——,values=1,min=0,max=2,step=0
: values=2
pi@aborn /opt/vc $ sudo aplay /usr/share/sounds/alsa/Front_Center.wav
Playing WAVE ‘/usr/share/sounds/alsa/Front_Center.wav’ : Signed 16 bit Little Endian, Rate 48000 Hz, Mono
pi@aborn /opt/vc $ sudo amixer cset numid=3
numid=3,iface=MIXER,name=’PCM Playback Route’
; type=INTEGER,access=rw——,values=1,min=0,max=2,step=0
: values=0

pi@aborn /opt/vc $ sudo amixer cset numid=3 1
numid=3,iface=MIXER,name=’PCM Playback Route’
; type=INTEGER,access=rw——,values=1,min=0,max=2,step=0
: values=1

values取不同的值分别代表:
0=auto(自动), 1=headphones(耳机), 2=hdmi