mirror of
https://github.com/Yetangitu/ampache
synced 2025-10-06 03:49:56 +02:00
UPNP fixes and optimization
1) optimization: _xxxChilds: slice whole items array BEFORE converting to output objects 2) fix with special chars in items title. Some players stops after receiving some special chars. Don't know which exactly char is wrong, replace all special chars to '-'
This commit is contained in:
parent
e75a38a007
commit
1569f8019d
3 changed files with 62 additions and 25 deletions
|
@ -442,9 +442,17 @@ class Upnp_Api
|
|||
return $meta;
|
||||
}
|
||||
|
||||
public static function _musicChilds($prmPath, $prmQuery)
|
||||
private static function _slice($items, $start, $count)
|
||||
{
|
||||
$maxCount = count($items);
|
||||
debug_event('upnp-api', 'slice: ' . $maxCount . " " . $start . " " . $count, '5');
|
||||
return array($maxCount, array_slice($items, $start, ($count == 0 ? $maxCount - $start : $count)));
|
||||
}
|
||||
|
||||
public static function _musicChilds($prmPath, $prmQuery, $start, $count)
|
||||
{
|
||||
$mediaItems = array();
|
||||
$maxCount = 0;
|
||||
$queryData = array();
|
||||
parse_str($prmQuery, $queryData);
|
||||
|
||||
|
@ -459,6 +467,7 @@ class Upnp_Api
|
|||
switch (count($pathreq)) {
|
||||
case 1: // Get artists list
|
||||
$artists = Catalog::get_artists();
|
||||
list($maxCount, $artists) = self::_slice($artists, $start, $count);
|
||||
foreach ($artists as $artist) {
|
||||
$artist->format();
|
||||
$mediaItems[] = self::_itemArtist($artist, $parent);
|
||||
|
@ -468,6 +477,7 @@ class Upnp_Api
|
|||
$artist = new Artist($pathreq[1]);
|
||||
if ($artist->id) {
|
||||
$album_ids = $artist->get_albums();
|
||||
list($maxCount, $album_ids) = self::_slice($album_ids, $start, $count);
|
||||
foreach ($album_ids as $album_id) {
|
||||
$album = new Album($album_id);
|
||||
$album->format();
|
||||
|
@ -482,6 +492,7 @@ class Upnp_Api
|
|||
switch (count($pathreq)) {
|
||||
case 1: // Get albums list
|
||||
$album_ids = Catalog::get_albums();
|
||||
list($maxCount, $album_ids) = self::_slice($album_ids, $start, $count);
|
||||
foreach ($album_ids as $album_id) {
|
||||
$album = new Album($album_id);
|
||||
$album->format();
|
||||
|
@ -492,6 +503,7 @@ class Upnp_Api
|
|||
$album = new Album($pathreq[1]);
|
||||
if ($album->id) {
|
||||
$song_ids = $album->get_songs();
|
||||
list($maxCount, $song_ids) = self::_slice($song_ids, $start, $count);
|
||||
foreach ($song_ids as $song_id) {
|
||||
$song = new Song($song_id);
|
||||
$song->format();
|
||||
|
@ -509,6 +521,7 @@ class Upnp_Api
|
|||
foreach ($catalogs as $catalog_id) {
|
||||
$catalog = Catalog::create_from_id($catalog_id);
|
||||
$songs = $catalog->get_songs();
|
||||
list($maxCount, $songs) = self::_slice($songs, $start, $count);
|
||||
foreach ($songs as $song) {
|
||||
$song->format();
|
||||
$mediaItems[] = self::_itemSong($song, $parent);
|
||||
|
@ -522,6 +535,7 @@ class Upnp_Api
|
|||
switch (count($pathreq)) {
|
||||
case 1: // Get playlists list
|
||||
$pl_ids = Playlist::get_playlists();
|
||||
list($maxCount, $pl_ids) = self::_slice($pl_ids, $start, $count);
|
||||
foreach ($pl_ids as $pl_id) {
|
||||
$playlist = new Playlist($pl_id);
|
||||
$playlist->format();
|
||||
|
@ -532,6 +546,7 @@ class Upnp_Api
|
|||
$playlist = new Playlist($pathreq[1]);
|
||||
if ($playlist->id) {
|
||||
$items = $playlist->get_items();
|
||||
list($maxCount, $items) = self::_slice($items, $start, $count);
|
||||
foreach ($items as $item) {
|
||||
if ($item['object_type'] == 'song') {
|
||||
$song = new Song($item['object_id']);
|
||||
|
@ -548,6 +563,7 @@ class Upnp_Api
|
|||
switch (count($pathreq)) {
|
||||
case 1: // Get playlists list
|
||||
$pl_ids = Search::get_searches();
|
||||
list($maxCount, $pl_ids) = self::_slice($pl_ids, $start, $count);
|
||||
foreach ($pl_ids as $pl_id) {
|
||||
$playlist = new Search($pl_id, 'song');
|
||||
$playlist->format();
|
||||
|
@ -558,6 +574,7 @@ class Upnp_Api
|
|||
$playlist = new Search($pathreq[1], 'song');
|
||||
if ($playlist->id) {
|
||||
$items = $playlist->get_items();
|
||||
list($maxCount, $items) = self::_slice($items, $start, $count);
|
||||
foreach ($items as $item) {
|
||||
if ($item['object_type'] == 'song') {
|
||||
$song = new Song($item['object_id']);
|
||||
|
@ -579,7 +596,9 @@ class Upnp_Api
|
|||
break;
|
||||
}
|
||||
|
||||
return $mediaItems;
|
||||
if ($maxCount == 0)
|
||||
$maxCount = count($mediaItems);
|
||||
return array($maxCount, $mediaItems);
|
||||
}
|
||||
|
||||
public static function _videoMetadata($prmPath, $prmQuery = '')
|
||||
|
@ -719,9 +738,10 @@ class Upnp_Api
|
|||
return $meta;
|
||||
}
|
||||
|
||||
public static function _videoChilds($prmPath, $prmQuery)
|
||||
public static function _videoChilds($prmPath, $prmQuery, $start, $count)
|
||||
{
|
||||
$mediaItems = array();
|
||||
$maxCount = 0;
|
||||
$queryData = array();
|
||||
parse_str($prmQuery, $queryData);
|
||||
|
||||
|
@ -736,6 +756,7 @@ class Upnp_Api
|
|||
switch (count($pathreq)) {
|
||||
case 1: // Get tvshow list
|
||||
$tvshows = Catalog::get_tvshows();
|
||||
list($maxCount, $tvshows) = self::_slice($tvshows, $start, $count);
|
||||
foreach ($tvshows as $tvshow) {
|
||||
$tvshow->format();
|
||||
$mediaItems[] = self::_itemTVShow($tvshow, $parent);
|
||||
|
@ -745,6 +766,7 @@ class Upnp_Api
|
|||
$tvshow = new TVShow($pathreq[1]);
|
||||
if ($tvshow->id) {
|
||||
$season_ids = $tvshow->get_seasons();
|
||||
list($maxCount, $season_ids) = self::_slice($season_ids, $start, $count);
|
||||
foreach ($season_ids as $season_id) {
|
||||
$season = new TVShow_Season($season_id);
|
||||
$season->format();
|
||||
|
@ -756,6 +778,7 @@ class Upnp_Api
|
|||
$season = new TVShow_Season($pathreq[2]);
|
||||
if ($season->id) {
|
||||
$episode_ids = $season->get_episodes();
|
||||
list($maxCount, $episode_ids) = self::_slice($episode_ids, $start, $count);
|
||||
foreach ($episode_ids as $episode_id) {
|
||||
$video = new Video($episode_id);
|
||||
$video->format();
|
||||
|
@ -770,6 +793,7 @@ class Upnp_Api
|
|||
switch (count($pathreq)) {
|
||||
case 1: // Get clips list
|
||||
$videos = Catalog::get_videos(null, 'clip');
|
||||
list($maxCount, $videos) = self::_slice($videos, $start, $count);
|
||||
foreach ($videos as $video) {
|
||||
$video->format();
|
||||
$mediaItems[] = self::_itemVideo($video, $parent);
|
||||
|
@ -782,6 +806,7 @@ class Upnp_Api
|
|||
switch (count($pathreq)) {
|
||||
case 1: // Get clips list
|
||||
$videos = Catalog::get_videos(null, 'movie');
|
||||
list($maxCount, $videos) = self::_slice($videos, $start, $count);
|
||||
foreach ($videos as $video) {
|
||||
$video->format();
|
||||
$mediaItems[] = self::_itemVideo($video, $parent);
|
||||
|
@ -794,6 +819,7 @@ class Upnp_Api
|
|||
switch (count($pathreq)) {
|
||||
case 1: // Get clips list
|
||||
$videos = Catalog::get_videos(null, 'personal_video');
|
||||
list($maxCount, $videos) = self::_slice($videos, $start, $count);
|
||||
foreach ($videos as $video) {
|
||||
$video->format();
|
||||
$mediaItems[] = self::_itemVideo($video, $parent);
|
||||
|
@ -810,7 +836,9 @@ class Upnp_Api
|
|||
break;
|
||||
}
|
||||
|
||||
return $mediaItems;
|
||||
if ($maxCount == 0)
|
||||
$maxCount = count($mediaItems);
|
||||
return array($maxCount, $mediaItems);
|
||||
}
|
||||
|
||||
public static function _callSearch($criteria)
|
||||
|
@ -819,6 +847,19 @@ class Upnp_Api
|
|||
return array();
|
||||
}
|
||||
|
||||
private static function _replaceSpecialSymbols($title)
|
||||
{
|
||||
debug_event('upnp_class', 'replace <<< ' . $title, 5);
|
||||
// replace non letter or digits
|
||||
$title = preg_replace('~[^\\pL\d\.\s\(\)]+~u', '-', $title);
|
||||
debug_event('upnp_class', 'replace >>> ' . $title, 5);
|
||||
|
||||
if ($title == "")
|
||||
$title = '(no title)';
|
||||
|
||||
return $title;
|
||||
}
|
||||
|
||||
private static function _itemArtist($artist, $parent)
|
||||
{
|
||||
return array(
|
||||
|
@ -826,7 +867,7 @@ class Upnp_Api
|
|||
'parentID' => $parent,
|
||||
'restricted' => '1',
|
||||
'childCount' => $artist->albums,
|
||||
'dc:title' => $artist->f_name,
|
||||
'dc:title' => self::_replaceSpecialSymbols($artist->f_name),
|
||||
'upnp:class' => 'object.container', // object.container.person.musicArtist
|
||||
);
|
||||
}
|
||||
|
@ -841,7 +882,7 @@ class Upnp_Api
|
|||
'parentID' => $parent,
|
||||
'restricted' => '1',
|
||||
'childCount' => $album->song_count,
|
||||
'dc:title' => $album->f_title,
|
||||
'dc:title' => self::_replaceSpecialSymbols($album->f_title),
|
||||
'upnp:class' => 'object.container', // object.container.album.musicAlbum
|
||||
'upnp:albumArtURI' => $art_url,
|
||||
);
|
||||
|
@ -854,7 +895,7 @@ class Upnp_Api
|
|||
'parentID' => $parent,
|
||||
'restricted' => '1',
|
||||
'childCount' => count($playlist->get_items()),
|
||||
'dc:title' => $playlist->f_name,
|
||||
'dc:title' => self::_replaceSpecialSymbols($playlist->f_name),
|
||||
'upnp:class' => 'object.container', // object.container.playlistContainer
|
||||
);
|
||||
}
|
||||
|
@ -866,7 +907,7 @@ class Upnp_Api
|
|||
'parentID' => $parent,
|
||||
'restricted' => '1',
|
||||
'childCount' => count($playlist->get_items()),
|
||||
'dc:title' => $playlist->f_name,
|
||||
'dc:title' => self::_replaceSpecialSymbols($playlist->f_name),
|
||||
'upnp:class' => 'object.container',
|
||||
);
|
||||
}
|
||||
|
@ -883,7 +924,7 @@ class Upnp_Api
|
|||
'id' => 'amp://music/songs/' . $song->id,
|
||||
'parentID' => $parent,
|
||||
'restricted' => '1',
|
||||
'dc:title' => $song->f_title,
|
||||
'dc:title' => self::_replaceSpecialSymbols($song->f_title),
|
||||
'upnp:class' => (isset($arrFileType['class'])) ? $arrFileType['class'] : 'object.item.unknownItem',
|
||||
'upnp:albumArtURI' => $art_url,
|
||||
'upnp:artist' => $song->f_artist,
|
||||
|
@ -910,7 +951,7 @@ class Upnp_Api
|
|||
'parentID' => $parent,
|
||||
'restricted' => '1',
|
||||
'childCount' => count($tvshow->get_seasons()),
|
||||
'dc:title' => $tvshow->f_name,
|
||||
'dc:title' => self::_replaceSpecialSymbols($tvshow->f_name),
|
||||
'upnp:class' => 'object.container',
|
||||
);
|
||||
}
|
||||
|
@ -922,7 +963,7 @@ class Upnp_Api
|
|||
'parentID' => $parent,
|
||||
'restricted' => '1',
|
||||
'childCount' => count($season->get_episodes()),
|
||||
'dc:title' => $season->f_name,
|
||||
'dc:title' => self::_replaceSpecialSymbols($season->f_name),
|
||||
'upnp:class' => 'object.container',
|
||||
);
|
||||
}
|
||||
|
@ -939,7 +980,7 @@ class Upnp_Api
|
|||
'id' => $parent . '/' . $video->id,
|
||||
'parentID' => $parent,
|
||||
'restricted' => '1',
|
||||
'dc:title' => $video->f_title,
|
||||
'dc:title' => self::_replaceSpecialSymbols($video->f_title),
|
||||
'upnp:class' => (isset($arrFileType['class'])) ? $arrFileType['class'] : 'object.item.unknownItem',
|
||||
'upnp:albumArtURI' => $art_url,
|
||||
'upnp:genre' => Tag::get_display($video->tags, false, 'video'),
|
||||
|
|
|
@ -26,6 +26,7 @@ $rootMediaItems[] = Upnp_Api::_videoMetadata('');
|
|||
}
|
||||
|
||||
$items = array();
|
||||
$totMatches = 0;
|
||||
$responseType = "u:Error";
|
||||
switch ($upnpRequest['action']) {
|
||||
case 'search':
|
||||
|
@ -34,7 +35,7 @@ $rootMediaItems[] = Upnp_Api::_videoMetadata('');
|
|||
break;
|
||||
case 'browse':
|
||||
$responseType = 'u:BrowseResponse';
|
||||
$items = array();
|
||||
|
||||
if ($upnpRequest['objectid'] == '0') {
|
||||
// Root items
|
||||
if ($upnpRequest['browseflag'] == 'BrowseMetadata') {
|
||||
|
@ -68,14 +69,14 @@ $rootMediaItems[] = Upnp_Api::_videoMetadata('');
|
|||
if ($upnpRequest['browseflag'] == 'BrowseMetadata') {
|
||||
$items = Upnp_Api::_musicMetadata($reqObjectURL['path'], $reqObjectURL['query']);
|
||||
} else {
|
||||
$items = Upnp_Api::_musicChilds($reqObjectURL['path'], $reqObjectURL['query']);
|
||||
list($totMatches, $items) = Upnp_Api::_musicChilds($reqObjectURL['path'], $reqObjectURL['query'], $upnpRequest['startingindex'], $upnpRequest['requestedcount']);
|
||||
}
|
||||
break;
|
||||
case 'video':
|
||||
if ($upnpRequest['browseflag'] == 'BrowseMetadata') {
|
||||
$items = Upnp_Api::_videoMetadata($reqObjectURL['path'], $reqObjectURL['query']);
|
||||
} else {
|
||||
$items = Upnp_Api::_videoChilds($reqObjectURL['path'], $reqObjectURL['query']);
|
||||
list($totMatches, $items) = Upnp_Api::_videoChilds($reqObjectURL['path'], $reqObjectURL['query'], $upnpRequest['startingindex'], $upnpRequest['requestedcount']);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -85,18 +86,13 @@ $rootMediaItems[] = Upnp_Api::_videoMetadata('');
|
|||
break;
|
||||
}
|
||||
|
||||
$totMatches = count($items);
|
||||
$totMatches = ($totMatches == 0) ? count($items) : $totMatches;
|
||||
if ($items == null || $totMatches == 0) {
|
||||
$domDIDL = Upnp_Api::createDIDL('');
|
||||
$numRet = 0;
|
||||
} else {
|
||||
if ($upnpRequest['requestedcount'] == 0) {
|
||||
$upnpRequest['requestedcount'] = $totMatches - $upnpRequest['startingindex'];
|
||||
}
|
||||
|
||||
$slicedItems = array_slice($items, $upnpRequest['startingindex'], $upnpRequest['requestedcount']);
|
||||
$domDIDL = Upnp_Api::createDIDL($slicedItems);
|
||||
$numRet = count($slicedItems);
|
||||
$domDIDL = Upnp_Api::createDIDL($items);
|
||||
$numRet = count($items);
|
||||
}
|
||||
|
||||
$xmlDIDL = $domDIDL->saveXML();
|
||||
|
|
|
@ -17,7 +17,7 @@ if (($_GET['btnSend']) || ($_GET['btnSendAuto'])) {
|
|||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<?php
|
||||
if ($_GET['btnSendAuto']) {
|
||||
echo '<meta http-equiv="refresh" content="10">';
|
||||
echo '<meta http-equiv="refresh" content="1">';
|
||||
}
|
||||
?>
|
||||
<title>Ampache UPnP</title>
|
||||
|
@ -41,7 +41,7 @@ body {
|
|||
<br />
|
||||
<br />
|
||||
<input type="submit" name="btnSend" id="id-btnSend" value="Send SSDP broadcast" />
|
||||
<input type="submit" name="btnSendAuto" id="id-btnSendAuto" value="Send SSDP broadcast every 10 sec" />
|
||||
<input type="submit" name="btnSendAuto" id="id-btnSendAuto" value="Send SSDP broadcast every second" />
|
||||
</form>
|
||||
<br />
|
||||
<?php
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue