void XSPFParser::writeTrack(QXmlStreamWriter & xml, const MediaInfo & mediaInfo) { xml.writeStartElement(XSPF_TRACK); //Filename QUrl url(mediaInfo.fileName()); writeTextElement(xml, XSPF_LOCATION, url.toEncoded()); //Unique ID //FIXME not implemented yet //writeTextElement(xml, XSPF_IDENTIFIER, QString()); //Artist writeTextElement(xml, XSPF_CREATOR, mediaInfo.metadataValue(MediaInfo::Artist)); //Album writeTextElement(xml, XSPF_ALBUM, mediaInfo.metadataValue(MediaInfo::Album)); //Track number writeTextElement(xml, XSPF_TRACKNUM, mediaInfo.metadataValue(MediaInfo::TrackNumber)); //Title writeTextElement(xml, XSPF_TITLE, mediaInfo.metadataValue(MediaInfo::Title)); //Comment writeTextElement(xml, XSPF_ANNOTATION, mediaInfo.metadataValue(MediaInfo::Comment)); //Length writeIntElement(xml, XSPF_DURATION, mediaInfo.lengthMilliseconds()); //Album art URL //FIXME not implemented yet //writeTextElement(xml, XSPF_IMAGE, mediaInfo.metadataValue(MediaInfo::AlbumArt)); //URL of the original web page writeTextElement(xml, XSPF_INFO, mediaInfo.metadataValue(MediaInfo::URL)); xml.writeStartElement(XSPF_EXTENSION); xml.writeAttribute(XSPF_APPLICATION, XSPF_QUARKPLAYER_NAMESPACE); writeTextElementWithNamespace(xml, XSPF_QUARKPLAYER_NAMESPACE, XSPF_QUARKPLAYER_CUE_START_INDEX, mediaInfo.cueStartIndexFormatted()); writeTextElementWithNamespace(xml, XSPF_QUARKPLAYER_NAMESPACE, XSPF_QUARKPLAYER_CUE_END_INDEX, mediaInfo.cueEndIndexFormatted()); writeTextElementWithNamespace(xml, XSPF_QUARKPLAYER_NAMESPACE, XSPF_QUARKPLAYER_YEAR, mediaInfo.metadataValue(MediaInfo::Year)); writeTextElementWithNamespace(xml, XSPF_QUARKPLAYER_NAMESPACE, XSPF_QUARKPLAYER_GENRE, mediaInfo.metadataValue(MediaInfo::Genre)); xml.writeEndElement(); //extension xml.writeEndElement(); //track }
void CUEParser::load() { QTime timeElapsed; timeElapsed.start(); _stop = false; QList<MediaInfo> files; qDebug() << __FUNCTION__ << "Playlist:" << _filename; //See http://regexlib.com/DisplayPatterns.aspx //REM GENRE "Alternative rock" //REM GENRE Pop static QRegExp rx_genre("^REM GENRE (.*)$"); //REM DATE 1994 static QRegExp rx_date("^REM DATE (\\d+)$"); //PERFORMER "Weezer" static QRegExp rx_root_performer("^PERFORMER \"(.*)\"$"); //TITLE "Weezer (The Blue Album)" static QRegExp rx_root_title("^TITLE \"(.*)\"$"); //FILE "01. My Name Is Jonas - [Weezer] .wav" WAVE static QRegExp rx_file("^FILE \"(.*)\""); // TRACK 01 AUDIO static QRegExp rx_track("^ TRACK (\\d+)"); // TITLE "No One Else" static QRegExp rx_title("^ TITLE \"(.*)\"$"); // PERFORMER "Weezer" static QRegExp rx_performer("^ PERFORMER \"(.*)\"$"); // INDEX 01 00:00:00 static QRegExp rx_index("^ INDEX 01 (.*)$"); QFile file(_filename); if (file.open(QIODevice::ReadOnly)) { QString path(QFileInfo(_filename).path()); QTextStream stream(&file); MediaInfo mediaInfo; //Root elements QString genre; QString date; QString albumArtist; QString album; /// QString filename; while (!stream.atEnd() && !_stop) { //Line of text, don't use trimmed() //since CUE sheet files contain indentation spaces QString line(stream.readLine()); if (line.isEmpty()) { //Do nothing } else if (rx_genre.indexIn(line) != -1) { genre = rx_genre.cap(1); } else if (rx_date.indexIn(line) != -1) { date = rx_date.cap(1); } else if (rx_root_performer.indexIn(line) != -1) { albumArtist = rx_root_performer.cap(1); } else if (rx_root_title.indexIn(line) != -1) { album = rx_root_title.cap(1); } else if (rx_file.indexIn(line) != -1) { filename = rx_file.cap(1); } else if (rx_track.indexIn(line) != -1) { QString track(rx_track.cap(1)); mediaInfo.insertMetadata(MediaInfo::TrackNumber, track); } else if (rx_title.indexIn(line) != -1) { QString title(rx_title.cap(1)); mediaInfo.insertMetadata(MediaInfo::Title, title); } else if (rx_performer.indexIn(line) != -1) { QString performer(rx_performer.cap(1)); mediaInfo.insertMetadata(MediaInfo::Artist, performer); } else if (rx_index.indexIn(line) != -1) { QString index(rx_index.cap(1)); mediaInfo.setCueStartIndex(index); if (!files.isEmpty()) { //Now we know the CUE end index from the previous media files.last().setCueEndIndex(index); } mediaInfo.insertMetadata(MediaInfo::Genre, genre); mediaInfo.insertMetadata(MediaInfo::Year, date); mediaInfo.insertMetadata(MediaInfo::AlbumArtist, albumArtist); mediaInfo.insertMetadata(MediaInfo::Album, album); bool isUrl = MediaInfo::isUrl(filename); mediaInfo.setUrl(isUrl); if (isUrl) { mediaInfo.setFileName(filename); } else { mediaInfo.setFileName(Util::canonicalFilePath(path, filename)); } if (!mediaInfo.fileName().isEmpty()) { //Add file to the list of files files << mediaInfo; //Clear the MediaInfo for the next lines mediaInfo.clear(); if (files.size() > FILES_FOUND_LIMIT) { //Emits the signal every FILES_FOUND_LIMIT files found emit filesFound(files); files.clear(); } } } else { //Syntax error } } } file.close(); if (!files.isEmpty()) { //Emits the signal for the remaining files found (< FILES_FOUND_LIMIT) emit filesFound(files); } //Emits the last signal emit finished(timeElapsed.elapsed()); }
void XSPFParser::load() { QTime timeElapsed; timeElapsed.start(); _stop = false; QList<MediaInfo> files; qDebug() << __FUNCTION__ << "Playlist:" << _filename; QFile file(_filename); if (file.open(QIODevice::ReadOnly)) { MediaInfo mediaInfo; QXmlStreamReader xml(&file); while (!xml.atEnd() && !_stop) { xml.readNext(); switch (xml.tokenType()) { case QXmlStreamReader::StartElement: { QString element(xml.name().toString()); if (element == XSPF_TRACK) { readTrack(xml, mediaInfo); if (!mediaInfo.fileName().isEmpty()) { //Add file to the list of files files << mediaInfo; //Clear the MediaInfo mediaInfo.clear(); if (files.size() > FILES_FOUND_LIMIT) { //Emits the signal every FILES_FOUND_LIMIT files found emit filesFound(files); files.clear(); } } } //Otherwise won't read the track end element break; } } } if (xml.hasError()) { qCritical() << __FUNCTION__ << "Error:" << xml.errorString() << "line:" << xml.lineNumber() << "column:" << xml.columnNumber(); } } file.close(); if (!files.isEmpty()) { //Emits the signal for the remaining files found (< FILES_FOUND_LIMIT) emit filesFound(files); } //Emits the last signal emit finished(timeElapsed.elapsed()); }