313 lines
10 KiB
PHP
313 lines
10 KiB
PHP
<?
|
|
define('INDCH', ' ');
|
|
|
|
require_once("XmlParser.php");
|
|
|
|
/**
|
|
* SmilPlaylist class
|
|
*
|
|
* @package Airtime
|
|
* @subpackage StorageServer
|
|
* @copyright 2010 Sourcefabric O.P.S.
|
|
* @license http://www.gnu.org/licenses/gpl.txt
|
|
*/
|
|
class SmilPlaylist {
|
|
|
|
/**
|
|
* Parse SMIL file or string
|
|
*
|
|
* @param string $data
|
|
* local path to SMIL file or SMIL string
|
|
* @param string $loc
|
|
* location: 'file'|'string'
|
|
* @return array
|
|
* reference, parse result tree (or PEAR::error)
|
|
*/
|
|
private static function &parse($data='', $loc='file')
|
|
{
|
|
return XmlParser::parse($data, $loc);
|
|
}
|
|
|
|
|
|
/**
|
|
* Import SMIL file to storage
|
|
*
|
|
* @param GreenBox $gb
|
|
* reference to GreenBox object
|
|
* @param string $aPath
|
|
* absolute path part of imported file (e.g. /home/user/airtime)
|
|
* @param string $rPath
|
|
* relative path/filename part of imported file
|
|
* (e.g. playlists/playlist_1.smil)
|
|
* @param array $gunids
|
|
* hash relation from filenames to gunids
|
|
* @param string $plid
|
|
* playlist gunid
|
|
* @param int $subjid
|
|
* local subject (user) id (id of user doing the import)
|
|
* @return Playlist
|
|
*/
|
|
public static function &import(&$gb, $aPath, $rPath, &$gunids, $plid, $subjid=NULL)
|
|
{
|
|
$parr = compact('subjid', 'aPath', 'plid', 'rPath');
|
|
$path = realpath("$aPath/$rPath");
|
|
if (FALSE === $path) {
|
|
return PEAR::raiseError(
|
|
"SmilPlaylist::import: file doesn't exist ($aPath/$rPath)"
|
|
);
|
|
}
|
|
$lspl = SmilPlaylist::convert2lspl($gb, $path, $gunids, $parr);
|
|
if (PEAR::isError($lspl)) {
|
|
return $lspl;
|
|
}
|
|
require_once("Playlist.php");
|
|
$pl =& Playlist::create($gb, $plid, "imported_SMIL");
|
|
if (PEAR::isError($pl)) {
|
|
return $pl;
|
|
}
|
|
$r = $pl->lock($gb, $subjid);
|
|
if (PEAR::isError($r)) {
|
|
return $r;
|
|
}
|
|
$r = $pl->setMetadata($lspl, 'string', 'playlist');
|
|
if (PEAR::isError($r)) {
|
|
return $r;
|
|
}
|
|
$r = $pl->unlock($gb);
|
|
if (PEAR::isError($r)) {
|
|
return $r;
|
|
}
|
|
return $pl;
|
|
}
|
|
|
|
|
|
/**
|
|
* Import SMIL file to storage.
|
|
*
|
|
* @param GreenBox $gb
|
|
* @param string $data
|
|
* local path to SMIL file
|
|
* @param hasharray $gunids
|
|
* hash relation from filenames to gunids
|
|
* @param array $parr
|
|
* array of subjid, aPath, plid, rPath
|
|
* @return string
|
|
* XML of playlist in Airtime playlist format
|
|
*/
|
|
public static function convert2lspl(&$gb, $data, &$gunids, $parr)
|
|
{
|
|
extract($parr);
|
|
$tree = SmilPlaylist::parse($data);
|
|
if (PEAR::isError($tree)) {
|
|
return $tree;
|
|
}
|
|
if ($tree->name != 'smil') {
|
|
return PEAR::raiseError("SmilPlaylist::parse: smil tag expected");
|
|
}
|
|
if (isset($tree->children[1])) {
|
|
return PEAR::raiseError(sprintf(
|
|
"SmilPlaylist::parse: unexpected tag %s in tag smil",
|
|
$tree->children[1]->name
|
|
));
|
|
}
|
|
$res = SmilPlaylistBodyElement::convert2lspl(
|
|
$gb, $tree->children[0], &$gunids, $parr);
|
|
return $res;
|
|
}
|
|
|
|
} // SmilPlaylist
|
|
|
|
|
|
/**
|
|
* @package Airtime
|
|
* @subpackage StorageServer
|
|
* @copyright 2010 Sourcefabric O.P.S.
|
|
* @license http://www.gnu.org/licenses/gpl.txt
|
|
*/
|
|
class SmilPlaylistBodyElement {
|
|
|
|
public static function convert2lspl(&$gb, &$tree, &$gunids, $parr, $ind='')
|
|
{
|
|
extract($parr);
|
|
$ind2 = $ind.INDCH;
|
|
if ($tree->name != 'body') {
|
|
return PEAR::raiseError("SmilPlaylist::parse: body tag expected");
|
|
}
|
|
if (isset($tree->children[1])) {
|
|
return PEAR::raiseError(sprintf(
|
|
"SmilPlaylist::parse: unexpected tag %s in tag body",
|
|
$tree->children[1]->name
|
|
));
|
|
}
|
|
$res = SmilPlaylistParElement::convert2lspl(
|
|
$gb, $tree->children[0], &$gunids, $parr, $ind2);
|
|
if (PEAR::isError($res)) {
|
|
return $res;
|
|
}
|
|
$title = basename($rPath);
|
|
$playlength = '0';
|
|
$res = "$ind<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n".
|
|
"$ind<playlist id=\"$plid\" playlength=\"$playlength\" title=\"$title\">\n".
|
|
"$ind2<metadata/>\n".
|
|
"$res".
|
|
"$ind</playlist>\n";
|
|
return $res;
|
|
}
|
|
|
|
} // class SmilPlaylistBodyElement
|
|
|
|
|
|
/**
|
|
* @package Airtime
|
|
* @subpackage StorageServer
|
|
* @copyright 2010 Sourcefabric O.P.S.
|
|
* @license http://www.gnu.org/licenses/gpl.txt
|
|
*/
|
|
class SmilPlaylistParElement {
|
|
|
|
public static function convert2lspl(&$gb, &$tree, &$gunids, $parr, $ind='')
|
|
{
|
|
extract($parr);
|
|
if ($tree->name != 'par') {
|
|
return PEAR::raiseError("SmilPlaylist::parse: par tag expected");
|
|
}
|
|
$res = '';
|
|
foreach ($tree->children as $i => $ch) {
|
|
$ch =& $tree->children[$i];
|
|
$r = SmilPlaylistAudioElement::convert2lspl($gb, $ch, &$gunids, $parr, $ind.INDCH);
|
|
if (PEAR::isError($r)) {
|
|
return $r;
|
|
}
|
|
$res .= $r;
|
|
}
|
|
return $res;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* @package Airtime
|
|
* @subpackage StorageServer
|
|
* @copyright 2010 Sourcefabric O.P.S.
|
|
* @license http://www.gnu.org/licenses/gpl.txt
|
|
*/
|
|
class SmilPlaylistAudioElement {
|
|
public static function convert2lspl(&$gb, &$tree, &$gunids, $parr, $ind='')
|
|
{
|
|
extract($parr);
|
|
$uri = $tree->attrs['src']->val;
|
|
$gunid = ( isset($gunids[basename($uri)]) ? $gunids[basename($uri)] : NULL);
|
|
$ind2 = $ind.INDCH;
|
|
if ($tree->name != 'audio') {
|
|
return PEAR::raiseError("SmilPlaylist::parse: audio tag expected");
|
|
}
|
|
if (isset($tree->children[2])) {
|
|
return PEAR::raiseError(sprintf(
|
|
"SmilPlaylist::parse: unexpected tag %s in tag audio",
|
|
$tree->children[2]->name
|
|
));
|
|
}
|
|
$res = ''; $fadeIn = 0; $fadeOut = 0;
|
|
foreach ($tree->children as $i => $ch) {
|
|
$ch =& $tree->children[$i];
|
|
$r = SmilPlaylistAnimateElement::convert2lspl($gb, $ch, &$gunids, $parr, $ind2);
|
|
if (PEAR::isError($r)) {
|
|
return $r;
|
|
}
|
|
switch ($r['type']) {
|
|
case "fadeIn": $fadeIn = $r['val']; break;
|
|
case "fadeOut": $fadeOut = $r['val']; break;
|
|
}
|
|
}
|
|
if ($fadeIn > 0 || $fadeOut > 0) {
|
|
$fiGunid = StoredFile::CreateGunid();
|
|
$fadeIn = Playlist::secondsToPlaylistTime($fadeIn);
|
|
$fadeOut = Playlist::secondsToPlaylistTime($fadeOut);
|
|
$fInfo = "$ind2<fadeInfo id=\"$fiGunid\" fadeIn=\"$fadeIn\" fadeOut=\"$fadeOut\"/>\n";
|
|
} else {
|
|
$fInfo = '';
|
|
}
|
|
$plElGunid = StoredFile::CreateGunid();
|
|
$acGunid = $gunid;
|
|
$type = 'audioClip';
|
|
if (preg_match("|\.([a-zA-Z0-9]+)$|", $uri, $va)) {
|
|
switch (strtolower($ext = $va[1])) {
|
|
case "lspl":
|
|
case "xml":
|
|
case "smil":
|
|
case "m3u":
|
|
$type = 'playlist';
|
|
$acId = $gb->bsImportPlaylistRaw($gunid,
|
|
$aPath, $uri, $ext, $gunids, $subjid);
|
|
if (PEAR::isError($acId)) {
|
|
return $r;
|
|
}
|
|
//break;
|
|
default:
|
|
$ac = StoredFile::RecallByGunid($gunid);
|
|
if (is_null($ac) || PEAR::isError($ac)) {
|
|
return $ac;
|
|
}
|
|
$r = $ac->md->getMetadataElement('dcterms:extent');
|
|
if (PEAR::isError($r)) {
|
|
return $r;
|
|
}
|
|
$playlength = $r[0]['value'];
|
|
}
|
|
}
|
|
|
|
$title = basename($tree->attrs['src']->val);
|
|
$offset = Playlist::secondsToPlaylistTime($tree->attrs['begin']->val);
|
|
$clipStart = Playlist::secondsToPlaylistTime($tree->attrs['clipStart']->val);
|
|
$clipEnd = Playlist::secondsToPlaylistTime($tree->attrs['clipEnd']->val);
|
|
$clipLength = Playlist::secondsToPlaylistTime($tree->attrs['clipLength']->val);
|
|
$res = "$ind<playlistElement id=\"$plElGunid\" relativeOffset=\"$offset\" clipStart=\"$clipStart\" clipEnd=\"$clipEnd\" clipLength=\"$clipLength\">\n".
|
|
"$ind2<$type id=\"$acGunid\" playlength=\"$playlength\" title=\"$title\"/>\n".
|
|
$fInfo.
|
|
"$ind</playlistElement>\n";
|
|
return $res;
|
|
}
|
|
} // class SmilPlaylistAudioElement
|
|
|
|
|
|
/**
|
|
* @package Airtime
|
|
* @subpackage StorageServer
|
|
* @copyright 2010 Sourcefabric O.P.S.
|
|
* @license http://www.gnu.org/licenses/gpl.txt
|
|
*/
|
|
class SmilPlaylistAnimateElement {
|
|
|
|
public static function convert2lspl(&$gb, &$tree, &$gunids, $parr, $ind='')
|
|
{
|
|
extract($parr);
|
|
if ($tree->name != 'animate') {
|
|
return PEAR::raiseError("SmilPlaylist::parse: animate tag expected");
|
|
}
|
|
if ($tree->attrs['attributeName']->val == 'soundLevel' &&
|
|
$tree->attrs['from']->val == '0%' &&
|
|
$tree->attrs['to']->val == '100%' &&
|
|
$tree->attrs['calcMode']->val == 'linear' &&
|
|
$tree->attrs['fill']->val == 'freeze' &&
|
|
$tree->attrs['begin']->val == '0s' &&
|
|
preg_match("|^([0-9.]+)s$|", $tree->attrs['end']->val, $va)
|
|
) {
|
|
return array('type'=>'fadeIn', 'val'=>intval($va[1]));
|
|
}
|
|
if ($tree->attrs['attributeName']->val == 'soundLevel' &&
|
|
$tree->attrs['from']->val == '100%' &&
|
|
$tree->attrs['to']->val == '0%' &&
|
|
$tree->attrs['calcMode']->val == 'linear' &&
|
|
$tree->attrs['fill']->val == 'freeze' &&
|
|
preg_match("|^([0-9.]+)s$|", $tree->attrs['begin']->val, $vaBegin) &&
|
|
preg_match("|^([0-9.]+)s$|", $tree->attrs['end']->val, $vaEnd)
|
|
) {
|
|
return array('type'=>'fadeOut', 'val'=>($vaEnd[1] - $vaBegin[1]));
|
|
}
|
|
return PEAR::raiseError(
|
|
"SmilPlaylistAnimateElement::convert2lspl: animate parameters too general"
|
|
);
|
|
}
|
|
} // class SmilPlaylistAnimateElement
|
|
|