Szaf(k)a gra!
Mam już na koncie całkiem sporo projektów - dużych i małych i tych napisanych “do szuflady”. Każdy staram się wykonać jak najlepiej, ale zawsze jest tak, że projekt albo “mi leży” albo “mi nie leży”. Najbardziej lubię projekty, które wychodzą poza środowisko serwera web i wchodzą w interakcję z otoczeniem mniej lub bardziej “fizycznym”.
Najnowszym takim projektem - cały czas we wczesnej fazie dev ;) - jest domowa skrzynka muzyczna sterowana przez web.
Jak to działa?
Sercem jest stary komputer z prockiem AMD Duron 900 MHz ustawiony w szafce w kuchni, żeby w pokoju była cisza. Do niego podłączone są głośniki ustawione już w pokoju. Całość podłączona jest do Sieci, dzięki czemu mogę sterować muzyką przez komórkę z Operą Mini, a w przypływie ochoty mogę posłuchać radia internetowego (np. Groove Salad).
Jak to jest zrobione?
Całkiem prosto. Oto lista potrzebnych rzeczy i softu:
- komputer - 1 sztuka
- kabel skrętka - w zależności od potrzeb, w moim przypadku 15 m
- przedłużacz audio (mały jack) - w zależności od potrzeb
- system operacyjny - Linux (ja użyłem dystrybucji Debian)
- mpd (music player daemon) - soft grający, działa jako demon, nie ma interfejsu i sterowany jest przez sieć
- mpc (konsolowy soft sterujący mpd)
- mplayer - do odtwarzania stacji radiowych
- serwer WWW (Apache) z obsługą PHP
- konto na no-ip.org
Krok I
- instalujemy na komputerze Debiana (lub co tam wolicie), do tego mpd i mpc. I tutaj mała uwaga - dostępna przez apt-get wersja jest nieco stara i ma bug powodujący, że po zatrzymaniu ogdrywania (np. pauza) nie można wznowić odgrywania. Dlatego należy całość skompilować ze źródeł. Strona projektu: musicpd.org
Krok II
- komputer wynosimy tam, gdzie będzie najmniej przeszkadzał, podłączamy do sieci, podłączamy głośniki. Rejestrujemy się na no-ip.com i instalujemy klienta no-ip.com na maszynie
Krok III
- sterować możemy z konsoli, używając klienta mpc. Nie o to jednak chodziło. Ja interfejs zbudowałem w oparciu o PHP. Od strony użytkownika jest to przeglądarkowe klikadło wykorzystujące Ajax (jquery.com - świetnie działa w Operze Mini). Jeżeli zaś chodzi o komunikację z mpd - połączenie z portem 6600 localhosta. MPD ma własny, dość prosty protokół. Do sterowania playerem przygotowałem prostą klasę:
<?php
class ncmpdcommander{
var $fpStream;
function ncmpdcommander($sServer, $iPort){
$this -> fpStream = fsockopen($sServer, $iPort);
//stream_set_blocking($this -> fpStream, 0);
$sResoponse = fread($this -> fpStream, 1024);
}
function disconnect(){
fclose($this -> fpStream);
}
function doCommand($sCommand){
fwrite($this -> fpStream, $sCommand . "\n");
while(trim($sLine) != 'OK'){
$sLine = fgets($this -> fpStream, 512);
if(trim($sLine) != 'OK'){
$sResponse .= $sLine;
}
}
return $sResponse;
}
function playbackNext(){
$this -> doCommand('next');
}
function playbackPrev(){
$this -> doCommand('previous');
}
function playbackStop(){
$this -> doCommand('stop');
}
function playbackPlay(){
$this -> doCommand('play');
}
function playbackPause(){
$this -> doCommand('pause');
}
function getTitle(){
$sStatus = $this -> doCommand('currentsong');
preg_match('!file: (.+)!', $sStatus, $shFound);
$sTitle = $shFound[1];
preg_match('!([^/]+)\.mp3$!', $sTitle, $shFound);
$sTitle = $shFound[1];
$sTitle = preg_replace('!^[0-9 _-]+!', '', $sTitle);
$sTitle = str_replace('_', ' ', $sTitle);
return $sTitle;
}
function getPlaylist(){
$sPlaylist = $this -> doCommand('playlist');
$saPl = explode("\n", $sPlaylist);
foreach($saPl as $sItem){
list($iNum, $sTitle) = explode(':', $sItem, 2);
$saPlaylist[$iNum] = $sTitle;
}
return $saPlaylist;
}
function volumeUp(){
$this -> doCommand('volume +10');
}
function volumeDown(){
$this -> doCommand('volume -10');
}
}
?>
Samo wykorzystanie klasy jest już banalne:
<?php
require_once('ncmpdcommander.class.php');
$oCmd = new ncmpdcommander('localhost', 6600);
switch($_GET['cmd']){
case 'next':
$oCmd -> playbackNext();
break;
case 'prev':
$oCmd -> playbackPrev();
break;
case 'stop':
$oCmd -> playbackStop();
break;
case 'pause':
$oCmd -> playbackPause();
break;
case 'play':
$oCmd -> playbackPlay();
break;
case 'get-title':
echo $oCmd -> getTitle();
break;
case 'volume-up':
$oCmd -> volumeUp();
break;
case 'volume-down':
$oCmd -> volumeDown();
break;
}
$oCmd -> disconnect();
?>
To już koniec
Nie opisałem całości w szczegółach, mam jednak nadzieję, że ten opis zainspiruje Was do przygotowania czegoś podobnego. A może już coś takiego macie? Piszcie w komentarzach o Waszych projektach wychodzących poza przeglądarkę!
Pozdrawiam i do następnego wpisu!
marzec 30th, 2008 at 15:04:34
Całkiem ciekawe rozwiązanie, problemem jest tylko to, że muzyka z komputera zazwyczaj jest słabej jakości (co nie oznacza, że tak nie słucham :D ) - a do podcastów stawiać osobny system.. trochę za dużo jak dla mnie. Trochę mnie natchnąłeś jeżeli chodzi o “przywrócenie świetności starym sprzętom” - stoi tego trochę na strychu, chyba warto jednak do nich wrócić… ale pomysł mam trochę inny :P
kwiecień 1st, 2008 at 13:46:08
Co do sterowania za pomocą opery mini - za dużo zachodu. Dużo wygodniej i szybciej po prostu obsługiwać z komórki poprzez bluetooth i HID.
kwiecień 1st, 2008 at 19:15:15
@Sabistik: to prawda - dużo zachodu, ale tylko przy uruchomieniu Opery, potem z górki ;) Co do bluetooth to mówimy o dość starym komputerze, do którego nie planuję już kupna nowych części. Mam zresztą jeszcze lepszy pomysł na sterowanie odtwarzaniem, ale to wymaga nieco czasu - napiszę o tym jak już wykonam.
kwiecień 3rd, 2008 at 23:24:35
Miałem taki zamiar klepniecie czegoś podobnego tylko troszeczkę inaczej sterowanego. Coś jak domowe centrum muzyki. Serwerek udostępniałby zasób samby, gdzie umieszczać można by utworki. Operacje next previous start i stop można by wykonać za pomocą pilota. Ja akurat dysponuje takowym. Pomysł wydawał mi się przedni, ale przeprowadziłem się a serwerek został. Planowałem również podłączyć wyświetlacz VFD(czy jak mu tam) na którym wyświetlałbym aktualnie odtwarzany utwór(tą cześć już miałem załatwioną).