1
0
Fork 0
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:
Afterster 2014-07-05 00:36:54 +02:00
parent d045a75e11
commit e07d23d7c9
9 changed files with 200 additions and 87 deletions

45
bin/broadcast.inc Normal file
View 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";
?>

View file

@ -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

View file

@ -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;

View file

@ -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;

View file

@ -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:*',
), ),
); );
} }

View file

@ -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>

View file

@ -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
View 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
View file

@ -0,0 +1,3 @@
<?php
require_once 'event-reply.php';
?>