mirror of
https://github.com/Yetangitu/ampache
synced 2025-10-06 03:49:56 +02:00
Working UPnP backing for browse and stream actions
This commit is contained in:
parent
d045a75e11
commit
e07d23d7c9
9 changed files with 200 additions and 87 deletions
45
bin/broadcast.inc
Normal file
45
bin/broadcast.inc
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
<?php
|
||||||
|
/* vim:set softtabstop=4 shiftwidth=4 expandtab: */
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* LICENSE: GNU General Public License, version 2 (GPLv2)
|
||||||
|
* Copyright 2001 - 2014 Ampache.org
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License v2
|
||||||
|
* as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
define('NO_SESSION','1');
|
||||||
|
define('CLI', 1);
|
||||||
|
|
||||||
|
$path = dirname(__FILE__);
|
||||||
|
$prefix = realpath($path . '/../');
|
||||||
|
require_once $prefix . '/lib/init.php';
|
||||||
|
|
||||||
|
ob_end_flush();
|
||||||
|
|
||||||
|
echo T_("Starting broadcasts...") . "\n";
|
||||||
|
|
||||||
|
if (AmpConfig::get('upnp_backend')) {
|
||||||
|
echo T_("UPnP broadcast... ");
|
||||||
|
Upnp_Api::sddpSend();
|
||||||
|
echo T_("Done.") . "\n";
|
||||||
|
} else {
|
||||||
|
echo T_("UPnP backend disabled. Broadcast skipped.") . "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
ob_end_flush();
|
||||||
|
echo "\n";
|
||||||
|
|
||||||
|
?>
|
|
@ -66,7 +66,7 @@ session_length = 3600
|
||||||
stream_length = 7200
|
stream_length = 7200
|
||||||
|
|
||||||
; This length defines how long a 'remember me' session and cookie will
|
; This length defines how long a 'remember me' session and cookie will
|
||||||
; last, the default is 7200, same as length. It is up to the administrator
|
; last, the default is 86400, same as length. It is up to the administrator
|
||||||
; of the box to increase this, for reference 86400 = 1 day
|
; of the box to increase this, for reference 86400 = 1 day
|
||||||
; 604800 = 1 week and 2419200 = 1 month
|
; 604800 = 1 week and 2419200 = 1 month
|
||||||
; DEFAULT: 86400
|
; DEFAULT: 86400
|
||||||
|
|
|
@ -314,8 +314,8 @@ class Artist extends database_object
|
||||||
$this->f_name = $name;
|
$this->f_name = $name;
|
||||||
$this->f_full_name = trim(trim($this->prefix) . ' ' . trim($this->name));
|
$this->f_full_name = trim(trim($this->prefix) . ' ' . trim($this->name));
|
||||||
|
|
||||||
// If this is a fake object, we're done here
|
// If this is a memory-only object, we're done here
|
||||||
if ($this->_fake) { return true; }
|
if (!$this->id) { return true; }
|
||||||
|
|
||||||
if ($this->catalog_id) {
|
if ($this->catalog_id) {
|
||||||
$this->f_link = AmpConfig::get('web_path') . '/artists.php?action=show&catalog=' . $this->catalog_id . '&artist=' . $this->id;
|
$this->f_link = AmpConfig::get('web_path') . '/artists.php?action=show&catalog=' . $this->catalog_id . '&artist=' . $this->id;
|
||||||
|
|
|
@ -61,6 +61,7 @@ class Song extends database_object implements media
|
||||||
public $f_album_artist_full;
|
public $f_album_artist_full;
|
||||||
public $f_album_full;
|
public $f_album_full;
|
||||||
public $f_time;
|
public $f_time;
|
||||||
|
public $f_time_h;
|
||||||
public $f_track;
|
public $f_track;
|
||||||
public $f_bitrate;
|
public $f_bitrate;
|
||||||
public $link;
|
public $link;
|
||||||
|
@ -935,6 +936,9 @@ class Song extends database_object implements media
|
||||||
$min = floor($this->time/60);
|
$min = floor($this->time/60);
|
||||||
$sec = sprintf("%02d", ($this->time%60));
|
$sec = sprintf("%02d", ($this->time%60));
|
||||||
$this->f_time = $min . ":" . $sec;
|
$this->f_time = $min . ":" . $sec;
|
||||||
|
$hour = sprintf("%02d", floor($min/60));
|
||||||
|
$min_h = sprintf("%02d", ($min%60));
|
||||||
|
$this->f_time_h = $hour . ":" . $min_h . ":" . $sec;
|
||||||
|
|
||||||
// Format the track (there isn't really anything to do here)
|
// Format the track (there isn't really anything to do here)
|
||||||
$this->f_track = $this->track;
|
$this->f_track = $this->track;
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*
|
*
|
||||||
|
* This class is a derived work from UMSP project (http://wiki.wdlxtv.com/UMSP).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -156,8 +157,6 @@ class Upnp_Api
|
||||||
|
|
||||||
public static function createDIDL($prmItems)
|
public static function createDIDL($prmItems)
|
||||||
{
|
{
|
||||||
# TODO: put object.container in container tags where they belong. But as long as the WDTVL doesn't mind... ;)
|
|
||||||
# $prmItems is an array of arrays
|
|
||||||
$xmlDoc = new DOMDocument('1.0', 'utf-8');
|
$xmlDoc = new DOMDocument('1.0', 'utf-8');
|
||||||
$xmlDoc->formatOutput = true;
|
$xmlDoc->formatOutput = true;
|
||||||
|
|
||||||
|
@ -168,9 +167,9 @@ class Upnp_Api
|
||||||
$xmlDoc->appendChild($ndDIDL);
|
$xmlDoc->appendChild($ndDIDL);
|
||||||
|
|
||||||
# Return empty DIDL if no items present:
|
# Return empty DIDL if no items present:
|
||||||
if ( (!isset($prmItems)) || ($prmItems == '') ) {
|
if ( (!isset($prmItems)) || (!is_array($prmItems)) ) {
|
||||||
return $xmlDoc;
|
return $xmlDoc;
|
||||||
} # end if
|
}
|
||||||
|
|
||||||
# Add each item in $prmItems array to $ndDIDL:
|
# Add each item in $prmItems array to $ndDIDL:
|
||||||
foreach ($prmItems as $item) {
|
foreach ($prmItems as $item) {
|
||||||
|
@ -226,21 +225,29 @@ class Upnp_Api
|
||||||
$ndRes->setAttribute('colorDepth', $value);
|
$ndRes->setAttribute('colorDepth', $value);
|
||||||
$useRes = true;
|
$useRes = true;
|
||||||
break;
|
break;
|
||||||
|
case 'sampleFrequency':
|
||||||
|
$ndRes->setAttribute('sampleFrequency', $value);
|
||||||
|
$useRes = true;
|
||||||
|
break;
|
||||||
|
case 'nrAudioChannels':
|
||||||
|
$ndRes->setAttribute('nrAudioChannels', $value);
|
||||||
|
$useRes = true;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
$ndTag = $xmlDoc->createElement($key);
|
$ndTag = $xmlDoc->createElement($key);
|
||||||
$ndItem->appendChild($ndTag);
|
$ndItem->appendChild($ndTag);
|
||||||
# check if string is already utf-8 encoded
|
# check if string is already utf-8 encoded
|
||||||
$ndTag_text = $xmlDoc->createTextNode((mb_detect_encoding($value,'auto')=='UTF-8')?$value:utf8_encode($value));
|
$ndTag_text = $xmlDoc->createTextNode((mb_detect_encoding($value,'auto')=='UTF-8')?$value:utf8_encode($value));
|
||||||
$ndTag->appendChild($ndTag_text);
|
$ndTag->appendChild($ndTag_text);
|
||||||
} # end switch
|
}
|
||||||
if ($useRes) {
|
if ($useRes) {
|
||||||
$ndItem->appendChild($ndRes);
|
$ndItem->appendChild($ndRes);
|
||||||
}
|
}
|
||||||
} # end foreach
|
}
|
||||||
$ndDIDL->appendChild($ndItem);
|
$ndDIDL->appendChild($ndItem);
|
||||||
} # end foreach
|
}
|
||||||
return $xmlDoc;
|
return $xmlDoc;
|
||||||
} # end function
|
}
|
||||||
|
|
||||||
|
|
||||||
public static function createSOAPEnvelope($prmDIDL, $prmNumRet, $prmTotMatches, $prmResponseType = 'u:BrowseResponse', $prmUpdateID = '0')
|
public static function createSOAPEnvelope($prmDIDL, $prmNumRet, $prmTotMatches, $prmResponseType = 'u:BrowseResponse', $prmUpdateID = '0')
|
||||||
|
@ -259,6 +266,7 @@ class Upnp_Api
|
||||||
$doc = new DOMDocument('1.0', 'utf-8');
|
$doc = new DOMDocument('1.0', 'utf-8');
|
||||||
$doc->formatOutput = true;
|
$doc->formatOutput = true;
|
||||||
$ndEnvelope = $doc->createElementNS('http://schemas.xmlsoap.org/soap/envelope/', 's:Envelope');
|
$ndEnvelope = $doc->createElementNS('http://schemas.xmlsoap.org/soap/envelope/', 's:Envelope');
|
||||||
|
$ndEnvelope->setAttribute("s:encodingStyle", "http://schemas.xmlsoap.org/soap/encoding/");
|
||||||
$doc->appendChild($ndEnvelope);
|
$doc->appendChild($ndEnvelope);
|
||||||
$ndBody = $doc->createElement('s:Body');
|
$ndBody = $doc->createElement('s:Body');
|
||||||
$ndEnvelope->appendChild($ndBody);
|
$ndEnvelope->appendChild($ndBody);
|
||||||
|
@ -294,6 +302,7 @@ class Upnp_Api
|
||||||
$meta = array(
|
$meta = array(
|
||||||
'id' => $root . '/artists',
|
'id' => $root . '/artists',
|
||||||
'parentID' => $root,
|
'parentID' => $root,
|
||||||
|
'restricted' => '1',
|
||||||
'childCount' => $counts['artists'],
|
'childCount' => $counts['artists'],
|
||||||
'dc:title' => T_('Artists'),
|
'dc:title' => T_('Artists'),
|
||||||
'upnp:class' => 'object.container',
|
'upnp:class' => 'object.container',
|
||||||
|
@ -317,6 +326,7 @@ class Upnp_Api
|
||||||
$meta = array(
|
$meta = array(
|
||||||
'id' => $root . '/albums',
|
'id' => $root . '/albums',
|
||||||
'parentID' => $root,
|
'parentID' => $root,
|
||||||
|
'restricted' => '1',
|
||||||
'childCount' => $counts['albums'],
|
'childCount' => $counts['albums'],
|
||||||
'dc:title' => T_('Albums'),
|
'dc:title' => T_('Albums'),
|
||||||
'upnp:class' => 'object.container',
|
'upnp:class' => 'object.container',
|
||||||
|
@ -340,6 +350,7 @@ class Upnp_Api
|
||||||
$meta = array(
|
$meta = array(
|
||||||
'id' => $root . '/songs',
|
'id' => $root . '/songs',
|
||||||
'parentID' => $root,
|
'parentID' => $root,
|
||||||
|
'restricted' => '1',
|
||||||
'childCount' => $counts['songs'],
|
'childCount' => $counts['songs'],
|
||||||
'dc:title' => T_('Songs'),
|
'dc:title' => T_('Songs'),
|
||||||
'upnp:class' => 'object.container',
|
'upnp:class' => 'object.container',
|
||||||
|
@ -363,6 +374,7 @@ class Upnp_Api
|
||||||
$meta = array(
|
$meta = array(
|
||||||
'id' => $root . '/playlists',
|
'id' => $root . '/playlists',
|
||||||
'parentID' => $root,
|
'parentID' => $root,
|
||||||
|
'restricted' => '1',
|
||||||
'childCount' => $counts['playlists'],
|
'childCount' => $counts['playlists'],
|
||||||
'dc:title' => T_('Playlists'),
|
'dc:title' => T_('Playlists'),
|
||||||
'upnp:class' => 'object.container',
|
'upnp:class' => 'object.container',
|
||||||
|
@ -386,6 +398,7 @@ class Upnp_Api
|
||||||
$meta = array(
|
$meta = array(
|
||||||
'id' => $root . '/smartplaylists',
|
'id' => $root . '/smartplaylists',
|
||||||
'parentID' => $root,
|
'parentID' => $root,
|
||||||
|
'restricted' => '1',
|
||||||
'childCount' => $counts['smartplaylists'],
|
'childCount' => $counts['smartplaylists'],
|
||||||
'dc:title' => T_('Smart Playlists'),
|
'dc:title' => T_('Smart Playlists'),
|
||||||
'upnp:class' => 'object.container',
|
'upnp:class' => 'object.container',
|
||||||
|
@ -406,6 +419,7 @@ class Upnp_Api
|
||||||
$meta = array(
|
$meta = array(
|
||||||
'id' => $root,
|
'id' => $root,
|
||||||
'parentID' => '0',
|
'parentID' => '0',
|
||||||
|
'restricted' => '1',
|
||||||
'childCount' => '5',
|
'childCount' => '5',
|
||||||
'dc:title' => T_('Music'),
|
'dc:title' => T_('Music'),
|
||||||
'upnp:class' => 'object.container',
|
'upnp:class' => 'object.container',
|
||||||
|
@ -569,9 +583,10 @@ class Upnp_Api
|
||||||
return array(
|
return array(
|
||||||
'id' => 'amp://music/artists/' . $artist->id,
|
'id' => 'amp://music/artists/' . $artist->id,
|
||||||
'parentID' => $parent,
|
'parentID' => $parent,
|
||||||
|
'restricted' => '1',
|
||||||
'childCount' => $artist->albums,
|
'childCount' => $artist->albums,
|
||||||
'dc:title' => $artist->f_name,
|
'dc:title' => $artist->f_name,
|
||||||
'upnp:class' => 'object.container',
|
'upnp:class' => 'object.container', // object.container.person.musicArtist
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -583,10 +598,11 @@ class Upnp_Api
|
||||||
return array(
|
return array(
|
||||||
'id' => 'amp://music/albums/' . $album->id,
|
'id' => 'amp://music/albums/' . $album->id,
|
||||||
'parentID' => $parent,
|
'parentID' => $parent,
|
||||||
|
'restricted' => '1',
|
||||||
'childCount' => $album->song_count,
|
'childCount' => $album->song_count,
|
||||||
'dc:title' => $album->f_title,
|
'dc:title' => $album->f_title,
|
||||||
'upnp:class' => 'object.container',
|
'upnp:class' => 'object.container', // object.container.album.musicAlbum
|
||||||
'upnp:album_art'=> $art_url,
|
'upnp:albumArtURI' => $art_url,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -595,9 +611,10 @@ class Upnp_Api
|
||||||
return array(
|
return array(
|
||||||
'id' => 'amp://music/playlists/' . $playlist->id,
|
'id' => 'amp://music/playlists/' . $playlist->id,
|
||||||
'parentID' => $parent,
|
'parentID' => $parent,
|
||||||
|
'restricted' => '1',
|
||||||
'childCount' => count($playlist->get_items()),
|
'childCount' => count($playlist->get_items()),
|
||||||
'dc:title' => $playlist->f_name,
|
'dc:title' => $playlist->f_name,
|
||||||
'upnp:class' => 'object.container',
|
'upnp:class' => 'object.container', // object.container.playlistContainer
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -606,6 +623,7 @@ class Upnp_Api
|
||||||
return array(
|
return array(
|
||||||
'id' => 'amp://music/smartplaylists/' . $playlist->id,
|
'id' => 'amp://music/smartplaylists/' . $playlist->id,
|
||||||
'parentID' => $parent,
|
'parentID' => $parent,
|
||||||
|
'restricted' => '1',
|
||||||
'childCount' => count($playlist->get_items()),
|
'childCount' => count($playlist->get_items()),
|
||||||
'dc:title' => $playlist->f_name,
|
'dc:title' => $playlist->f_name,
|
||||||
'upnp:class' => 'object.container',
|
'upnp:class' => 'object.container',
|
||||||
|
@ -623,13 +641,24 @@ class Upnp_Api
|
||||||
return array(
|
return array(
|
||||||
'id' => 'amp://music/songs/' . $song->id,
|
'id' => 'amp://music/songs/' . $song->id,
|
||||||
'parentID' => $parent,
|
'parentID' => $parent,
|
||||||
|
'restricted' => '1',
|
||||||
'dc:title' => $song->f_title,
|
'dc:title' => $song->f_title,
|
||||||
'upnp:class' => (isset($arrFileType['class'])) ? $arrFileType['class'] : 'object.item.unknownItem',
|
'upnp:class' => (isset($arrFileType['class'])) ? $arrFileType['class'] : 'object.item.unknownItem',
|
||||||
'upnp:album_art'=> $art_url,
|
'upnp:albumArtURI' => $art_url,
|
||||||
'dc:date' => date("c", $song->addition_time),
|
'upnp:artist' => $song->f_artist,
|
||||||
|
'upnp:album' => $song->f_album,
|
||||||
|
'upnp:genre' => Tag::get_display($song->tags, false, 'song'),
|
||||||
|
//'dc:date' => date("c", $song->addition_time),
|
||||||
|
'upnp:originalTrackNumber' => $song->track,
|
||||||
|
|
||||||
'res' => Song::play_url($song->id),
|
'res' => Song::play_url($song->id),
|
||||||
'size' => $song->size,
|
|
||||||
'protocolInfo' => $arrFileType['mime'],
|
'protocolInfo' => $arrFileType['mime'],
|
||||||
|
'size' => $song->size,
|
||||||
|
'duration' => $song->f_time_h . '.0',
|
||||||
|
'bitrate' => $song->bitrate,
|
||||||
|
'sampleFrequency' => $song->rate,
|
||||||
|
//'nrAudioChannels' => '1',
|
||||||
|
'description' => $song->comment,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -638,219 +667,219 @@ class Upnp_Api
|
||||||
return array(
|
return array(
|
||||||
'wav' => array(
|
'wav' => array(
|
||||||
'class' => 'object.item.audioItem',
|
'class' => 'object.item.audioItem',
|
||||||
'mime' => 'file-get:*:audio/x-wav:*',
|
'mime' => 'http-get:*:audio/x-wav:*',
|
||||||
),
|
),
|
||||||
'mpa' => array(
|
'mpa' => array(
|
||||||
'class' => 'object.item.audioItem',
|
'class' => 'object.item.audioItem',
|
||||||
'mime' => 'file-get:*:audio/mpeg:*',
|
'mime' => 'http-get:*:audio/mpeg:*',
|
||||||
),
|
),
|
||||||
'.mp1' => array(
|
'.mp1' => array(
|
||||||
'class' => 'object.item.audioItem',
|
'class' => 'object.item.audioItem',
|
||||||
'mime' => 'file-get:*:audio/mpeg:*',
|
'mime' => 'http-get:*:audio/mpeg:*',
|
||||||
),
|
),
|
||||||
'mp3' => array(
|
'mp3' => array(
|
||||||
'class' => 'object.item.audioItem',
|
'class' => 'object.item.audioItem.musicTrack',
|
||||||
'mime' => 'file-get:*:audio/mpeg:*',
|
'mime' => 'http-get:*:audio/mpeg:*',
|
||||||
),
|
),
|
||||||
'aiff' => array(
|
'aiff' => array(
|
||||||
'class' => 'object.item.audioItem',
|
'class' => 'object.item.audioItem',
|
||||||
'mime' => 'file-get:*:audio/x-aiff:*',
|
'mime' => 'http-get:*:audio/x-aiff:*',
|
||||||
),
|
),
|
||||||
'aif' => array(
|
'aif' => array(
|
||||||
'class' => 'object.item.audioItem',
|
'class' => 'object.item.audioItem',
|
||||||
'mime' => 'file-get:*:audio/x-aiff:*',
|
'mime' => 'http-get:*:audio/x-aiff:*',
|
||||||
),
|
),
|
||||||
'wma' => array(
|
'wma' => array(
|
||||||
'class' => 'object.item.audioItem',
|
'class' => 'object.item.audioItem',
|
||||||
'mime' => 'file-get:*:audio/x-ms-wma:*',
|
'mime' => 'http-get:*:audio/x-ms-wma:*',
|
||||||
),
|
),
|
||||||
'lpcm' => array(
|
'lpcm' => array(
|
||||||
'class' => 'object.item.audioItem',
|
'class' => 'object.item.audioItem',
|
||||||
'mime' => 'file-get:*:audio/lpcm:*',
|
'mime' => 'http-get:*:audio/lpcm:*',
|
||||||
),
|
),
|
||||||
'aac' => array(
|
'aac' => array(
|
||||||
'class' => 'object.item.audioItem',
|
'class' => 'object.item.audioItem',
|
||||||
'mime' => 'file-get:*:audio/x-aac:*',
|
'mime' => 'http-get:*:audio/x-aac:*',
|
||||||
),
|
),
|
||||||
'm4a' => array(
|
'm4a' => array(
|
||||||
'class' => 'object.item.audioItem',
|
'class' => 'object.item.audioItem',
|
||||||
'mime' => 'file-get:*:audio/x-m4a:*',
|
'mime' => 'http-get:*:audio/x-m4a:*',
|
||||||
),
|
),
|
||||||
'ac3' => array(
|
'ac3' => array(
|
||||||
'class' => 'object.item.audioItem',
|
'class' => 'object.item.audioItem',
|
||||||
'mime' => 'file-get:*:audio/x-ac3:*',
|
'mime' => 'http-get:*:audio/x-ac3:*',
|
||||||
),
|
),
|
||||||
'pcm' => array(
|
'pcm' => array(
|
||||||
'class' => 'object.item.audioItem',
|
'class' => 'object.item.audioItem',
|
||||||
'mime' => 'file-get:*:audio/lpcm:*',
|
'mime' => 'http-get:*:audio/lpcm:*',
|
||||||
),
|
),
|
||||||
'flac' => array(
|
'flac' => array(
|
||||||
'class' => 'object.item.audioItem',
|
'class' => 'object.item.audioItem',
|
||||||
'mime' => 'file-get:*:audio/flac:*',
|
'mime' => 'http-get:*:audio/flac:*',
|
||||||
),
|
),
|
||||||
'ogg' => array(
|
'ogg' => array(
|
||||||
'class' => 'object.item.audioItem',
|
'class' => 'object.item.audioItem',
|
||||||
'mime' => 'file-get:*:application/ogg:*',
|
'mime' => 'http-get:*:application/ogg:*',
|
||||||
),
|
),
|
||||||
'mka' => array(
|
'mka' => array(
|
||||||
'class' => 'object.item.audioItem',
|
'class' => 'object.item.audioItem',
|
||||||
'mime' => 'file-get:*:audio/x-matroska:*',
|
'mime' => 'http-get:*:audio/x-matroska:*',
|
||||||
),
|
),
|
||||||
'mp4a' => array(
|
'mp4a' => array(
|
||||||
'class' => 'object.item.audioItem',
|
'class' => 'object.item.audioItem',
|
||||||
'mime' => 'file-get:*:audio/x-m4a:*',
|
'mime' => 'http-get:*:audio/x-m4a:*',
|
||||||
),
|
),
|
||||||
'mp2' => array(
|
'mp2' => array(
|
||||||
'class' => 'object.item.audioItem',
|
'class' => 'object.item.audioItem',
|
||||||
'mime' => 'file-get:*:audio/mpeg:*',
|
'mime' => 'http-get:*:audio/mpeg:*',
|
||||||
),
|
),
|
||||||
'gif' => array(
|
'gif' => array(
|
||||||
'class' => 'object.item.imageItem',
|
'class' => 'object.item.imageItem',
|
||||||
'mime' => 'file-get:*:image/gif:*',
|
'mime' => 'http-get:*:image/gif:*',
|
||||||
),
|
),
|
||||||
'jpg' => array(
|
'jpg' => array(
|
||||||
'class' => 'object.item.imageItem',
|
'class' => 'object.item.imageItem',
|
||||||
'mime' => 'file-get:*:image/jpeg:*',
|
'mime' => 'http-get:*:image/jpeg:*',
|
||||||
),
|
),
|
||||||
'jpe' => array(
|
'jpe' => array(
|
||||||
'class' => 'object.item.imageItem',
|
'class' => 'object.item.imageItem',
|
||||||
'mime' => 'file-get:*:image/jpeg:*',
|
'mime' => 'http-get:*:image/jpeg:*',
|
||||||
),
|
),
|
||||||
'png' => array(
|
'png' => array(
|
||||||
'class' => 'object.item.imageItem',
|
'class' => 'object.item.imageItem',
|
||||||
'mime' => 'file-get:*:image/png:*',
|
'mime' => 'http-get:*:image/png:*',
|
||||||
),
|
),
|
||||||
'tiff' => array(
|
'tiff' => array(
|
||||||
'class' => 'object.item.imageItem',
|
'class' => 'object.item.imageItem',
|
||||||
'mime' => 'file-get:*:image/tiff:*',
|
'mime' => 'http-get:*:image/tiff:*',
|
||||||
),
|
),
|
||||||
'tif' => array(
|
'tif' => array(
|
||||||
'class' => 'object.item.imageItem',
|
'class' => 'object.item.imageItem',
|
||||||
'mime' => 'file-get:*:image/tiff:*',
|
'mime' => 'http-get:*:image/tiff:*',
|
||||||
),
|
),
|
||||||
'jpeg' => array(
|
'jpeg' => array(
|
||||||
'class' => 'object.item.imageItem',
|
'class' => 'object.item.imageItem',
|
||||||
'mime' => 'file-get:*:image/jpeg:*',
|
'mime' => 'http-get:*:image/jpeg:*',
|
||||||
),
|
),
|
||||||
'bmp' => array(
|
'bmp' => array(
|
||||||
'class' => 'object.item.imageItem',
|
'class' => 'object.item.imageItem',
|
||||||
'mime' => 'file-get:*:image/bmp:*',
|
'mime' => 'http-get:*:image/bmp:*',
|
||||||
),
|
),
|
||||||
'asf' => array(
|
'asf' => array(
|
||||||
'class' => 'object.item.videoItem',
|
'class' => 'object.item.videoItem',
|
||||||
'mime' => 'file-get:*:video/x-ms-asf:*',
|
'mime' => 'http-get:*:video/x-ms-asf:*',
|
||||||
),
|
),
|
||||||
'wmv' => array(
|
'wmv' => array(
|
||||||
'class' => 'object.item.videoItem',
|
'class' => 'object.item.videoItem',
|
||||||
'mime' => 'file-get:*:video/x-ms-wmv:*',
|
'mime' => 'http-get:*:video/x-ms-wmv:*',
|
||||||
),
|
),
|
||||||
'mpeg2' => array(
|
'mpeg2' => array(
|
||||||
'class' => 'object.item.videoItem',
|
'class' => 'object.item.videoItem',
|
||||||
'mime' => 'file-get:*:video/mpeg2:*',
|
'mime' => 'http-get:*:video/mpeg2:*',
|
||||||
),
|
),
|
||||||
'avi' => array(
|
'avi' => array(
|
||||||
'class' => 'object.item.videoItem',
|
'class' => 'object.item.videoItem',
|
||||||
'mime' => 'file-get:*:video/x-msvideo:*',
|
'mime' => 'http-get:*:video/x-msvideo:*',
|
||||||
),
|
),
|
||||||
'divx' => array(
|
'divx' => array(
|
||||||
'class' => 'object.item.videoItem',
|
'class' => 'object.item.videoItem',
|
||||||
'mime' => 'file-get:*:video/x-msvideo:*',
|
'mime' => 'http-get:*:video/x-msvideo:*',
|
||||||
),
|
),
|
||||||
'mpg' => array(
|
'mpg' => array(
|
||||||
'class' => 'object.item.videoItem',
|
'class' => 'object.item.videoItem',
|
||||||
'mime' => 'file-get:*:video/mpeg:*',
|
'mime' => 'http-get:*:video/mpeg:*',
|
||||||
),
|
),
|
||||||
'm1v' => array(
|
'm1v' => array(
|
||||||
'class' => 'object.item.videoItem',
|
'class' => 'object.item.videoItem',
|
||||||
'mime' => 'file-get:*:video/mpeg:*',
|
'mime' => 'http-get:*:video/mpeg:*',
|
||||||
),
|
),
|
||||||
'm2v' => array(
|
'm2v' => array(
|
||||||
'class' => 'object.item.videoItem',
|
'class' => 'object.item.videoItem',
|
||||||
'mime' => 'file-get:*:video/mpeg:*',
|
'mime' => 'http-get:*:video/mpeg:*',
|
||||||
),
|
),
|
||||||
'mp4' => array(
|
'mp4' => array(
|
||||||
'class' => 'object.item.videoItem',
|
'class' => 'object.item.videoItem',
|
||||||
'mime' => 'file-get:*:video/mp4:*',
|
'mime' => 'http-get:*:video/mp4:*',
|
||||||
),
|
),
|
||||||
'mov' => array(
|
'mov' => array(
|
||||||
'class' => 'object.item.videoItem',
|
'class' => 'object.item.videoItem',
|
||||||
'mime' => 'file-get:*:video/quicktime:*',
|
'mime' => 'http-get:*:video/quicktime:*',
|
||||||
),
|
),
|
||||||
'vob' => array(
|
'vob' => array(
|
||||||
'class' => 'object.item.videoItem',
|
'class' => 'object.item.videoItem',
|
||||||
'mime' => 'file-get:*:video/dvd:*',
|
'mime' => 'http-get:*:video/dvd:*',
|
||||||
),
|
),
|
||||||
'dvr-ms' => array(
|
'dvr-ms' => array(
|
||||||
'class' => 'object.item.videoItem',
|
'class' => 'object.item.videoItem',
|
||||||
'mime' => 'file-get:*:video/x-ms-dvr:*',
|
'mime' => 'http-get:*:video/x-ms-dvr:*',
|
||||||
),
|
),
|
||||||
'dat' => array(
|
'dat' => array(
|
||||||
'class' => 'object.item.videoItem',
|
'class' => 'object.item.videoItem',
|
||||||
'mime' => 'file-get:*:video/mpeg:*',
|
'mime' => 'http-get:*:video/mpeg:*',
|
||||||
),
|
),
|
||||||
'mpeg' => array(
|
'mpeg' => array(
|
||||||
'class' => 'object.item.videoItem',
|
'class' => 'object.item.videoItem',
|
||||||
'mime' => 'file-get:*:video/mpeg:*',
|
'mime' => 'http-get:*:video/mpeg:*',
|
||||||
),
|
),
|
||||||
'm1s' => array(
|
'm1s' => array(
|
||||||
'class' => 'object.item.videoItem',
|
'class' => 'object.item.videoItem',
|
||||||
'mime' => 'file-get:*:video/mpeg:*',
|
'mime' => 'http-get:*:video/mpeg:*',
|
||||||
),
|
),
|
||||||
'm2p' => array(
|
'm2p' => array(
|
||||||
'class' => 'object.item.videoItem',
|
'class' => 'object.item.videoItem',
|
||||||
'mime' => 'file-get:*:video/mpeg2:*',
|
'mime' => 'http-get:*:video/mpeg2:*',
|
||||||
),
|
),
|
||||||
'm2t' => array(
|
'm2t' => array(
|
||||||
'class' => 'object.item.videoItem',
|
'class' => 'object.item.videoItem',
|
||||||
'mime' => 'file-get:*:video/mpeg2ts:*',
|
'mime' => 'http-get:*:video/mpeg2ts:*',
|
||||||
),
|
),
|
||||||
'm2ts' => array(
|
'm2ts' => array(
|
||||||
'class' => 'object.item.videoItem',
|
'class' => 'object.item.videoItem',
|
||||||
'mime' => 'file-get:*:video/mpeg2ts:*',
|
'mime' => 'http-get:*:video/mpeg2ts:*',
|
||||||
),
|
),
|
||||||
'mts' => array(
|
'mts' => array(
|
||||||
'class' => 'object.item.videoItem',
|
'class' => 'object.item.videoItem',
|
||||||
'mime' => 'file-get:*:video/mpeg2ts:*',
|
'mime' => 'http-get:*:video/mpeg2ts:*',
|
||||||
),
|
),
|
||||||
'ts' => array(
|
'ts' => array(
|
||||||
'class' => 'object.item.videoItem',
|
'class' => 'object.item.videoItem',
|
||||||
'mime' => 'file-get:*:video/mpeg2ts:*',
|
'mime' => 'http-get:*:video/mpeg2ts:*',
|
||||||
),
|
),
|
||||||
'tp' => array(
|
'tp' => array(
|
||||||
'class' => 'object.item.videoItem',
|
'class' => 'object.item.videoItem',
|
||||||
'mime' => 'file-get:*:video/mpeg2ts:*',
|
'mime' => 'http-get:*:video/mpeg2ts:*',
|
||||||
),
|
),
|
||||||
'trp' => array(
|
'trp' => array(
|
||||||
'class' => 'object.item.videoItem',
|
'class' => 'object.item.videoItem',
|
||||||
'mime' => 'file-get:*:video/mpeg2ts:*',
|
'mime' => 'http-get:*:video/mpeg2ts:*',
|
||||||
),
|
),
|
||||||
'm4t' => array(
|
'm4t' => array(
|
||||||
'class' => 'object.item.videoItem',
|
'class' => 'object.item.videoItem',
|
||||||
'mime' => 'file-get:*:video/mpeg2ts:*',
|
'mime' => 'http-get:*:video/mpeg2ts:*',
|
||||||
),
|
),
|
||||||
'm4v' => array(
|
'm4v' => array(
|
||||||
'class' => 'object.item.videoItem',
|
'class' => 'object.item.videoItem',
|
||||||
'mime' => 'file-get:*:video/MP4V-ES:*',
|
'mime' => 'http-get:*:video/MP4V-ES:*',
|
||||||
),
|
),
|
||||||
'vbs' => array(
|
'vbs' => array(
|
||||||
'class' => 'object.item.videoItem',
|
'class' => 'object.item.videoItem',
|
||||||
'mime' => 'file-get:*:video/mpeg2:*',
|
'mime' => 'http-get:*:video/mpeg2:*',
|
||||||
),
|
),
|
||||||
'mod' => array(
|
'mod' => array(
|
||||||
'class' => 'object.item.videoItem',
|
'class' => 'object.item.videoItem',
|
||||||
'mime' => 'file-get:*:video/mpeg2:*',
|
'mime' => 'http-get:*:video/mpeg2:*',
|
||||||
),
|
),
|
||||||
'mkv' => array(
|
'mkv' => array(
|
||||||
'class' => 'object.item.videoItem',
|
'class' => 'object.item.videoItem',
|
||||||
'mime' => 'file-get:*:video/x-matroska:*',
|
'mime' => 'http-get:*:video/x-matroska:*',
|
||||||
),
|
),
|
||||||
'3g2' => array(
|
'3g2' => array(
|
||||||
'class' => 'object.item.videoItem',
|
'class' => 'object.item.videoItem',
|
||||||
'mime' => 'file-get:*:video/mp4:*',
|
'mime' => 'http-get:*:video/mp4:*',
|
||||||
),
|
),
|
||||||
'3gp' => array(
|
'3gp' => array(
|
||||||
'class' => 'object.item.videoItem',
|
'class' => 'object.item.videoItem',
|
||||||
'mime' => 'file-get:*:video/mp4:*',
|
'mime' => 'http-get:*:video/mp4:*',
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
RewriteEngine On
|
RewriteEngine On
|
||||||
RewriteCond %{REQUEST_FILENAME} !-d
|
RewriteCond %{REQUEST_FILENAME} !-d
|
||||||
RewriteCond %{REQUEST_FILENAME} !-s
|
RewriteCond %{REQUEST_FILENAME} !-s
|
||||||
RewriteRule ^art/([^/]+)/([0-9]+)/thumb([0-9]*)\.([a-z]+)$ /image.php?id=$2&sid=$1 [L]
|
RewriteRule ^art/([^/]+)/([0-9]+)/thumb([0-9]*)\.([a-z]+)$ /image.php?id=$2&auth=$1 [L]
|
||||||
RewriteRule ^([^/]+)/([^/]+)(/.*)?$ /play/$3?$1=$2 [N,QSA]
|
RewriteRule ^([^/]+)/([^/]+)(/.*)?$ /play/$3?$1=$2 [N,QSA]
|
||||||
RewriteRule ^(/[^/]+|[^/]+/|/?)$ /play/index.php [L,QSA]
|
RewriteRule ^(/[^/]+|[^/]+/|/?)$ /play/index.php [L,QSA]
|
||||||
</IfModule>
|
</IfModule>
|
|
@ -81,8 +81,8 @@ $web_path = AmpConfig::get('raw_web_path');
|
||||||
<service>
|
<service>
|
||||||
<serviceType>urn:schemas-upnp-org:service:ConnectionManager:1</serviceType>
|
<serviceType>urn:schemas-upnp-org:service:ConnectionManager:1</serviceType>
|
||||||
<serviceId>urn:upnp-org:serviceId:ConnectionManager</serviceId>
|
<serviceId>urn:upnp-org:serviceId:ConnectionManager</serviceId>
|
||||||
<controlURL><?php echo $web_path; ?>/upnp/cmControl.xml</controlURL>
|
<controlURL><?php echo $web_path; ?>/upnp/cm-control-reply.php</controlURL>
|
||||||
<eventSubURL><?php echo $web_path; ?>/upnp/event-reply.php</eventSubURL>
|
<eventSubURL><?php echo $web_path; ?>/upnp/cm-event-reply.php</eventSubURL>
|
||||||
<SCPDURL><?php echo $web_path; ?>/upnp/MediaServerConnectionManager.xml</SCPDURL>
|
<SCPDURL><?php echo $web_path; ?>/upnp/MediaServerConnectionManager.xml</SCPDURL>
|
||||||
</service>
|
</service>
|
||||||
</serviceList>
|
</serviceList>
|
||||||
|
|
32
upnp/cm-control-reply.php
Normal file
32
upnp/cm-control-reply.php
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
<?php
|
||||||
|
define('NO_SESSION','1');
|
||||||
|
require_once '../lib/init.php';
|
||||||
|
|
||||||
|
if (!AmpConfig::get('upnp_backend')) {
|
||||||
|
echo "Disabled.";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
set_time_limit(600);
|
||||||
|
|
||||||
|
header ("Content-Type: text/html; charset=UTF-8");
|
||||||
|
|
||||||
|
// Parse the request from UPnP player
|
||||||
|
$requestRaw = file_get_contents('php://input');
|
||||||
|
if ($requestRaw != '') {
|
||||||
|
$upnpRequest = Upnp_Api::parseUPnPRequest($requestRaw);
|
||||||
|
debug_event('upnp-cm', 'Request: ' . $requestRaw, '5');
|
||||||
|
} else {
|
||||||
|
echo 'Error: no UPnP request.';
|
||||||
|
debug_event('upnp-cm', 'No request', '5');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($upnpRequest['action']) {
|
||||||
|
case 'getprotocolinfo':
|
||||||
|
$responseType = 'u:GetProtocolInfoResponse';
|
||||||
|
//$items = Upnp_Api::cm_getProtocolInfo();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
3
upnp/cm-event-reply.php
Normal file
3
upnp/cm-event-reply.php
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<?php
|
||||||
|
require_once 'event-reply.php';
|
||||||
|
?>
|
Loading…
Add table
Add a link
Reference in a new issue