Got rid of all the stuff related to GUNID hex-to-int conversion. Commented out lots of functions that are either not in use or will no longer work. Pypo: made things more generic and pluggable, added documentation. Added the PHP scripts to serve the right info back to pypo.
352 lines
No EOL
12 KiB
PHP
352 lines
No EOL
12 KiB
PHP
<?
|
|
define('INDCH', ' ');
|
|
|
|
/**
|
|
* M3uPlaylist class
|
|
*
|
|
* @package Campcaster
|
|
* @subpackage StorageServer
|
|
* @copyright 2010 Sourcefabric O.P.S.
|
|
* @license http://www.gnu.org/licenses/gpl.txt
|
|
*/
|
|
class M3uPlaylist {
|
|
|
|
/**
|
|
* Parse M3U file or string
|
|
*
|
|
* @param string $data
|
|
* local path to M3U file or M3U string
|
|
* @param string $loc
|
|
* location: 'file'|'string'
|
|
* @return array
|
|
* reference, parse result tree (or PEAR::error)
|
|
*/
|
|
function &parse($data='', $loc='file')
|
|
{
|
|
switch ($loc) {
|
|
case "file":
|
|
if (!is_file($data)) {
|
|
return PEAR::raiseError(
|
|
"M3uPlaylist::parse: file not found ($data)"
|
|
);
|
|
}
|
|
if (!is_readable($data)) {
|
|
return PEAR::raiseError(
|
|
"M3uPlaylist::parse: can't read file ($data)"
|
|
);
|
|
}
|
|
$data = file_get_contents($data);
|
|
case "string":
|
|
$arr = preg_split("|\n#EXTINF: |", $data);
|
|
if ($arr[0] != '#EXTM3U') {
|
|
return PEAR::raiseError(
|
|
"M3uPlaylist::parse: invalid M3U header"
|
|
);
|
|
}
|
|
array_shift($arr);
|
|
break;
|
|
default:
|
|
return PEAR::raiseError(
|
|
"M3uPlaylist::parse: unsupported data location ($loc)"
|
|
);
|
|
}
|
|
return $arr;
|
|
}
|
|
|
|
|
|
/**
|
|
* Import M3U file to storage
|
|
*
|
|
* @param GreenBox $gb
|
|
* @param string $aPath
|
|
* absolute path part of imported file (e.g. /home/user/campcaster)
|
|
* @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
|
|
*/
|
|
function import(&$gb, $aPath, $rPath, &$gunids, $plid, $subjid=NULL)
|
|
{
|
|
// $path = realpath("$aPath/$rPath");
|
|
// if (FALSE === $path) {
|
|
// return PEAR::raiseError(
|
|
// "M3uPlaylist::import: file doesn't exist ($aPath/$rPath)"
|
|
// );
|
|
// }
|
|
// $arr = M3uPlaylist::parse($path);
|
|
// if (PEAR::isError($arr)) {
|
|
// return $arr;
|
|
// }
|
|
// require_once("Playlist.php");
|
|
// $pl =& Playlist::create($gb, $plid, "imported_M3U");
|
|
// if (PEAR::isError($pl)) {
|
|
// return $pl;
|
|
// }
|
|
// $r = $pl->lock($gb, $subjid);
|
|
// if (PEAR::isError($r)) {
|
|
// return $r;
|
|
// }
|
|
// foreach ($arr as $i => $it) {
|
|
// list($md, $uri) = preg_split("|\n|", $it);
|
|
// list($length, $title) = preg_split("|, *|", $md);
|
|
// // $gunid = StoredFile::CreateGunid();
|
|
// $gunid = ( isset($gunids[basename($uri)]) ? $gunids[basename($uri)] : NULL);
|
|
// $acId = BasicStor::IdFromGunid($gunid);
|
|
// if (PEAR::isError($acId)) {
|
|
// return $acId;
|
|
// }
|
|
// $length = Playlist::secondsToPlaylistTime($length);
|
|
// $offset = '???';
|
|
// if (preg_match("|\.([a-zA-Z0-9]+)$|", $uri, $va)) {
|
|
// switch (strtolower($ext = $va[1])) {
|
|
// case "lspl":
|
|
// case "xml":
|
|
// case "smil":
|
|
// case "m3u":
|
|
// $acId = $gb->bsImportPlaylistRaw($gunid,
|
|
// $aPath, $uri, $ext, $gunids, $subjid);
|
|
// if (PEAR::isError($acId)) {
|
|
// break;
|
|
// }
|
|
// //no break!
|
|
// default:
|
|
// if (is_null($gunid)) {
|
|
// return PEAR::raiseError(
|
|
// "M3uPlaylist::import: no gunid");
|
|
// }
|
|
// $r = $pl->addAudioClip($acId);
|
|
// if (PEAR::isError($r)) {
|
|
// return $r;
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
// $r = $pl->unlock($gb);
|
|
// if (PEAR::isError($r)) {
|
|
// return $r;
|
|
// }
|
|
// return $pl;
|
|
}
|
|
|
|
/**
|
|
* Import M3U file to storage
|
|
*
|
|
* @param GreenBox $gb
|
|
* @param string $data
|
|
* local path to M3U file
|
|
* @return string
|
|
* XML playlist in Campcaster playlist format
|
|
*/
|
|
function convert2lspl(&$gb, $data)
|
|
{
|
|
$arr = M3uPlaylist::parse($data);
|
|
if (PEAR::isError($arr)) {
|
|
return $arr;
|
|
}
|
|
$ind = '';
|
|
$ind2 = $ind.INDCH;
|
|
$ind3 = $ind2.INDCH;
|
|
$res = '';
|
|
foreach ($arr as $i => $it) {
|
|
list($md, $uri) = preg_split("|\n|", $it);
|
|
list($length, $title) = preg_split("|, *|", $md);
|
|
$gunid = StoredFile::CreateGunid();
|
|
$gunid2 = StoredFile::CreateGunid();
|
|
$length = Playlist::secondsToPlaylistTime($length);
|
|
$offset = '???';
|
|
$clipStart = '???';
|
|
$clipEnd = '???';
|
|
$clipLength = '???';
|
|
$uri_h = preg_replace("|--|", "d;d;", htmlspecialchars("$uri"));
|
|
if (preg_match("|\.([a-zA-Z0-9]+)$|", $uri, $va)) {
|
|
switch (strtolower($ext = $va[1])) {
|
|
case "lspl":
|
|
case "xml":
|
|
case "smil":
|
|
case "m3u":
|
|
$acOrPl = "$ind3<playlist id=\"$gunid2\" ".
|
|
"playlength=\"$length\" title=\"$title\"/> ".
|
|
"<!-- $uri_h -->\n";
|
|
break;
|
|
default:
|
|
$acOrPl = "$ind3<audioClip id=\"$gunid2\" ".
|
|
"playlength=\"$length\" title=\"$title\"/> ".
|
|
"<!-- $uri_h -->\n";
|
|
break;
|
|
}
|
|
}
|
|
$res .= "$ind2<playlistElement id=\"$gunid\" relativeOffset=\"$offset\" clipStart=\"$clipStart\" clipEnd=\"$clipEnd\" clipLength=\"$clipLength\">\n".
|
|
$acOrPl.
|
|
"$ind2</playlistElement>\n";
|
|
}
|
|
$res = "$ind<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n".
|
|
"$ind<playlist id=\"$gunid\" playlength=\"$playlength\" title=\"\">\n".
|
|
"$ind2<metadata/>\n".
|
|
"$res".
|
|
"$ind</playlist>\n";
|
|
return $res;
|
|
}
|
|
} // class M3uPlaylist
|
|
|
|
|
|
/**
|
|
* @package Campcaster
|
|
* @subpackage StorageServer
|
|
* @copyright 2010 Sourcefabric O.P.S.
|
|
* @license http://www.gnu.org/licenses/gpl.txt
|
|
*/
|
|
class M3uPlaylistBodyElement {
|
|
function convert2lspl(&$tree, $ind='')
|
|
{
|
|
$ind2 = $ind.INDCH;
|
|
if ($tree->name != 'body') {
|
|
return PEAR::raiseError("M3uPlaylist::parse: body tag expected");
|
|
}
|
|
if (isset($tree->children[1])) {
|
|
return PEAR::raiseError(sprintf(
|
|
"M3uPlaylist::parse: unexpected tag %s in tag body",
|
|
$tree->children[1]->name
|
|
));
|
|
}
|
|
$res = M3uPlaylistParElement::convert2lspl($tree->children[0], $ind2);
|
|
if (PEAR::isError($res)) {
|
|
return $res;
|
|
}
|
|
$gunid = StoredFile::CreateGunid();
|
|
$playlength = '???'; // ***
|
|
$res = "$ind<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n".
|
|
"$ind<playlist id=\"$gunid\" playlength=\"$playlength\" title=\"\">\n".
|
|
"$ind2<metadata/>\n".
|
|
"$res".
|
|
"$ind</playlist>\n";
|
|
return $res;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* @package Campcaster
|
|
* @subpackage StorageServer
|
|
* @copyright 2010 Sourcefabric O.P.S.
|
|
* @license http://www.gnu.org/licenses/gpl.txt
|
|
*/
|
|
class M3uPlaylistParElement {
|
|
function convert2lspl(&$tree, $ind='')
|
|
{
|
|
if ($tree->name != 'par') {
|
|
return PEAR::raiseError("M3uPlaylist::parse: par tag expected");
|
|
}
|
|
$res = '';
|
|
foreach ($tree->children as $i => $ch) {
|
|
$ch =& $tree->children[$i];
|
|
$r = M3uPlaylistAudioElement::convert2lspl($ch, $ind.INDCH);
|
|
if (PEAR::isError($r)) {
|
|
return $r;
|
|
}
|
|
$res .= $r;
|
|
}
|
|
return $res;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* @package Campcaster
|
|
* @subpackage StorageServer
|
|
* @copyright 2010 Sourcefabric O.P.S.
|
|
* @license http://www.gnu.org/licenses/gpl.txt
|
|
*/
|
|
class M3uPlaylistAudioElement {
|
|
function convert2lspl(&$tree, $ind='')
|
|
{
|
|
$ind2 = $ind.INDCH;
|
|
if ($tree->name != 'audio') {
|
|
return PEAR::raiseError("M3uPlaylist::parse: audio tag expected");
|
|
}
|
|
if (isset($tree->children[2])) {
|
|
return PEAR::raiseError(sprintf(
|
|
"M3uPlaylist::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 = M3uPlaylistAnimateElement::convert2lspl($ch, $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) {
|
|
$fadeIn = Playlist::secondsToPlaylistTime($fadeIn);
|
|
$fadeOut = Playlist::secondsToPlaylistTime($fadeOut);
|
|
$fInfo = "$ind2<fadeInfo fadeIn=\"$fadeIn\" fadeOut=\"$fadeOut\"/>\n";
|
|
} else {
|
|
$fInfo = '';
|
|
}
|
|
$plElGunid = StoredFile::CreateGunid();
|
|
$aGunid = StoredFile::CreateGunid();
|
|
$title = basename($tree->attrs['src']->val);
|
|
$offset = Playlist::secondsToPlaylistTime($tree->attrs['begin']->val);
|
|
$playlength = '???'; # ***
|
|
$res = "$ind<playlistElement id=\"$plElGunid\" relativeOffset=\"$offset\">\n".
|
|
"$ind2<audioClip id=\"$aGunid\" playlength=\"$playlength\" title=\"$title\"/>\n".
|
|
$fInfo.
|
|
"$ind</playlistElement>\n";
|
|
return $res;
|
|
}
|
|
} // class M3uPlaylistAudioElement
|
|
|
|
|
|
/**
|
|
* @package Campcaster
|
|
* @subpackage StorageServer
|
|
* @copyright 2010 Sourcefabric O.P.S.
|
|
* @license http://www.gnu.org/licenses/gpl.txt
|
|
*/
|
|
class M3uPlaylistAnimateElement {
|
|
function convert2lspl(&$tree, $ind='') {
|
|
if ($tree->name != 'animate') {
|
|
return PEAR::raiseError("M3uPlaylist::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'=>$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(
|
|
"M3uPlaylistAnimateElement::convert2lspl: animate parameters too general"
|
|
);
|
|
}
|
|
}
|
|
|
|
?>
|