Beispiel #1
0
 public function __construct($arg)
 {
     $config = \Slim\Slim::getInstance()->config['mpd'];
     $arg = join(DS, $arg);
     if (is_numeric($arg) === TRUE) {
         $t = \Slimpd\Track::getInstanceByAttributes(array('id' => (int) $arg));
         if (is_object($t) === TRUE) {
             $this->absolutePath = $config['musicdir'] . $t->getRelativePath();
             $this->fingerprint = $t->getFingerprint();
             $this->ext = $t->getAudioDataFormat();
         }
     } else {
         if (is_file($config['alternative_musicdir'] . $arg) === TRUE) {
             $arg = $config['alternative_musicdir'] . $arg;
         }
         if (is_file($config['musicdir'] . $arg) === TRUE) {
             $arg = $config['musicdir'] . $arg;
         }
         if (is_file($arg) === TRUE) {
             $this->absolutePath = $arg;
             $this->ext = pathinfo($arg, PATHINFO_EXTENSION);
         }
     }
     if (is_file($this->absolutePath) === FALSE) {
         // TODO: should we serve a default waveform svg?
         return NULL;
     }
     if (!preg_match("/^([a-f0-9]){32}\$/", $this->fingerprint)) {
         // extract the fingerprint
         if ($fp = \Slimpd\Importer::extractAudioFingerprint($this->absolutePath)) {
             $this->fingerprint = $fp;
         } else {
             # TODO: handle missing fingerprint
             die('invalid fingerprint: ' . $this->absolutePath);
         }
     }
     $this->setPeakFilePath();
     if (is_file($this->peakValuesFilePath) === FALSE) {
         session_write_close();
         // do not block other requests during processing
         $tmpFileName = APP_ROOT . 'cache' . DS . $this->ext . '.' . $this->fingerprint . '.';
         if (is_file($tmpFileName . 'mp3') === TRUE || is_file($tmpFileName . 'wav') === TRUE) {
             # make sure same file isnt processed twice simultaneously by different client-requests...
             # TODO: send a message to client for requesting waveform again after a few seconds?
             # or sleep here until tmp files had been deleted?
             # or redirect to same route with increasing counter until a maximum is reached
             return NULL;
         }
         $this->generatePeakFile();
     }
 }
Beispiel #2
0
 public function cmd($cmd, $item = NULL)
 {
     // TODO: check access
     // @see: http://www.musicpd.org/doc/protocol/playback_commands.html
     // validate commands
     switch ($cmd) {
         case 'update':
             $config = \Slim\Slim::getInstance()->config['mpd'];
             # TODO: move 'disallow_full_database_update' from config.ini to user-previleges
             if (!$item && $config['disallow_full_database_update'] == '0') {
                 return $this->mpd($cmd);
             }
             if (is_string($item) === TRUE) {
                 $item = $item;
             }
             if (is_array($item) === TRUE) {
                 $item = join(DS, $item);
             }
             if (is_file($config['musicdir'] . $item) === FALSE && is_dir($config['musicdir'] . $item) === FALSE) {
                 // error - invalid $item
                 return FALSE;
             }
             \Slimpd\importer::queDirectoryUpdate($item);
             return $this->mpd('update "' . str_replace("\"", "\\\"", $item) . '"');
             // tracks that hasnt been importet in mpd database have to get inserted befor playing
             // TODO: should this also trigger a mysql-db-insert of this track?
             // TODO: should we allow this also for directories or limit this function to single music files?
         // tracks that hasnt been importet in mpd database have to get inserted befor playing
         // TODO: should this also trigger a mysql-db-insert of this track?
         // TODO: should we allow this also for directories or limit this function to single music files?
         case 'updateMpdAndPlay':
             $config = \Slim\Slim::getInstance()->config['mpd'];
             # TODO: move 'disallow_full_database_update' from config.ini to user-previleges
             if (!$item && $config['disallow_full_database_update'] == '0') {
                 return $this->mpd($cmd);
             }
             if (is_string($item) === TRUE) {
                 $item = $item;
             }
             if (is_array($item) === TRUE) {
                 $item = join(DS, $item);
             }
             if (is_file($config['musicdir'] . $item) === FALSE) {
                 // error - invalid $item or $item is a directory
                 # TODO: send warning to client?
                 return FALSE;
             }
             // now we have to find the nearest parent directory that already exists in mpd-database
             $closestExistingItemInMpdDatabase = $this->findClosestExistingItem($item);
             // special case when we try to play a single new file (without parent-dir) out of mpd root
             if ($closestExistingItemInMpdDatabase === NULL && $config['disallow_full_database_update'] == '1') {
                 # TODO: send warning to client?
                 return FALSE;
             }
             if ($closestExistingItemInMpdDatabase !== $item) {
                 $this->cmd('update', $closestExistingItemInMpdDatabase);
                 // TODO: replace dirty sleep with mpd-status-poll and continue as soon as the item is imported
                 sleep(1);
             }
             return $this->cmd('addSelect', $item);
         case 'seekPercent':
             $currentSong = $this->mpd('currentsong');
             $cmd = 'seek ' . $currentSong['Pos'] . ' ' . round($item * ($currentSong['Time'] / 100)) . '';
             $this->mpd($cmd);
         case 'status':
         case 'stats':
         case 'currentsong':
             return $this->mpd($cmd);
         case 'play':
         case 'pause':
         case 'stop':
         case 'previous':
         case 'next':
             $this->mpd($cmd);
             break;
         case 'toggleRepeat':
             $status = $this->mpd('status');
             $this->mpd('repeat ' . (int) ($status['repeat'] xor 1));
             break;
         case 'toggleRandom':
             $status = $this->mpd('status');
             $this->mpd('random ' . (int) ($status['random'] xor 1));
             break;
         case 'toggleConsume':
             $status = $this->mpd('status');
             $this->mpd('consume ' . (int) ($status['consume'] xor 1));
             break;
         case 'playlistStatus':
             $this->playlistStatus();
             break;
         case 'addSelect':
             # TODO: general handling of position to add
             # TODO: general handling of playing immediately or simply appending to playlist
             $path = '';
             if (is_string($item) === TRUE) {
                 $path = $item;
             }
             if (is_numeric($item) === TRUE) {
                 $path = \Slimpd\Track::getInstanceByAttributes(array('id' => $item))->getRelativePath();
             }
             if (is_array($item) === TRUE) {
                 $path = join(DS, $item);
             }
             if (is_file(\Slim\Slim::getInstance()->config['mpd']['musicdir'] . $path) === TRUE) {
                 $this->mpd('addid "' . str_replace("\"", "\\\"", $path) . '" 0');
                 $this->mpd('play 0');
             } else {
                 // trailing slash on directories will not work - lets remove it
                 if (substr($path, -1) === DS) {
                     $path = substr($path, 0, -1);
                 }
                 $this->mpd('add "' . str_replace("\"", "\\\"", $path) . '"');
             }
             break;
         case 'playIndex':
             $this->mpd('play ' . $item);
             break;
         case 'deleteIndex':
             $this->mpd('delete ' . $item);
             break;
         case 'clearPlaylist':
             $this->mpd('clear');
             break;
         case 'clearPlaylistNotCurrent':
             $status = $this->mpd('status');
             $songId = isset($status['songid']) ? $status['songid'] : 0;
             if ($songId > 0) {
                 // move current song to first position
                 $this->mpd('moveid ' . $songId . ' 0');
                 $playlistLength = isset($status['playlistlength']) ? $status['playlistlength'] : 0;
                 if ($playlistLength > 1) {
                     $this->mpd('delete 1:' . $playlistLength);
                 }
             }
             break;
         case 'playSelect':
             //		playSelect();
         //		playSelect();
         case 'addSelect':
             //		addSelect();
         //		addSelect();
         case 'deleteIndexAjax':
             //	deleteIndexAjax();
         //	deleteIndexAjax();
         case 'deletePlayed':
             //		deletePlayed();
         //		deletePlayed();
         case 'volumeImageMap':
             //	volumeImageMap();
         //	volumeImageMap();
         case 'toggleMute':
             //		toggleMute();
         //		toggleMute();
         case 'loopGain':
             //			loopGain();
         //			loopGain();
         case 'playlistTrack':
             //	playlistTrack();
             die('sorry, not implemented yet');
             break;
         default:
             die('unsupported');
             break;
     }
 }
Beispiel #3
0
        foreach ($rows as $row) {
            $excerped = $cl->BuildExcerpts([$row['phrase']], 'slimpdautocomplete', $term);
            $filterType = $filterTypeMapping[$row['type']];
            $entry = ['label' => $excerped[0], 'url' => $filterType === 'track' ? '/searchall/page/1/sort/relevance/desc?q=' . $row['phrase'] : '/library/' . $filterType . '/' . $row['itemid'], 'type' => $filterType, 'typelabel' => $app->ll->str($filterType), 'itemid' => $row['itemid']];
            switch ($filterType) {
                case 'artist':
                case 'label':
                    $entry['img'] = '/skin/default/img/icon-' . $filterType . '.png';
                    break;
                case 'album':
                case 'track':
                    $entry['img'] = '/image-50/' . $filterType . '/' . $row['itemid'];
                    break;
            }
            $result[] = $entry;
        }
    }
    #echo "<pre>" . print_r($result,1); die();
    #echo "<pre>" . print_r($rows,1); die();
    echo json_encode($result);
    exit;
})->name('autocomplete');
$app->get('/deliver/:item+', function ($item) use($app, $config) {
    $path = join(DS, $item);
    if (is_numeric($path)) {
        $track = \Slimpd\Track::getInstanceByAttributes(array('id' => (int) $path));
        $path = $track === NULL ? '' : $track->getRelativePath();
    }
    deliver($app->config['mpd']['alternative_musicdir'] . $path, $app);
    $app->stop();
});