Added support for playlist import (M3U, PLS, ASX and WPL).

This commit is contained in:
LoRd_MuldeR 2011-01-30 21:49:32 +01:00
parent e9a1ba9b06
commit 571625a032
3 changed files with 266 additions and 5 deletions

View File

@ -25,8 +25,8 @@
#define VER_LAMEXP_MAJOR 4
#define VER_LAMEXP_MINOR_HI 0
#define VER_LAMEXP_MINOR_LO 0
#define VER_LAMEXP_BUILD 279
#define VER_LAMEXP_SUFFIX Beta-2
#define VER_LAMEXP_BUILD 282
#define VER_LAMEXP_SUFFIX Beta-3
/*
* Tools versions

View File

@ -77,9 +77,12 @@ void FileAnalyzer::run()
emit fileSelected(QFileInfo(currentFile).fileName());
AudioFileModel file = analyzeFile(currentFile);
if(file.fileName().isEmpty() || file.formatContainerType().isEmpty() || file.formatAudioType().isEmpty())
{
if(!importPlaylist(m_inputFiles, currentFile))
{
m_filesRejected++;
qDebug("Skipped: %s", file.filePath().toUtf8().constData());
}
continue;
}
m_filesAccepted++;
@ -91,7 +94,7 @@ void FileAnalyzer::run()
}
////////////////////////////////////////////////////////////
// Public Functions
// Privtae Functions
////////////////////////////////////////////////////////////
const AudioFileModel FileAnalyzer::analyzeFile(const QString &filePath)
@ -355,6 +358,246 @@ unsigned int FileAnalyzer::parseDuration(const QString &str)
return 0;
}
bool FileAnalyzer::importPlaylist(QStringList &fileList, const QString &playlistFile)
{
QFileInfo file(playlistFile);
QDir baseDir(file.canonicalPath());
QDir rootDir(baseDir);
while(rootDir.cdUp());
//Sanity check
if(file.size() < 3 || file.size() > 512000)
{
return false;
}
//Detect playlist type
playlist_t playlistType = isPlaylist(file.canonicalFilePath());
//Exit if not a playlist
if(playlistType == noPlaylist)
{
return false;
}
QFile data(playlistFile);
//Open file for reading
if(!data.open(QIODevice::ReadOnly))
{
return false;
}
//Parse playlist depending on type
switch(playlistType)
{
case m3uPlaylist:
return parsePlaylist_m3u(data, fileList, baseDir, rootDir);
break;
case plsPlaylist:
return parsePlaylist_pls(data, fileList, baseDir, rootDir);
break;
case wplPlaylist:
return parsePlaylist_wpl(data, fileList, baseDir, rootDir);
break;
default:
return false;
break;
}
}
bool FileAnalyzer::parsePlaylist_m3u(QFile &data, QStringList &fileList, const QDir &baseDir, const QDir &rootDir)
{
QByteArray line = data.readLine();
while(line.size() > 0)
{
QFileInfo filename1(QDir::fromNativeSeparators(QString::fromUtf8(line.constData(), line.size()).trimmed()));
QFileInfo filename2(QDir::fromNativeSeparators(QString::fromLatin1(line.constData(), line.size()).trimmed()));
filename1.setCaching(false);
filename2.setCaching(false);
if(!(filename1.filePath().startsWith("#") || filename2.filePath().startsWith("#")))
{
fixFilePath(filename1, baseDir, rootDir);
fixFilePath(filename2, baseDir, rootDir);
if(filename1.exists())
{
if(isPlaylist(filename1.canonicalFilePath()) == noPlaylist)
{
fileList << filename1.canonicalFilePath();
}
}
else if(filename2.exists())
{
if(isPlaylist(filename2.canonicalFilePath()) == noPlaylist)
{
fileList << filename2.canonicalFilePath();
}
}
}
line = data.readLine();
}
return true;
}
bool FileAnalyzer::parsePlaylist_pls(QFile &data, QStringList &fileList, const QDir &baseDir, const QDir &rootDir)
{
QRegExp plsEntry("File(\\d+)=(.+)", Qt::CaseInsensitive);
QByteArray line = data.readLine();
while(line.size() > 0)
{
bool flag = false;
QString temp1(QDir::fromNativeSeparators(QString::fromUtf8(line.constData(), line.size()).trimmed()));
QString temp2(QDir::fromNativeSeparators(QString::fromLatin1(line.constData(), line.size()).trimmed()));
if(!flag && plsEntry.indexIn(temp1) >= 0)
{
QFileInfo filename(QDir::fromNativeSeparators(plsEntry.cap(2)).trimmed());
filename.setCaching(false);
fixFilePath(filename, baseDir, rootDir);
if(filename.exists())
{
if(isPlaylist(filename.canonicalFilePath()) == noPlaylist)
{
fileList << filename.canonicalFilePath();
flag = true;
}
}
}
if(!flag && plsEntry.indexIn(temp2) >= 0)
{
QFileInfo filename(QDir::fromNativeSeparators(plsEntry.cap(2)).trimmed());
filename.setCaching(false);
fixFilePath(filename, baseDir, rootDir);
if(filename.exists())
{
if(isPlaylist(filename.canonicalFilePath()) == noPlaylist)
{
fileList << filename.canonicalFilePath();
flag = true;
}
}
}
line = data.readLine();
}
return true;
}
bool FileAnalyzer::parsePlaylist_wpl(QFile &data, QStringList &fileList, const QDir &baseDir, const QDir &rootDir)
{
QRegExp wplEntry("<(media|ref)[^<>]*(src|href)=\"([^\"]+)\"[^<>]*>", Qt::CaseInsensitive);
QByteArray line = data.readLine();
while(line.size() > 0)
{
bool flag = false;
QString temp1(QDir::fromNativeSeparators(QString::fromUtf8(line.constData(), line.size()).trimmed()));
QString temp2(QDir::fromNativeSeparators(QString::fromLatin1(line.constData(), line.size()).trimmed()));
if(!flag && wplEntry.indexIn(temp1) >= 0)
{
QFileInfo filename(QDir::fromNativeSeparators(wplEntry.cap(3)).trimmed());
filename.setCaching(false);
fixFilePath(filename, baseDir, rootDir);
if(filename.exists())
{
if(isPlaylist(filename.canonicalFilePath()) == noPlaylist)
{
fileList << filename.canonicalFilePath();
flag = true;
}
}
}
if(!flag && wplEntry.indexIn(temp2) >= 0)
{
QFileInfo filename(QDir::fromNativeSeparators(wplEntry.cap(3)).trimmed());
filename.setCaching(false);
fixFilePath(filename, baseDir, rootDir);
if(filename.exists())
{
if(isPlaylist(filename.canonicalFilePath()) == noPlaylist)
{
fileList << filename.canonicalFilePath();
flag = true;
}
}
}
line = data.readLine();
}
return true;
}
FileAnalyzer::playlist_t FileAnalyzer::isPlaylist(const QString &fileName)
{
QFileInfo file (fileName);
if(file.suffix().compare("m3u", Qt::CaseInsensitive) == 0)
{
return m3uPlaylist;
}
else if(file.suffix().compare("m3u8", Qt::CaseInsensitive) == 0)
{
return m3uPlaylist;
}
else if(file.suffix().compare("pls", Qt::CaseInsensitive) == 0)
{
return plsPlaylist;
}
else if(file.suffix().compare("asx", Qt::CaseInsensitive) == 0)
{
return wplPlaylist;
}
else if(file.suffix().compare("wpl", Qt::CaseInsensitive) == 0)
{
return wplPlaylist;
}
else
{
return noPlaylist;
}
}
void FileAnalyzer::fixFilePath(QFileInfo &filename, const QDir &baseDir, const QDir &rootDir)
{
if(filename.filePath().startsWith("/"))
{
while(filename.filePath().startsWith("/"))
{
filename.setFile(filename.filePath().mid(1));
}
filename.setFile(rootDir.filePath(filename.filePath()));
}
if(!filename.isAbsolute())
{
filename.setFile(baseDir.filePath(filename.filePath()));
}
}
////////////////////////////////////////////////////////////
// Public Functions
////////////////////////////////////////////////////////////
unsigned int FileAnalyzer::filesAccepted(void)
{
return m_filesAccepted;

View File

@ -27,6 +27,9 @@
#include <QStringList>
class AudioFileModel;
class QFile;
class QDir;
class QFileInfo;
////////////////////////////////////////////////////////////
// Splash Thread
@ -56,11 +59,26 @@ private:
sectionOther
};
enum playlist_t
{
noPlaylist,
m3uPlaylist,
plsPlaylist,
wplPlaylist
};
const AudioFileModel analyzeFile(const QString &filePath);
void updateInfo(AudioFileModel &audioFile, const QString &key, const QString &value);
void updateSection(const QString &section);
unsigned int parseYear(const QString &str);
unsigned int parseDuration(const QString &str);
bool importPlaylist(QStringList &fileList, const QString &playlistFile);
bool parsePlaylist_m3u(QFile &data, QStringList &fileList, const QDir &baseDir, const QDir &rootDir);
bool parsePlaylist_pls(QFile &data, QStringList &fileList, const QDir &baseDir, const QDir &rootDir);
bool parsePlaylist_wpl(QFile &data, QStringList &fileList, const QDir &baseDir, const QDir &rootDir);
playlist_t isPlaylist(const QString &fileName);
void fixFilePath(QFileInfo &filename, const QDir &baseDir, const QDir &rootDir);
QStringList m_inputFiles;
const QString m_mediaInfoBin_x86;