You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
686 lines
18 KiB
686 lines
18 KiB
/*
|
|
* playlistimport.cpp
|
|
*
|
|
* Copyright (C) 2004-2005 Jürgen Kofler <kaffeine@gmx.net>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|
*/
|
|
|
|
#include <tqdom.h>
|
|
#include <tqregexp.h>
|
|
#include <tqxml.h>
|
|
|
|
#include <kdebug.h>
|
|
#include <tdeio/netaccess.h>
|
|
|
|
#include "playlistimport.h"
|
|
|
|
class MyXMLParser : public TQXmlDefaultHandler
|
|
{
|
|
|
|
public:
|
|
TQValueList<MRL> mrls;
|
|
bool isKaffeinePlaylist;
|
|
|
|
|
|
MyXMLParser() : isKaffeinePlaylist(false)
|
|
{}
|
|
|
|
bool startElement(const TQString&, const TQString&,
|
|
const TQString &qname, const TQXmlAttributes &att)
|
|
{
|
|
|
|
if (qname == "playlist")
|
|
if (att.value("client") == "kaffeine")
|
|
{
|
|
isKaffeinePlaylist = true;
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (qname != "entry") return true;
|
|
|
|
TQStringList subs = TQStringList();
|
|
int currentSub = -1;
|
|
|
|
if ((!att.value("subs").isNull()) && (!att.value("subs").isEmpty()))
|
|
subs = TQStringList::split("&",att.value("subs"),false);
|
|
if ((!att.value("subs").isNull()) && (!att.value("subs").isEmpty()))
|
|
{
|
|
bool ok;
|
|
currentSub = att.value("currentSub").toInt(&ok);
|
|
if (!ok)
|
|
currentSub = -1;
|
|
}
|
|
|
|
// kdDebug() << "PlaylistImport: kaffeine import url: " << att.value("url") << endl;
|
|
mrls.append(MRL(att.value("url"), att.value("title"), PlaylistImport::stringToTime(att.value("length")),
|
|
att.value("mime"), att.value("artist"), att.value("album"), att.value("track"),
|
|
att.value("year"), att.value("genre"), TQString(), subs, currentSub));
|
|
return true;
|
|
}
|
|
|
|
};
|
|
|
|
bool PlaylistImport::kaffeine(const TQString& playlist, TQValueList<MRL>& mrls)
|
|
{
|
|
kdDebug() << "PlaylistImport: kaffeine: " << playlist << endl;
|
|
TQFile file(playlist);
|
|
if (!file.open(IO_ReadOnly)) return false;
|
|
|
|
TQXmlInputSource source(&file);
|
|
TQXmlSimpleReader reader;
|
|
|
|
MyXMLParser parser;
|
|
reader.setContentHandler(&parser);
|
|
reader.parse(source);
|
|
file.close();
|
|
|
|
if (!parser.isKaffeinePlaylist)
|
|
{
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
TQValueList<MRL>::ConstIterator end(parser.mrls.end());
|
|
for (TQValueList<MRL>::ConstIterator it = parser.mrls.begin(); it != end; ++it)
|
|
mrls.append(*it);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
class NoatunXMLParser : public TQXmlDefaultHandler
|
|
{
|
|
|
|
public:
|
|
TQValueList<MRL> mrls;
|
|
bool isNoatunPlaylist;
|
|
|
|
NoatunXMLParser(): isNoatunPlaylist(false)
|
|
{}
|
|
|
|
bool startElement(const TQString&, const TQString &,
|
|
const TQString &qname, const TQXmlAttributes &att)
|
|
{
|
|
|
|
if (qname == "playlist")
|
|
if (att.value("client") == "noatun")
|
|
{
|
|
isNoatunPlaylist = true;
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (qname != "item") return true;
|
|
|
|
TQString title = att.value("title");
|
|
|
|
if (title.isNull())
|
|
title = att.value("url");
|
|
|
|
bool ok;
|
|
TQTime length;
|
|
int time = att.value("length").toInt(&ok);
|
|
if ((ok) && (time > 0))
|
|
{
|
|
length = TQTime().addMSecs(time);
|
|
}
|
|
|
|
kdDebug() << "PlaylistImport: noatun import url: " << att.value("url") << endl;
|
|
mrls.append(MRL(att.value("url"), title, length, TQString(), att.value("author"),
|
|
att.value("album"), att.value("track")));
|
|
|
|
return true;
|
|
}
|
|
|
|
};
|
|
|
|
bool PlaylistImport::noatun(const TQString& playlist, TQValueList<MRL>& mrls)
|
|
{
|
|
kdDebug() << "PlaylistImport: noatun: " << playlist << endl;
|
|
TQFile file(playlist);
|
|
if (!file.open(IO_ReadOnly)) return false;
|
|
|
|
TQXmlInputSource source(&file);
|
|
TQXmlSimpleReader reader;
|
|
|
|
NoatunXMLParser parser;
|
|
reader.setContentHandler(&parser);
|
|
reader.parse(source);
|
|
file.close();
|
|
|
|
if (!parser.isNoatunPlaylist)
|
|
{
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
TQValueList<MRL>::ConstIterator end(parser.mrls.end());
|
|
for (TQValueList<MRL>::ConstIterator it = parser.mrls.begin(); it != end; ++it)
|
|
mrls.append(*it);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
bool PlaylistImport::m3u(const TQString& playlist , TQValueList<MRL>& mrls)
|
|
{
|
|
kdDebug() << "PlaylistImport: m3u: " << playlist << endl;
|
|
TQFile file(playlist);
|
|
if (!file.open(IO_ReadOnly)) return false;
|
|
TQTextStream stream(&file);
|
|
|
|
// if (stream.readLine().upper() != "#EXTM3U") return false;
|
|
TQString url;
|
|
int time;
|
|
bool ok;
|
|
TQTime length;
|
|
TQString title;
|
|
KURL kUrl;
|
|
bool foundAnyUrl = false;
|
|
KURL plurl(playlist);
|
|
plurl.setFileName ("");
|
|
|
|
while (!stream.eof())
|
|
{
|
|
url = stream.readLine();
|
|
time = 0;
|
|
title = TQString();
|
|
length = TQTime();
|
|
if (url.left(1) == "#")
|
|
{
|
|
if (url.left(7).upper() == "#EXTINF")
|
|
{
|
|
url = url.remove(0,8);
|
|
time = url.section(",", 0,0).toInt(&ok);
|
|
if ((ok) && (time > 0))
|
|
{
|
|
length = TQTime().addSecs(time);
|
|
}
|
|
|
|
title = url.section(",",1,1);
|
|
url = stream.readLine();
|
|
}
|
|
else
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
url.replace ('\\', '/'); /* for windows styled urls */
|
|
kUrl = KURL (plurl, url); /* maybe a relative url */
|
|
if (kUrl.isValid())
|
|
{
|
|
kdDebug() << "PlaylistImport: m3u import url: " << kUrl.prettyURL() << endl;
|
|
|
|
MRL mrl;
|
|
if (kUrl.isLocalFile())
|
|
mrl.setURL(kUrl.path());
|
|
else
|
|
mrl.setURL(kUrl.prettyURL());
|
|
if (title.isNull())
|
|
title = kUrl.fileName();
|
|
mrl.setTitle(title);
|
|
mrl.setLength(length);
|
|
|
|
mrls.append(mrl);
|
|
|
|
foundAnyUrl = true;
|
|
}
|
|
else
|
|
kdDebug() << "PlaylistImport: M3U: Not valid: " << kUrl.prettyURL() << endl;
|
|
}
|
|
file.close();
|
|
if (foundAnyUrl)
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
|
|
bool PlaylistImport::pls(const TQString& playlist, TQValueList<MRL>& mrls)
|
|
{
|
|
kdDebug() << "PlaylistImport: pls: " << playlist << endl;
|
|
TQFile file(playlist);
|
|
if (!file.open(IO_ReadOnly)) return false;
|
|
|
|
TQTextStream stream(&file);
|
|
|
|
//if (stream.readLine().upper() != "[PLAYLIST]") return false;
|
|
|
|
// Better Handling of pls playlists - Taken from amaroK - amarok.kde.org
|
|
// Counted number of "File#=" lines.
|
|
uint entryCnt = 0;
|
|
// Value of the "NumberOfEntries=#" line.
|
|
uint numberOfEntries = 0;
|
|
bool havePlaylistSection = false;
|
|
TQString tmp;
|
|
TQStringList lines;
|
|
|
|
// set Regexp keywords, Be case insensitive
|
|
const TQRegExp regExp_NumberOfEntries("^NumberOfEntries\\s*=\\s*\\d+$", false);
|
|
const TQRegExp regExp_File("^File\\d+\\s*=", false);
|
|
const TQRegExp regExp_Title("^Title\\d+\\s*=", false);
|
|
const TQRegExp regExp_Length("^Length\\d+\\s*=\\s*-?\\d+$", false);
|
|
const TQRegExp regExp_Version("^Version\\s*=\\s*\\d+$", false);
|
|
const TQString section_playlist("[playlist]");
|
|
|
|
/* Preprocess the input data.
|
|
* Read the lines into a buffer; Cleanup the line strings;
|
|
* Count the entries manually and read "NumberOfEntries".
|
|
*/
|
|
while (!stream.atEnd()) {
|
|
tmp = stream.readLine();
|
|
tmp = tmp.stripWhiteSpace();
|
|
if (tmp.isEmpty())
|
|
continue;
|
|
lines.append(tmp);
|
|
|
|
if (tmp == section_playlist) {
|
|
havePlaylistSection = true;
|
|
continue;
|
|
}
|
|
|
|
if (tmp.contains(regExp_File)) {
|
|
entryCnt++;
|
|
continue;
|
|
}
|
|
|
|
if (tmp.contains(regExp_NumberOfEntries)) {
|
|
numberOfEntries = TQString(tmp.section('=', -1)).stripWhiteSpace().toUInt();
|
|
continue;
|
|
}
|
|
}
|
|
|
|
file.close();
|
|
|
|
if (numberOfEntries != entryCnt) {
|
|
kdError() << "PlaylistImport: Invalid \"NumberOfEntries\" value in .pls playlist. "
|
|
<< "NumberOfEntries=" << numberOfEntries << " counted="
|
|
<< entryCnt << endl;
|
|
/* Corrupt file. The "NumberOfEntries" value is
|
|
* not correct. Fix it by setting it to the manually
|
|
* counted number and go on parsing.
|
|
*/
|
|
numberOfEntries = entryCnt;
|
|
}
|
|
// If we have no Entries, return
|
|
if (!numberOfEntries)
|
|
return true;
|
|
|
|
int time;
|
|
bool ok;
|
|
uint index;
|
|
bool inPlaylistSection = false;
|
|
TQString* titles = new TQString[entryCnt];
|
|
TQString* files = new TQString[entryCnt];
|
|
TQTime* length = new TQTime[entryCnt];
|
|
|
|
TQStringList::const_iterator i = lines.begin(), end = lines.end();
|
|
for ( ; i != end; ++i) {
|
|
if (!inPlaylistSection && havePlaylistSection) {
|
|
/* The playlist begins with the "[playlist]" tag.
|
|
* Skip everything before this.
|
|
*/
|
|
if ((*i) == section_playlist)
|
|
inPlaylistSection = true;
|
|
continue;
|
|
}
|
|
if ((*i).contains(regExp_File)) {
|
|
// Have a "File#=XYZ" line.
|
|
index = extractIndex(*i);
|
|
if (index > numberOfEntries || index == 0)
|
|
continue;
|
|
files[index-1] = TQString((*i).section('=', 1)).stripWhiteSpace();
|
|
continue;
|
|
}
|
|
if ((*i).contains(regExp_Title)) {
|
|
// Have a "Title#=XYZ" line.
|
|
index = extractIndex(*i);
|
|
if (index > numberOfEntries || index == 0)
|
|
continue;
|
|
titles[index-1] = TQString((*i).section('=', 1)).stripWhiteSpace();
|
|
continue;
|
|
}
|
|
if ((*i).contains(regExp_Length)) {
|
|
// Have a "Length#=XYZ" line.
|
|
index = extractIndex(*i);
|
|
if (index > numberOfEntries || index == 0)
|
|
continue;
|
|
tmp = TQString((*i).section('=', 1)).stripWhiteSpace();
|
|
time = tmp.toInt(&ok);
|
|
if ( !(ok) || !(time > 0) ) continue;
|
|
length[index-1] = TQTime().addSecs(time);
|
|
continue;
|
|
}
|
|
if ((*i).contains(regExp_NumberOfEntries)) {
|
|
// Have the "NumberOfEntries=#" line.
|
|
continue;
|
|
}
|
|
if ((*i).contains(regExp_Version)) {
|
|
// Have the "Version=#" line.
|
|
tmp = TQString((*i).section('=', 1)).stripWhiteSpace();
|
|
// We only support Version=2
|
|
if (tmp.toUInt(&ok) != 2)
|
|
kdWarning() << "PlaylistImport: pls: Unsupported version." << endl;
|
|
continue;
|
|
}
|
|
kdWarning() << "PlaylistImport: pls: Unrecognized line: \"" << *i << "\"" << endl;
|
|
}
|
|
|
|
for (uint i=0; i<entryCnt; i++)
|
|
{
|
|
if (files[i].isNull()) continue;
|
|
kdDebug() << "PlaylistImport: pls import url: " << files[i] << endl;
|
|
if (titles[i].isNull())
|
|
titles[i] = files[i];
|
|
mrls.append(MRL(files[i], titles[i], length[i]));
|
|
}
|
|
|
|
delete [] titles;
|
|
delete [] files;
|
|
delete [] length;
|
|
|
|
return true;
|
|
}
|
|
|
|
// Helper for pls import
|
|
uint PlaylistImport::extractIndex( const TQString &str )
|
|
{
|
|
/* Extract the index number out of a .pls line.
|
|
* Example:
|
|
* extractIndex("File2=foobar") == 2
|
|
*/
|
|
bool ok = false;
|
|
unsigned int ret;
|
|
TQString tmp(str.section('=', 0, 0));
|
|
tmp.remove(TQRegExp("^\\D*"));
|
|
ret = tmp.stripWhiteSpace().toUInt(&ok);
|
|
if (!ok)
|
|
kdError() << "PlaylistImport: pls: Corrupt pls file, Error extracting index." << endl;
|
|
return ret;
|
|
}
|
|
|
|
bool PlaylistImport::ram(const MRL& playlist, TQValueList<MRL>& mrls, TQWidget* parent)
|
|
{
|
|
TQ_ULONG result;
|
|
char buf[10];
|
|
|
|
kdDebug() << "PlaylistImport: ram: " << playlist.url() << endl;
|
|
memset( buf, 0, 10 );
|
|
|
|
if (playlist.kurl().isLocalFile()) {
|
|
TQFile file(playlist.kurl().path());
|
|
if (!file.open(IO_ReadOnly)) {
|
|
kdError() << "PlaylistImport: Can't open " << playlist.url() << endl;
|
|
return false;
|
|
}
|
|
result = file.readBlock(buf, 4);
|
|
file.close();
|
|
if (result != 4) {
|
|
kdError() << "PlaylistImport: Can't read " << playlist.url() << endl;
|
|
return false;
|
|
}
|
|
if (buf[0]=='.' && buf[1]=='R' && buf[2]=='M' && buf[3]=='F') {
|
|
kdDebug() << "PlaylistImport: Seems to be a real media file" << endl;
|
|
return false;
|
|
}
|
|
}
|
|
else if (!playlist.kurl().protocol().startsWith("http")) {
|
|
kdError() << "PlaylistImport: ram: Download via " << playlist.kurl().protocol() << " protocol not supported." << endl;
|
|
return false;
|
|
}
|
|
|
|
kdDebug() << "PlaylistImport: Seems to be a ram playlist!" << endl;
|
|
|
|
TQString localFile, url;
|
|
if (TDEIO::NetAccess::mimetype(playlist.kurl(), parent) == "application/vnd.rn-realmedia") {
|
|
kdDebug() << "PlaylistImport: Seems to be a real media file" << endl;
|
|
return false;
|
|
}
|
|
|
|
if (TDEIO::NetAccess::download(playlist.kurl(), localFile, parent))
|
|
{
|
|
TQFile plFile(localFile);
|
|
if (!plFile.open(IO_ReadOnly)) return false;
|
|
TQTextStream stream( &plFile );
|
|
|
|
while (!stream.eof())
|
|
{
|
|
url = stream.readLine();
|
|
|
|
if (url[0] == '#') continue; /* ignore comments */
|
|
if (url == "--stop--") break; /* stop line */
|
|
|
|
if ((url.left(7) == "rtsp://") || (url.left(6) == "pnm://") || (url.left(7) == "http://"))
|
|
{
|
|
kdDebug() << "PlaylistImport: ram import url: " << url << endl;
|
|
mrls.append(MRL(url, url));
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
kdError() << "PlaylistImport: " << TDEIO::NetAccess::lastErrorString() << endl;
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**********************************************************************************
|
|
* load asx playlist *
|
|
* spec: http://msdn.microsoft.com/library/en-us/wmplay/mmp_sdk/asxelement.asp *
|
|
**********************************************************************************/
|
|
|
|
bool PlaylistImport::asx(const TQString& playlist, TQValueList<MRL>& mrls)
|
|
{
|
|
kdDebug() << "PlaylistImport: asx: " << playlist << endl;
|
|
TQFile file(playlist);
|
|
if (!file.open(IO_ReadOnly)) return false;
|
|
|
|
TQDomDocument doc;
|
|
TQString errorMsg;
|
|
int errorLine, errorColumn;
|
|
if (!doc.setContent(&file, &errorMsg, &errorLine, &errorColumn))
|
|
{
|
|
kdError() << "PlaylistImport: XML parse error: " << errorMsg
|
|
<< " (line: " << errorLine << ", column: " << errorColumn << ")" << endl;
|
|
return false;
|
|
}
|
|
|
|
TQDomElement root = doc.documentElement();
|
|
|
|
TQString url;
|
|
TQString title;
|
|
TQString author;
|
|
TQTime length;
|
|
TQString duration;
|
|
|
|
if (root.nodeName().lower() != "asx") return false;
|
|
|
|
TQDomNode node = root.firstChild();
|
|
TQDomNode subNode;
|
|
TQDomElement element;
|
|
|
|
while (!node.isNull())
|
|
{
|
|
url = TQString();
|
|
title = TQString();
|
|
author = TQString();
|
|
length = TQTime();
|
|
if (node.nodeName().lower() == "entry")
|
|
{
|
|
subNode = node.firstChild();
|
|
while (!subNode.isNull())
|
|
{
|
|
if ((subNode.nodeName().lower() == "ref") && (subNode.isElement()) && (url.isNull()))
|
|
{
|
|
element = subNode.toElement();
|
|
if (element.hasAttribute("href"))
|
|
url = element.attribute("href");
|
|
if (element.hasAttribute("HREF"))
|
|
url = element.attribute("HREF");
|
|
if (element.hasAttribute("Href"))
|
|
url = element.attribute("Href");
|
|
if (element.hasAttribute("HRef"))
|
|
url = element.attribute("HRef");
|
|
|
|
}
|
|
|
|
if ((subNode.nodeName().lower() == "duration") && (subNode.isElement()))
|
|
{
|
|
duration = TQString();
|
|
element = subNode.toElement();
|
|
if (element.hasAttribute("value"))
|
|
duration = element.attribute("value");
|
|
if (element.hasAttribute("Value"))
|
|
duration = element.attribute("Value");
|
|
if (element.hasAttribute("VALUE"))
|
|
duration = element.attribute("VALUE");
|
|
|
|
if (!duration.isNull())
|
|
length = PlaylistImport::stringToTime(duration);
|
|
}
|
|
|
|
if ((subNode.nodeName().lower() == "title") && (subNode.isElement()))
|
|
{
|
|
title = subNode.toElement().text();
|
|
}
|
|
if ((subNode.nodeName().lower() == "author") && (subNode.isElement()))
|
|
{
|
|
author = subNode.toElement().text();
|
|
}
|
|
|
|
/* possible nodes we ignore: ABSTRACT, BANNER, BASE, COPYRIGHT, ENDMARKER, MOREINFO, PARAM,
|
|
* PREVIEWDURATION, STARTMARKER, STARTTIME
|
|
*/
|
|
subNode = subNode.nextSibling();
|
|
}
|
|
|
|
if (!url.isNull())
|
|
{
|
|
if (title.isNull())
|
|
title = url;
|
|
kdDebug() << "PlaylistImport: asx import url: " << url << endl;
|
|
mrls.append(MRL(url, title, length, TQString(), author));
|
|
}
|
|
}
|
|
node = node.nextSibling();
|
|
}
|
|
|
|
file.close();
|
|
|
|
return true;
|
|
}
|
|
|
|
/****************************************************************
|
|
* Full SMIL support seems to be impossible at the moment... *
|
|
* spec: http://www.w3.org/TR/REC-smil/ *
|
|
****************************************************************/
|
|
|
|
bool PlaylistImport::smil(const TQString& playlist, const MRL& baseMRL, TQValueList<MRL>& mrls)
|
|
{
|
|
kdDebug() << "PlaylistImport: smil: " << playlist << endl;
|
|
TQFile file(playlist);
|
|
if (!file.open(IO_ReadOnly)) return false;
|
|
|
|
TQDomDocument doc;
|
|
doc.setContent(&file);
|
|
TQDomElement root = doc.documentElement();
|
|
|
|
if (root.nodeName().lower() != "smil") return false;
|
|
|
|
bool anyURL = false;
|
|
KURL kurl;
|
|
TQString url;
|
|
TQDomNodeList nodeList;
|
|
TQDomNode node;
|
|
TQDomElement element;
|
|
|
|
//video sources...
|
|
nodeList = doc.elementsByTagName("video");
|
|
kdDebug() << "PlaylistImport: smil: " << nodeList.count() << " 'video' tags found" << endl;
|
|
for (uint i = 0; i < nodeList.count(); i++)
|
|
{
|
|
node = nodeList.item(i);
|
|
url = TQString();
|
|
if ((node.nodeName().lower() == "video") && (node.isElement()))
|
|
{
|
|
element = node.toElement();
|
|
if (element.hasAttribute("src"))
|
|
url = element.attribute("src");
|
|
if (element.hasAttribute("Src"))
|
|
url = element.attribute("Src");
|
|
if (element.hasAttribute("SRC"))
|
|
url = element.attribute("SRC");
|
|
}
|
|
if (!url.isNull())
|
|
{
|
|
kurl = KURL(baseMRL.kurl(), url);
|
|
kdDebug() << "PlaylistImport: smil: found video source: " << kurl.url() << endl;
|
|
mrls.append(kurl);
|
|
anyURL = true;
|
|
}
|
|
}
|
|
|
|
//audio sources...
|
|
nodeList = doc.elementsByTagName("audio");
|
|
kdDebug() << "PlaylistImport: smil: " << nodeList.count() << " 'audio' tags found" << endl;
|
|
for (uint i = 0; i < nodeList.count(); i++)
|
|
{
|
|
node = nodeList.item(i);
|
|
url = TQString();
|
|
if ((node.nodeName().lower() == "audio") && (node.isElement()))
|
|
{
|
|
element = node.toElement();
|
|
if (element.hasAttribute("src"))
|
|
url = element.attribute("src");
|
|
if (element.hasAttribute("Src"))
|
|
url = element.attribute("Src");
|
|
if (element.hasAttribute("SRC"))
|
|
url = element.attribute("SRC");
|
|
}
|
|
if (!url.isNull())
|
|
{
|
|
kurl = KURL(baseMRL.kurl(), url);
|
|
kdDebug() << "PlaylistImport: smil: found audio source: " << kurl.url() << endl;
|
|
mrls.append(kurl);
|
|
anyURL = true;
|
|
}
|
|
}
|
|
|
|
file.close();
|
|
return anyURL;
|
|
}
|
|
|
|
TQTime PlaylistImport::stringToTime(const TQString& timeString)
|
|
{
|
|
int sec = 0;
|
|
bool ok = false;
|
|
TQStringList tokens = TQStringList::split(':',timeString);
|
|
|
|
sec += tokens[0].toInt(&ok)*3600; //hours
|
|
sec += tokens[1].toInt(&ok)*60; //minutes
|
|
sec += tokens[2].toInt(&ok); //secs
|
|
|
|
if (ok)
|
|
return TQTime().addSecs(sec);
|
|
else
|
|
return TQTime();
|
|
}
|