diff --git a/utils/cuesheetwriter.cpp b/utils/cuesheetwriter.cpp index 145d011..7e6c622 100644 --- a/utils/cuesheetwriter.cpp +++ b/utils/cuesheetwriter.cpp @@ -1,98 +1,98 @@ /* AUDEX CDDA EXTRACTOR * Copyright (C) 2007-2015 Marco Nelles (audex@maniatek.com) * * * 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 3 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, see . */ #include "cuesheetwriter.h" CueSheetWriter::CueSheetWriter(CDDAModel *model) { this->model = model; } CueSheetWriter::~CueSheetWriter() { } QStringList CueSheetWriter::cueSheet(const QString& binFilename) const { QStringList result; result << "REM cue file written by Audex Version " AUDEX_VERSION; result << QString("REM GENRE \"%1\"").arg(model->genre()); result << QString("REM DATE \"%1\"").arg(model->year()); result << QString("PERFORMER \"%1\"").arg(model->artist()); result << QString("TITLE \"%1\"").arg(model->title()); QFileInfo info(binFilename); result << QString("FILE \"%1\" %2").arg(info.fileName()).arg(p_filetype(binFilename)); const QList dsig = model->discSignature(); int leadin = 0; for (int i = 0; i < dsig.count()-1; ++i) { if (!model->isAudioTrack(i+1)) continue; result << QString(" TRACK %1 AUDIO").arg(i+1, 2, 10, QChar('0')); result << QString(" PERFORMER \"%1\"").arg(model->data(model->index(i, CDDA_MODEL_COLUMN_ARTIST_INDEX)).toString()); result << QString(" TITLE \"%1\"").arg(model->data(model->index(i, CDDA_MODEL_COLUMN_TITLE_INDEX)).toString()); if ((i == 0) && (dsig.at(i) > 0)) leadin = dsig.at(i); float l = (float)(dsig.at(i)-leadin) / 75.0f; int min = (int)l / 60; int sec = (int)l % 60; int frames = (dsig.at(i)-leadin) - (((min*60)+sec)*75); result << QString(" INDEX 01 %1:%2:%3").arg(min, 2, 10, QChar('0')).arg(sec, 2, 10, QChar('0')).arg(frames, 2, 10, QChar('0')); } return result; } QStringList CueSheetWriter::cueSheet(const QStringList& filenames) const { QStringList result; result << "REM cue file written by Audex Version " AUDEX_VERSION; result << QString("REM GENRE \"%1\"").arg(model->genre()); result << QString("REM DATE \"%1\"").arg(model->year()); result << QString("PERFORMER \"%1\"").arg(model->artist()); result << QString("TITLE \"%1\"").arg(model->title()); for (int i = 0; i < filenames.count(); ++i) { QFileInfo info(filenames.at(i)); result << QString("FILE \"%1\" %2").arg(info.fileName()).arg(p_filetype(filenames.at(i))); result << QString(" TRACK %1 AUDIO").arg(i+1, 2, 10, QChar('0')); result << QString(" PERFORMER \"%1\"").arg(model->data(model->index(i, CDDA_MODEL_COLUMN_ARTIST_INDEX)).toString()); result << QString(" TITLE \"%1\"").arg(model->data(model->index(i, CDDA_MODEL_COLUMN_TITLE_INDEX)).toString()); result << QString(" INDEX 01 00:00:00"); } return result; } QString CueSheetWriter::p_filetype(const QString& filename) const { QString result = "WAVE"; - if ((filename.toLower().endsWith("aiff")) || (filename.toLower().endsWith("aif"))) result = "AIFF"; - else if (filename.toLower().endsWith("mp3")) result = "MP3"; + if ((filename.toLower().endsWith(QLatin1String("aiff"))) || (filename.toLower().endsWith(QLatin1String("aif")))) result = "AIFF"; + else if (filename.toLower().endsWith(QLatin1String("mp3"))) result = "MP3"; return result; } diff --git a/utils/encoderassistant.cpp b/utils/encoderassistant.cpp index f4c6537..049e647 100644 --- a/utils/encoderassistant.cpp +++ b/utils/encoderassistant.cpp @@ -1,496 +1,496 @@ /* AUDEX CDDA EXTRACTOR * Copyright (C) 2007-2015 Marco Nelles (audex@maniatek.com) * * * 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 3 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, see . */ #include "encoderassistant.h" long makeVersionNumber(int major, int minor, int patch) { long versionNumber= ((major & 0xFF) << 16) | ((minor & 0xFF) << 8) | (patch & 0xFF); return versionNumber; } const QString EncoderAssistant::name(const EncoderAssistant::Encoder encoder) { switch (encoder) { case EncoderAssistant::LAME : return ENCODER_LAME_NAME; case EncoderAssistant::OGGENC : return ENCODER_OGGENC_NAME; case EncoderAssistant::FLAC : return ENCODER_FLAC_NAME; case EncoderAssistant::FAAC : return ENCODER_FAAC_NAME; case EncoderAssistant::WAVE : return ENCODER_WAVE_NAME; case EncoderAssistant::CUSTOM : return ENCODER_CUSTOM_NAME; default : return ""; } return ""; } const QString EncoderAssistant::encoderName(const Encoder encoder) { switch (encoder) { case EncoderAssistant::LAME : return ENCODER_LAME_ENCODER_NAME; case EncoderAssistant::OGGENC : return ENCODER_OGGENC_ENCODER_NAME; case EncoderAssistant::FLAC : return ENCODER_FLAC_ENCODER_NAME; case EncoderAssistant::FAAC : return ENCODER_FAAC_ENCODER_NAME; case EncoderAssistant::WAVE : return ENCODER_WAVE_ENCODER_NAME; case EncoderAssistant::CUSTOM : return ENCODER_CUSTOM_ENCODER_NAME; default : return ""; } return ""; } const QString EncoderAssistant::icon(const EncoderAssistant::Encoder encoder) { switch (encoder) { case EncoderAssistant::LAME : return ENCODER_LAME_ICON; case EncoderAssistant::OGGENC : return ENCODER_OGGENC_ICON; case EncoderAssistant::FLAC : return ENCODER_FLAC_ICON; case EncoderAssistant::FAAC : return ENCODER_FAAC_ICON; case EncoderAssistant::WAVE : return ENCODER_WAVE_ICON; case EncoderAssistant::CUSTOM : return ENCODER_CUSTOM_ICON; default : return ""; } return ""; } bool EncoderAssistant::available(const EncoderAssistant::Encoder encoder) { switch (encoder) { case EncoderAssistant::LAME : return (KProcess::execute(ENCODER_LAME_BIN, QStringList() << ENCODER_LAME_VERSION_PARA)==0); case EncoderAssistant::OGGENC : return (KProcess::execute(ENCODER_OGGENC_BIN, QStringList() << ENCODER_OGGENC_VERSION_PARA)==0); case EncoderAssistant::FLAC : return (KProcess::execute(ENCODER_FLAC_BIN, QStringList() << ENCODER_FLAC_VERSION_PARA)==0); case EncoderAssistant::FAAC : return (KProcess::execute(ENCODER_FAAC_BIN, QStringList() << ENCODER_FAAC_VERSION_PARA)==1); case EncoderAssistant::WAVE : return (KProcess::execute(ENCODER_WAVE_BIN, QStringList() << ENCODER_WAVE_VERSION_PARA)==0); case EncoderAssistant::CUSTOM : return true; default : return false; } return false; } bool EncoderAssistant::canEmbedCover(const Encoder encoder, int *maxCoverSize) { switch (encoder) { case EncoderAssistant::LAME : if (maxCoverSize) *maxCoverSize = ENCODER_LAME_MAX_EMBED_COVER_SIZE; return true; case EncoderAssistant::OGGENC : case EncoderAssistant::FLAC : return true; case EncoderAssistant::FAAC : case EncoderAssistant::WAVE : case EncoderAssistant::CUSTOM : default : break; } if (maxCoverSize) *maxCoverSize = 0; return false; } const QString EncoderAssistant::version(const EncoderAssistant::Encoder encoder) { KProcess process; process.setOutputChannelMode(KProcess::SeparateChannels); process.setReadChannel(KProcess::StandardError); switch (encoder) { case EncoderAssistant::LAME : process.setShellCommand(QString(ENCODER_LAME_BIN)+' '+QString(ENCODER_LAME_VERSION_PARA)); break; case EncoderAssistant::OGGENC : process.setShellCommand(QString(ENCODER_OGGENC_BIN)+' '+QString(ENCODER_OGGENC_VERSION_PARA)); break; case EncoderAssistant::FLAC : process.setShellCommand(QString(ENCODER_FLAC_BIN)+' '+QString(ENCODER_FLAC_VERSION_PARA)); break; case EncoderAssistant::FAAC : process.setShellCommand(QString(ENCODER_FAAC_BIN)+' '+QString(ENCODER_FAAC_VERSION_PARA)); break; case EncoderAssistant::WAVE : return ""; case EncoderAssistant::CUSTOM : return ""; default : return ""; } process.start(); if (!process.waitForFinished()) return ""; QByteArray rawoutput = process.readAllStandardError(); if (rawoutput.size() == 0) rawoutput = process.readAllStandardOutput(); QString output(rawoutput); QStringList list = output.trimmed().split('\n'); if (list.count()==0) return ""; QStringList words = list[0].split(' '); if (words.count()==0) return ""; switch (encoder) { case EncoderAssistant::LAME : if ((words.contains("version")) && (words.indexOf("version")+1 0) { major = version[0].toUInt(); versionNumber = (major & 0xFF) << 16; } if (version.count() > 1) { minor = version[1].toUInt(); versionNumber = versionNumber | (minor & 0xFF) << 8; } if (version.count() > 2) { patch = version[2].toUInt(); versionNumber = versionNumber | (patch & 0xFF); } } break; case EncoderAssistant::WAVE : case EncoderAssistant::CUSTOM : default : ; } return versionNumber; } const QString EncoderAssistant::pattern(const EncoderAssistant::Encoder encoder, const Parameters& parameters) { switch (encoder) { case EncoderAssistant::LAME : { int preset = parameters.valueToInt(ENCODER_LAME_PRESET_KEY, ENCODER_LAME_PRESET); bool cbr = parameters.valueToBool(ENCODER_LAME_CBR_KEY); int bitrate = parameters.valueToInt(ENCODER_LAME_BITRATE_KEY, ENCODER_LAME_BITRATE); bool embed_cover = parameters.valueToBool(ENCODER_LAME_EMBED_COVER_KEY); QString cmd = ENCODER_LAME_BIN; switch (preset) { case 0 : cmd += " --preset medium"; break; case 1 : cmd += " --preset standard"; break; case 2 : cmd += " --preset extreme"; break; case 3 : cmd += " --preset insane"; break; case 4 : cmd += QString(" --preset")+(cbr?QString(" cbr"):QString())+QString(" %1").arg(bitrate); break; default : cmd += " --preset standard"; } QString v = EncoderAssistant::version(EncoderAssistant::LAME); - if ((v.startsWith("3.95")) || (v.startsWith("3.96")) || (v.startsWith("3.97"))) { + if ((v.startsWith(QLatin1String("3.95"))) || (v.startsWith(QLatin1String("3.96"))) || (v.startsWith(QLatin1String("3.97")))) { cmd += QString(" --vbr-new"); } //if we have eyeD3, use this for tagging as lame can't handle unicode if (KProcess::execute(ENCODER_LAME_HELPER_TAG, QStringList() << ENCODER_LAME_HELPER_TAG_VERSION_PARA) == 0) { cmd += QString::fromUtf8(" $" VAR_INPUT_FILE" $" VAR_OUTPUT_FILE); cmd += QString::fromUtf8(" && eyeD3 -t \"$" VAR_TRACK_TITLE"\" -a \"$" VAR_TRACK_ARTIST"\" --set-text-frame=TPE2:\"$" VAR_ALBUM_ARTIST"\" -A \"$" VAR_ALBUM_TITLE \ "\" -Y \"$" VAR_DATE"\" -n $" VAR_TRACK_NO" -N $" VAR_NO_OF_TRACKS" --set-text-frame=\"TCON:$" VAR_GENRE"\" "\ "--set-text-frame=TSSE:\"$" VAR_AUDEX" / Encoder $" VAR_ENCODER"\" ${" VAR_CD_NO" pre=\"--set-text-frame=TPOS:\"}"); if (embed_cover) { cmd += QString::fromUtf8(" ${" VAR_COVER_FILE" pre=\"--add-image=\" post=\":FRONT_COVER\"}"); } cmd += QString::fromUtf8(" --set-encoding=latin1 $" VAR_OUTPUT_FILE" && eyeD3 --to-v2.3 $" VAR_OUTPUT_FILE); } else { if (embed_cover) { cmd += QString::fromUtf8(" ${" VAR_COVER_FILE" pre=\"--ti \"}"); } cmd += QString::fromUtf8(" --add-id3v2 --id3v2-only --ignore-tag-errors --tt \"$" VAR_TRACK_TITLE"\" --ta \"$" VAR_TRACK_ARTIST \ "\" --tl \"$" VAR_ALBUM_TITLE"\" --ty \"$" VAR_DATE"\" --tn \"$" VAR_TRACK_NO"/$" VAR_NO_OF_TRACKS"\" --tc \"$" VAR_AUDEX" / Encoder $" VAR_ENCODER"\" "\ "--tg \"$" VAR_GENRE"\" ${" VAR_CD_NO" pre=\"--tv TPOS=\"}"\ " $" VAR_INPUT_FILE" $" VAR_OUTPUT_FILE); } return cmd; } case EncoderAssistant::OGGENC : { double quality = parameters.valueToDouble(ENCODER_OGGENC_QUALITY_KEY, ENCODER_OGGENC_QUALITY); bool min_bitrate = parameters.valueToBool(ENCODER_OGGENC_MINBITRATE_KEY); int min_bitrate_value = parameters.valueToInt(ENCODER_OGGENC_MINBITRATE_VALUE_KEY, ENCODER_OGGENC_MINBITRATE_VALUE); bool max_bitrate = parameters.valueToBool(ENCODER_OGGENC_MAXBITRATE_KEY); int max_bitrate_value = parameters.valueToInt(ENCODER_OGGENC_MAXBITRATE_VALUE_KEY, ENCODER_OGGENC_MAXBITRATE_VALUE); QString cmd = ENCODER_OGGENC_BIN; cmd += QString(" -q %1").arg(quality, 0, 'f', 2); if (min_bitrate) { cmd += QString(" -m %1").arg(min_bitrate_value); } if (max_bitrate) { cmd += QString(" -M %1").arg(max_bitrate_value); } cmd += QString::fromUtf8(" -c \"Artist=$" VAR_TRACK_ARTIST"\" -c \"Title=$" VAR_TRACK_TITLE"\" -c \"Album=$" VAR_ALBUM_TITLE\ "\" -c \"Date=$" VAR_DATE"\" -c \"Tracknumber=$" VAR_TRACK_NO"\" -c \"Genre=$" VAR_GENRE\ "\" ${" VAR_CD_NO" pre=\"-c Discnumber=\"}"\ " -o $" VAR_OUTPUT_FILE" $" VAR_INPUT_FILE); return cmd; } case EncoderAssistant::FLAC : { int compression = parameters.valueToInt(ENCODER_FLAC_COMPRESSION_KEY, ENCODER_FLAC_COMPRESSION); bool embed_cover = parameters.valueToBool(ENCODER_FLAC_EMBED_COVER_KEY); QString cmd = ENCODER_FLAC_BIN; if (embed_cover) { long versionNumber=EncoderAssistant::versionNumber(EncoderAssistant::FLAC); if (versionNumber >= makeVersionNumber(1,1,3) ) { cmd += QString::fromUtf8(" --picture=\\|\\|\\|\\|$" VAR_COVER_FILE); } } cmd += QString(" -%1").arg(compression); cmd += QString::fromUtf8(" -T Artist=\"$" VAR_TRACK_ARTIST"\" -T Title=\"$" VAR_TRACK_TITLE"\" -T Album=\"$" VAR_ALBUM_TITLE\ "\" -T Date=\"$" VAR_DATE"\" -T Tracknumber=\"$" VAR_TRACK_NO"\" -T Genre=\"$" VAR_GENRE\ "\" -o $" VAR_OUTPUT_FILE" $" VAR_INPUT_FILE); return cmd; } case EncoderAssistant::FAAC : { int quality = parameters.valueToInt(ENCODER_FAAC_QUALITY_KEY, ENCODER_FAAC_QUALITY); QString cmd = ENCODER_FAAC_BIN; cmd += QString(" -q %1").arg(quality); cmd += QString::fromUtf8(" --title \"$" VAR_TRACK_TITLE"\" --artist \"$" VAR_TRACK_ARTIST"\" --album \"$" VAR_ALBUM_TITLE\ "\" --year \"$" VAR_DATE"\" --track $" VAR_TRACK_NO" ${" VAR_CD_NO" pre=\"--disc \"} --genre \"$" VAR_GENRE\ "\" -o $" VAR_OUTPUT_FILE" $" VAR_INPUT_FILE); return cmd; } case EncoderAssistant::WAVE : { return QString(ENCODER_WAVE_BIN)+" $" VAR_INPUT_FILE" $" VAR_OUTPUT_FILE; } case EncoderAssistant::CUSTOM : { return parameters.value(ENCODER_CUSTOM_COMMAND_PATTERN_KEY, ENCODER_CUSTOM_COMMAND_PATTERN); } default : ; } return ""; } Parameters EncoderAssistant::stdParameters(const Encoder encoder, const Quality quality) { Parameters parameters; switch (encoder) { case EncoderAssistant::LAME : switch (quality) { case NORMAL : parameters.setValue(ENCODER_LAME_PRESET_KEY, ENCODER_LAME_PRESET); parameters.setValue(ENCODER_LAME_EMBED_COVER_KEY, ENCODER_LAME_EMBED_COVER); parameters.setValue(ENCODER_LAME_BITRATE_KEY, ENCODER_LAME_BITRATE); parameters.setValue(ENCODER_LAME_EMBED_COVER_KEY, ENCODER_LAME_EMBED_COVER); break; case MOBILE : parameters.setValue(ENCODER_LAME_PRESET_KEY, ENCODER_LAME_PRESET_M); parameters.setValue(ENCODER_LAME_EMBED_COVER_KEY, ENCODER_LAME_EMBED_COVER_M); parameters.setValue(ENCODER_LAME_BITRATE_KEY, ENCODER_LAME_BITRATE_M); parameters.setValue(ENCODER_LAME_EMBED_COVER_KEY, ENCODER_LAME_EMBED_COVER_M); break; case EXTREME : parameters.setValue(ENCODER_LAME_PRESET_KEY, ENCODER_LAME_PRESET_X); parameters.setValue(ENCODER_LAME_EMBED_COVER_KEY, ENCODER_LAME_EMBED_COVER_X); parameters.setValue(ENCODER_LAME_BITRATE_KEY, ENCODER_LAME_BITRATE_X); parameters.setValue(ENCODER_LAME_EMBED_COVER_KEY, ENCODER_LAME_EMBED_COVER_X); break; } break; case EncoderAssistant::OGGENC : switch (quality) { case NORMAL : parameters.setValue(ENCODER_OGGENC_QUALITY_KEY, ENCODER_OGGENC_QUALITY); parameters.setValue(ENCODER_OGGENC_MINBITRATE_KEY, ENCODER_OGGENC_MINBITRATE); parameters.setValue(ENCODER_OGGENC_MINBITRATE_VALUE_KEY, ENCODER_OGGENC_MINBITRATE_VALUE); parameters.setValue(ENCODER_OGGENC_MAXBITRATE_KEY, ENCODER_OGGENC_MAXBITRATE); parameters.setValue(ENCODER_OGGENC_MAXBITRATE_VALUE_KEY, ENCODER_OGGENC_MAXBITRATE_VALUE); break; case MOBILE : parameters.setValue(ENCODER_OGGENC_QUALITY_KEY, ENCODER_OGGENC_QUALITY_M); parameters.setValue(ENCODER_OGGENC_MINBITRATE_KEY, ENCODER_OGGENC_MINBITRATE_M); parameters.setValue(ENCODER_OGGENC_MINBITRATE_VALUE_KEY, ENCODER_OGGENC_MINBITRATE_VALUE_M); parameters.setValue(ENCODER_OGGENC_MAXBITRATE_KEY, ENCODER_OGGENC_MAXBITRATE_M); parameters.setValue(ENCODER_OGGENC_MAXBITRATE_VALUE_KEY, ENCODER_OGGENC_MAXBITRATE_VALUE_M); break; case EXTREME : parameters.setValue(ENCODER_OGGENC_QUALITY_KEY, ENCODER_OGGENC_QUALITY_X); parameters.setValue(ENCODER_OGGENC_MINBITRATE_KEY, ENCODER_OGGENC_MINBITRATE_X); parameters.setValue(ENCODER_OGGENC_MINBITRATE_VALUE_KEY, ENCODER_OGGENC_MINBITRATE_VALUE_X); parameters.setValue(ENCODER_OGGENC_MAXBITRATE_KEY, ENCODER_OGGENC_MAXBITRATE_X); parameters.setValue(ENCODER_OGGENC_MAXBITRATE_VALUE_KEY, ENCODER_OGGENC_MAXBITRATE_VALUE_X); break; } break; case EncoderAssistant::FLAC : parameters.setValue(ENCODER_FLAC_COMPRESSION_KEY, ENCODER_FLAC_COMPRESSION); parameters.setValue(ENCODER_FLAC_EMBED_COVER_KEY, ENCODER_FLAC_EMBED_COVER); break; case EncoderAssistant::FAAC : switch (quality) { case NORMAL : parameters.setValue(ENCODER_FAAC_QUALITY_KEY, ENCODER_FAAC_QUALITY); break; case MOBILE : parameters.setValue(ENCODER_FAAC_QUALITY_KEY, ENCODER_FAAC_QUALITY_M); break; case EXTREME : parameters.setValue(ENCODER_FAAC_QUALITY_KEY, ENCODER_FAAC_QUALITY_X); break; } break; case EncoderAssistant::WAVE : case EncoderAssistant::CUSTOM : default : ; } return parameters; } const QMap EncoderAssistant::encoderList() { QMap encoders; encoders[(int)EncoderAssistant::LAME] = ENCODER_LAME_NAME; encoders[(int)EncoderAssistant::OGGENC] = ENCODER_OGGENC_NAME; encoders[(int)EncoderAssistant::FLAC] = ENCODER_FLAC_NAME; encoders[(int)EncoderAssistant::FAAC] = ENCODER_FAAC_NAME; encoders[(int)EncoderAssistant::WAVE] = ENCODER_WAVE_NAME; encoders[(int)EncoderAssistant::CUSTOM] = ENCODER_CUSTOM_NAME; return encoders; } const QMap EncoderAssistant::availableEncoderNameList() { QMap encoders; if (EncoderAssistant::available(EncoderAssistant::LAME)) encoders[(int)EncoderAssistant::LAME] = ENCODER_LAME_NAME; if (EncoderAssistant::available(EncoderAssistant::OGGENC)) encoders[(int)EncoderAssistant::OGGENC] = ENCODER_OGGENC_NAME; if (EncoderAssistant::available(EncoderAssistant::FLAC)) encoders[(int)EncoderAssistant::FLAC] = ENCODER_FLAC_NAME; if (EncoderAssistant::available(EncoderAssistant::FAAC)) encoders[(int)EncoderAssistant::FAAC] = ENCODER_FAAC_NAME; if (EncoderAssistant::available(EncoderAssistant::WAVE)) encoders[(int)EncoderAssistant::WAVE] = ENCODER_WAVE_NAME; if (EncoderAssistant::available(EncoderAssistant::CUSTOM)) encoders[(int)EncoderAssistant::CUSTOM] = ENCODER_CUSTOM_NAME; return encoders; } const QMap EncoderAssistant::availableEncoderNameListWithVersions() { QMap encoders; if (EncoderAssistant::available(EncoderAssistant::LAME)) encoders[(int)EncoderAssistant::LAME] = ENCODER_LAME_NAME+' '+version(LAME); if (EncoderAssistant::available(EncoderAssistant::OGGENC)) encoders[(int)EncoderAssistant::OGGENC] = ENCODER_OGGENC_NAME+' '+version(OGGENC); if (EncoderAssistant::available(EncoderAssistant::FLAC)) encoders[(int)EncoderAssistant::FLAC] = ENCODER_FLAC_NAME+' '+version(FLAC); if (EncoderAssistant::available(EncoderAssistant::FAAC)) encoders[(int)EncoderAssistant::FAAC] = ENCODER_FAAC_NAME+' '+version(FAAC); if (EncoderAssistant::available(EncoderAssistant::WAVE)) encoders[(int)EncoderAssistant::WAVE] = ENCODER_WAVE_NAME+' '+version(WAVE); if (EncoderAssistant::available(EncoderAssistant::CUSTOM)) encoders[(int)EncoderAssistant::CUSTOM] = ENCODER_CUSTOM_NAME+' '+version(CUSTOM); return encoders; } diff --git a/utils/playlist.cpp b/utils/playlist.cpp index 1d52fb6..232cc0d 100644 --- a/utils/playlist.cpp +++ b/utils/playlist.cpp @@ -1,405 +1,405 @@ /* AUDEX CDDA EXTRACTOR * Copyright (C) 2007-2015 Marco Nelles (audex@maniatek.com) * * * 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 3 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, see . */ #include "playlist.h" Playlist::Playlist() { } Playlist::Playlist(const QByteArray& playlist) { addPlaylist(playlist); } Playlist::~Playlist() { } void Playlist::addPlaylist(const QByteArray& playlist) { QString format = p_playlist_format(playlist); if (format == "m3u") { p_add_M3U(playlist); } else if (format == "pls") { p_add_PLS(playlist); } else if (format == "xspf") { p_add_XSPF(playlist); } } void Playlist::clear() { p_playlist.clear(); } void Playlist::appendItem(const PlaylistItem& item) { p_playlist.append(item); } QByteArray Playlist::toM3U(const QString& playlistPath, const bool utf8) const { QStringList playlist; playlist.append("#EXTM3U"); for (int i = 0; i < p_playlist.count(); ++i) { PlaylistItem pi = p_playlist[i]; if (pi.filename().isEmpty()) continue; if (!pi.artist().isEmpty()) { playlist.append(QString("#EXTINF:%1,%2 - %3").arg(pi.length()).arg(pi.artist()).arg(pi.title())); } else { playlist.append(QString("#EXTINF:%1,%2").arg(pi.length()).arg(pi.title())); } if (!playlistPath.isEmpty()) { QDir dir(playlistPath); playlist.append(dir.relativeFilePath(pi.filename())); } else { playlist.append(pi.filename()); } } if (utf8) return playlist.join("\n").append("\n").toUtf8(); else return playlist.join("\n").append("\n").toLatin1(); } QByteArray Playlist::toPLS(const QString& playlistPath, const bool utf8) const { QStringList playlist; playlist.append("[Playlist]"); int j = 0; for (int i = 0; i < p_playlist.count(); ++i) { PlaylistItem pi = p_playlist[i]; if (pi.filename().isEmpty()) continue; ++j; if (!playlistPath.isEmpty()) { QDir dir(playlistPath); playlist.append(QString("File%1=%2").arg(i+1).arg(dir.relativeFilePath(pi.filename()))); } else { playlist.append(QString("File%1=%2").arg(i+1).arg(pi.filename())); } if (!pi.artist().isEmpty()) { playlist.append(QString("Title%1=%2 - %3").arg(i+1).arg(pi.artist()).arg(pi.title())); } else { playlist.append(QString("Title%1=%2").arg(i+1).arg(pi.title())); } playlist.append(QString("Length%1=%2").arg(i+1).arg(pi.length())); } playlist.append(QString("NumberOfEntries=%1").arg(j)); playlist.append(QString("Version=2")); if (utf8) return playlist.join("\n").append("\n").toUtf8(); else return playlist.join("\n").append("\n").toLatin1(); } QByteArray Playlist::toXSPF() const { QDomDocument doc; QDomElement root = doc.createElement("playlist"); root.setAttribute("version", "1"); root.setAttribute("xmlns", "http://xspf.org/ns/0"); QDomElement creator = doc.createElement("creator"); QDomText text = doc.createTextNode("audex"); creator.appendChild(text); root.appendChild(creator); QDomElement tracklist = doc.createElement("trackList"); int j = 0; for (int i = 0; i < p_playlist.count(); ++i) { PlaylistItem pi = p_playlist[i]; if (pi.filename().isEmpty()) continue; ++j; QDomElement track = doc.createElement("track"); QDomElement ch = doc.createElement("location"); QDomText text = doc.createTextNode(pi.filename()); ch.appendChild(text); track.appendChild(ch); if (!pi.artist().isEmpty()) { ch = doc.createElement("creator"); text = doc.createTextNode(pi.artist()); ch.appendChild(text); track.appendChild(ch); } ch = doc.createElement("title"); text = doc.createTextNode(pi.title()); ch.appendChild(text); track.appendChild(ch); ch = doc.createElement("trackNum"); text = doc.createTextNode(QString::number(j)); ch.appendChild(text); track.appendChild(ch); if (pi.length() > 0) { ch = doc.createElement("duration"); text = doc.createTextNode(QString::number(pi.length()*1000)); ch.appendChild(text); track.appendChild(ch); } tracklist.appendChild(track); } root.appendChild(tracklist); doc.appendChild(root); QByteArray xml_header("\n"); return doc.toByteArray().prepend(xml_header); } const QString Playlist::p_playlist_format(const QByteArray& playlist) { if (playlist.contains("#EXTM3U") || playlist.contains("#EXTINF")) return "m3u"; if (playlist.toLower().contains("[playlist]")) return "pls"; if (playlist.contains(" items; while (!line.isNull()) { int equals = line.indexOf('='); QString key = line.left(equals).toLower(); QString value = line.mid(equals + 1); QRegExp n_re("\\d+$"); n_re.indexIn(key); int n = n_re.cap(0).toInt(); - if (key.startsWith("file")) + if (key.startsWith(QLatin1String("file"))) { items[n].setFilename(value); } - else if (key.startsWith("title")) + else if (key.startsWith(QLatin1String("title"))) { items[n].setTitle(value); } - else if (key.startsWith("length")) + else if (key.startsWith(QLatin1String("length"))) { bool ok; int seconds = value.toInt(&ok); if (ok) items[n].setLength(seconds); } line = stream.readLine().trimmed(); } QMap::const_iterator i = items.constBegin(); while (i != items.constEnd()) { p_playlist.append(i.value()); ++i; } } void Playlist::p_add_XSPF(const QByteArray& playlist) { QDomDocument doc; QString errorMsg; int errorCol; int errorRow; if (!doc.setContent(QString(playlist), &errorMsg, &errorRow, &errorCol)) return; QDomElement rootElement = doc.firstChildElement("playlist"); if (rootElement.isNull()) return; QDomElement tracklistElement = rootElement.firstChildElement("trackList"); if (tracklistElement.isNull()) return; QMap items; QMap items_no_tracknum; QDomElement child = tracklistElement.firstChildElement("track"); int m = 0; while (!child.isNull()) { bool ok; int n = child.firstChildElement("trackNum").text().toInt(&ok); if (!ok) { items_no_tracknum[m].setFilename(child.firstChildElement("location").text()); items_no_tracknum[m].setArtist(child.firstChildElement("creator").text()); items_no_tracknum[m].setTitle(child.firstChildElement("title").text()); items_no_tracknum[m].setLength(child.firstChildElement("duration").text().toInt() / 1000); ++m; } else { items[n].setFilename(child.firstChildElement("location").text()); items[n].setArtist(child.firstChildElement("creator").text()); items[n].setTitle(child.firstChildElement("title").text()); items[n].setLength(child.firstChildElement("duration").text().toInt() / 1000); } child = child.nextSiblingElement(); } QMap::const_iterator i = items.constBegin(); while (i != items.constEnd()) { p_playlist.append(i.value()); ++i; } QMap::const_iterator j = items_no_tracknum.constBegin(); while (j != items_no_tracknum.constEnd()) { p_playlist.append(j.value()); ++j; } } const PlaylistItem Playlist::p_parse_m3u_metadata_line(const QString& line) { PlaylistItem pi; QString info = line.section(':', 1); QString l = info.section(',', 0, 0); bool ok; int length = l.toInt(&ok); if (!ok) return pi; pi.setLength(length); QString track_info = info.section(',', 1); QStringList list = track_info.split('-'); if (list.length() <= 1) { pi.setTitle(track_info); return pi; } pi.setArtist(list[0].trimmed()); pi.setTitle(list[1].trimmed()); return pi; }