Explicitly pass MIME type to OpenEnc when adding cover artwork via "--picture" option.
This commit is contained in:
parent
6bc9126295
commit
281c94026d
@ -439,6 +439,7 @@ copy /Y "$(SolutionDir)\..\Prerequisites\Qt4\$(PlatformToolset)\Shared\plugins\i
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release_Static|Win32'">$(SolutionDir)tmp\$(ProjectName)\MOC_%(Filename).cpp;%(Outputs)</Outputs>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)tmp\$(ProjectName)\MOC_%(Filename).cpp;%(Outputs)</Outputs>
|
||||
</CustomBuild>
|
||||
<ClInclude Include="src\MimeTypes.h" />
|
||||
<ClInclude Include="tmp\LameXP\UIC_AboutDialog.h" />
|
||||
<ClInclude Include="tmp\LameXP\UIC_CueSheetImport.h" />
|
||||
<ClInclude Include="tmp\LameXP\UIC_DropBox.h" />
|
||||
|
@ -552,6 +552,9 @@
|
||||
<ClInclude Include="src\IPCCommands.h">
|
||||
<Filter>Header Files\Misc</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\MimeTypes.h">
|
||||
<Filter>Header Files\Misc</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="gui\DropBox.ui">
|
||||
|
@ -439,6 +439,7 @@ copy /Y "$(SolutionDir)\..\Prerequisites\Qt4\$(PlatformToolset)\Shared\plugins\i
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release_Static|Win32'">$(SolutionDir)tmp\$(ProjectName)\MOC_%(Filename).cpp;%(Outputs)</Outputs>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)tmp\$(ProjectName)\MOC_%(Filename).cpp;%(Outputs)</Outputs>
|
||||
</CustomBuild>
|
||||
<ClInclude Include="src\MimeTypes.h" />
|
||||
<ClInclude Include="tmp\LameXP\UIC_AboutDialog.h" />
|
||||
<ClInclude Include="tmp\LameXP\UIC_CueSheetImport.h" />
|
||||
<ClInclude Include="tmp\LameXP\UIC_DropBox.h" />
|
||||
|
@ -552,6 +552,9 @@
|
||||
<ClInclude Include="src\IPCCommands.h">
|
||||
<Filter>Header Files\Misc</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\MimeTypes.h">
|
||||
<Filter>Header Files\Misc</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="gui\DropBox.ui">
|
||||
|
@ -35,7 +35,7 @@
|
||||
#define VER_LAMEXP_MINOR_LO 2
|
||||
#define VER_LAMEXP_TYPE Beta
|
||||
#define VER_LAMEXP_PATCH 5
|
||||
#define VER_LAMEXP_BUILD 1794
|
||||
#define VER_LAMEXP_BUILD 1795
|
||||
#define VER_LAMEXP_CONFG 1700
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -22,9 +22,15 @@
|
||||
|
||||
#include "Encoder_Opus.h"
|
||||
|
||||
//MUtils
|
||||
#include <MUtils/Global.h>
|
||||
|
||||
//Internal
|
||||
#include "Global.h"
|
||||
#include "Model_Settings.h"
|
||||
#include "MimeTypes.h"
|
||||
|
||||
//Qt
|
||||
#include <QProcess>
|
||||
#include <QDir>
|
||||
#include <QUUid>
|
||||
@ -183,8 +189,7 @@ bool OpusEncoder::encode(const QString &sourceFile, const AudioFileModel_MetaInf
|
||||
if(metaInfo.year()) args << "--date" << QString::number(metaInfo.year());
|
||||
if(metaInfo.position()) args << "--comment" << QString("tracknumber=%1").arg(QString::number(metaInfo.position()));
|
||||
if(!metaInfo.comment().isEmpty()) args << "--comment" << QString("comment=%1").arg(cleanTag(metaInfo.comment()));
|
||||
if(!metaInfo.cover().isEmpty()) args << "--picture" << QDir::toNativeSeparators(metaInfo.cover());
|
||||
|
||||
if(!metaInfo.cover().isEmpty()) args << "--picture" << makeCoverParam(metaInfo.cover());
|
||||
|
||||
if(!m_configCustomParams.isEmpty()) args << m_configCustomParams.split(" ", QString::SkipEmptyParts);
|
||||
|
||||
@ -259,6 +264,29 @@ bool OpusEncoder::encode(const QString &sourceFile, const AudioFileModel_MetaInf
|
||||
return true;
|
||||
}
|
||||
|
||||
QString OpusEncoder::detectMimeType(const QString &coverFile)
|
||||
{
|
||||
const QString suffix = QFileInfo(coverFile).suffix();
|
||||
for (size_t i = 0; MIME_TYPES[i].type; i++)
|
||||
{
|
||||
for (size_t k = 0; MIME_TYPES[i].ext[k]; k++)
|
||||
{
|
||||
if (suffix.compare(QString::fromLatin1(MIME_TYPES[i].ext[k]), Qt::CaseInsensitive) == 0)
|
||||
{
|
||||
return QString::fromLatin1(MIME_TYPES[i].type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
qWarning("Unknown MIME type for extension '%s' -> using default!", MUTILS_UTF8(coverFile));
|
||||
return QString::fromLatin1(MIME_TYPES[0].type);
|
||||
}
|
||||
|
||||
QString OpusEncoder::makeCoverParam(const QString &coverFile)
|
||||
{
|
||||
return QString("3|%1|||%2").arg(detectMimeType(coverFile), QDir::toNativeSeparators(coverFile));
|
||||
}
|
||||
|
||||
void OpusEncoder::setOptimizeFor(int optimizeFor)
|
||||
{
|
||||
m_configOptimizeFor = qBound(0, optimizeFor, 2);
|
||||
|
@ -55,4 +55,7 @@ private:
|
||||
int m_configOptimizeFor;
|
||||
int m_configEncodeComplexity;
|
||||
int m_configFrameSize;
|
||||
|
||||
static inline QString detectMimeType(const QString &coverFile);
|
||||
static inline QString makeCoverParam(const QString &coverFile);
|
||||
};
|
||||
|
39
src/MimeTypes.h
Normal file
39
src/MimeTypes.h
Normal file
@ -0,0 +1,39 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// LameXP - Audio Encoder Front-End
|
||||
// Copyright (C) 2004-2015 LoRd_MuldeR <MuldeR2@GMX.de>
|
||||
//
|
||||
// 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, but always including the *additional*
|
||||
// restrictions defined in the "License.txt" file.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
static const struct
|
||||
{
|
||||
const char *type;
|
||||
const char *ext[8];
|
||||
}
|
||||
MIME_TYPES[] =
|
||||
{
|
||||
{ "image/jpeg", { "jpg", "jpeg", "jpe", NULL } },
|
||||
{ "image/png", { "png", NULL } },
|
||||
{ "image/gif", { "gif", NULL } },
|
||||
{ "image/tiff", { "tif", "tiff", NULL } },
|
||||
{ NULL, { NULL } }
|
||||
};
|
||||
|
||||
static const size_t MIME_TYPES_MAX = (sizeof(MIME_TYPES) / sizeof(MIME_TYPES[0])) - 2;
|
@ -26,6 +26,7 @@
|
||||
#include "Global.h"
|
||||
#include "LockedFile.h"
|
||||
#include "Model_AudioFile.h"
|
||||
#include "MimeTypes.h"
|
||||
|
||||
//MUtils
|
||||
#include <MUtils/Global.h>
|
||||
@ -178,8 +179,8 @@ const AudioFileModel AnalyzeTask::analyzeFile(const QString &filePath, int *type
|
||||
readTest.close();
|
||||
|
||||
bool skipNext = false;
|
||||
unsigned int id_val[2] = {UINT_MAX, UINT_MAX};
|
||||
cover_t coverType = coverNone;
|
||||
QPair<quint32, quint32> id_val(UINT_MAX, UINT_MAX);
|
||||
quint32 coverType = UINT_MAX;
|
||||
QByteArray coverData;
|
||||
|
||||
QStringList params;
|
||||
@ -236,7 +237,7 @@ const AudioFileModel AnalyzeTask::analyzeFile(const QString &filePath, int *type
|
||||
QString val = line.mid(index+1).trimmed();
|
||||
if(!key.isEmpty())
|
||||
{
|
||||
updateInfo(audioFile, &skipNext, id_val, &coverType, &coverData, key, val);
|
||||
updateInfo(audioFile, skipNext, id_val, coverType, coverData, key, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -271,7 +272,7 @@ const AudioFileModel AnalyzeTask::analyzeFile(const QString &filePath, int *type
|
||||
process.waitForFinished(-1);
|
||||
}
|
||||
|
||||
if((coverType != coverNone) && (!coverData.isEmpty()))
|
||||
if((coverType != UINT_MAX) && (!coverData.isEmpty()))
|
||||
{
|
||||
retrieveCover(audioFile, coverType, coverData);
|
||||
}
|
||||
@ -284,7 +285,7 @@ const AudioFileModel AnalyzeTask::analyzeFile(const QString &filePath, int *type
|
||||
return audioFile;
|
||||
}
|
||||
|
||||
void AnalyzeTask::updateInfo(AudioFileModel &audioFile, bool *skipNext, unsigned int *id_val, cover_t *coverType, QByteArray *coverData, const QString &key, const QString &value)
|
||||
void AnalyzeTask::updateInfo(AudioFileModel &audioFile, bool &skipNext, QPair<quint32, quint32> &id_val, quint32 &coverType, QByteArray &coverData, const QString &key, const QString &value)
|
||||
{
|
||||
//qWarning("'%s' -> '%s'", MUTILS_UTF8(key), MUTILS_UTF8(value));
|
||||
|
||||
@ -293,7 +294,7 @@ void AnalyzeTask::updateInfo(AudioFileModel &audioFile, bool *skipNext, unsigned
|
||||
{
|
||||
if(value.isEmpty())
|
||||
{
|
||||
*skipNext = false;
|
||||
skipNext = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -302,15 +303,15 @@ void AnalyzeTask::updateInfo(AudioFileModel &audioFile, bool *skipNext, unsigned
|
||||
unsigned int id = value.toUInt(&ok);
|
||||
if(ok)
|
||||
{
|
||||
if(IS_KEY("Gen_ID")) { id_val[0] = qMin(id_val[0], id); *skipNext = (id > id_val[0]); }
|
||||
if(IS_KEY("Aud_ID")) { id_val[1] = qMin(id_val[1], id); *skipNext = (id > id_val[1]); }
|
||||
if(IS_KEY("Gen_ID")) { id_val.first = qMin(id_val.first, id); skipNext = (id > id_val.first); }
|
||||
if(IS_KEY("Aud_ID")) { id_val.second = qMin(id_val.second, id); skipNext = (id > id_val.second); }
|
||||
}
|
||||
else
|
||||
{
|
||||
*skipNext = true;
|
||||
skipNext = true;
|
||||
}
|
||||
}
|
||||
if(*skipNext)
|
||||
if(skipNext)
|
||||
{
|
||||
qWarning("Skipping info for non-primary stream!");
|
||||
}
|
||||
@ -318,7 +319,7 @@ void AnalyzeTask::updateInfo(AudioFileModel &audioFile, bool *skipNext, unsigned
|
||||
}
|
||||
|
||||
/*Skip or empty?*/
|
||||
if((*skipNext) || value.isEmpty())
|
||||
if((skipNext) || value.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -326,7 +327,7 @@ void AnalyzeTask::updateInfo(AudioFileModel &audioFile, bool *skipNext, unsigned
|
||||
/*Playlist file?*/
|
||||
if(IS_KEY("Aud_Source"))
|
||||
{
|
||||
*skipNext = true;
|
||||
skipNext = true;
|
||||
audioFile.techInfo().setContainerType(QString());
|
||||
audioFile.techInfo().setAudioType(QString());
|
||||
qWarning("Skipping info for playlist file!");
|
||||
@ -382,22 +383,27 @@ void AnalyzeTask::updateInfo(AudioFileModel &audioFile, bool *skipNext, unsigned
|
||||
}
|
||||
else if(IS_KEY("Gen_Cover") || IS_KEY("Gen_Cover_Type"))
|
||||
{
|
||||
if(*coverType == coverNone)
|
||||
if(coverType == UINT_MAX)
|
||||
{
|
||||
*coverType = coverJpeg;
|
||||
coverType = 0;
|
||||
}
|
||||
}
|
||||
else if(IS_KEY("Gen_Cover_Mime"))
|
||||
{
|
||||
QString temp = FIRST_TOK(value);
|
||||
if(!temp.compare("image/jpeg", Qt::CaseInsensitive)) *coverType = coverJpeg;
|
||||
else if(!temp.compare("image/png", Qt::CaseInsensitive)) *coverType = coverPng;
|
||||
else if(!temp.compare("image/gif", Qt::CaseInsensitive)) *coverType = coverGif;
|
||||
for (quint32 i = 0; MIME_TYPES[i].type; i++)
|
||||
{
|
||||
if (temp.compare(QString::fromLatin1(MIME_TYPES[i].type), Qt::CaseInsensitive) == 0)
|
||||
{
|
||||
coverType = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(IS_KEY("Gen_Cover_Data"))
|
||||
{
|
||||
if(!coverData->isEmpty()) coverData->clear();
|
||||
coverData->append(QByteArray::fromBase64(FIRST_TOK(value).toLatin1()));
|
||||
if(!coverData.isEmpty()) coverData.clear();
|
||||
coverData.append(QByteArray::fromBase64(FIRST_TOK(value).toLatin1()));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -483,27 +489,14 @@ bool AnalyzeTask::checkFile_CDDA(QFile &file)
|
||||
return ((i >= 0) && (j >= 0) && (k >= 0) && (k > j) && (j > i));
|
||||
}
|
||||
|
||||
void AnalyzeTask::retrieveCover(AudioFileModel &audioFile, cover_t coverType, const QByteArray &coverData)
|
||||
void AnalyzeTask::retrieveCover(AudioFileModel &audioFile, const quint32 coverType, const QByteArray &coverData)
|
||||
{
|
||||
qDebug("Retrieving cover!");
|
||||
QString extension;
|
||||
qDebug("Retrieving cover! (MIME_TYPES_MAX=%u)", MIME_TYPES_MAX);
|
||||
|
||||
switch(coverType)
|
||||
static const QString ext = QString::fromLatin1(MIME_TYPES[qBound(0U, coverType, MIME_TYPES_MAX)].ext[0]);
|
||||
if(!(QImage::fromData(coverData, ext.toUpper().toLatin1().constData()).isNull()))
|
||||
{
|
||||
case coverPng:
|
||||
extension = QString::fromLatin1("png");
|
||||
break;
|
||||
case coverGif:
|
||||
extension = QString::fromLatin1("gif");
|
||||
break;
|
||||
default:
|
||||
extension = QString::fromLatin1("jpg");
|
||||
break;
|
||||
}
|
||||
|
||||
if(!(QImage::fromData(coverData, extension.toUpper().toLatin1().constData()).isNull()))
|
||||
{
|
||||
QFile coverFile(QString("%1/%2.%3").arg(MUtils::temp_folder(), MUtils::rand_str(), extension));
|
||||
QFile coverFile(QString("%1/%2.%3").arg(MUtils::temp_folder(), MUtils::rand_str(), ext));
|
||||
if(coverFile.open(QIODevice::WriteOnly))
|
||||
{
|
||||
coverFile.write(coverData);
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <QStringList>
|
||||
#include <QMutex>
|
||||
#include <QSemaphore>
|
||||
#include <QPair>
|
||||
|
||||
class AudioFileModel;
|
||||
class QFile;
|
||||
@ -56,9 +57,6 @@ public:
|
||||
fileTypeUnknown = 4
|
||||
};
|
||||
|
||||
//Wait until there is a free slot in the queue
|
||||
static bool waitForFreeSlot(volatile bool *abortFlag);
|
||||
|
||||
signals:
|
||||
void fileAnalyzed(const unsigned int taskId, const int fileType, const AudioFileModel &file);
|
||||
void taskCompleted(const unsigned int taskId);
|
||||
@ -68,20 +66,12 @@ protected:
|
||||
void run_ex(void);
|
||||
|
||||
private:
|
||||
enum cover_t
|
||||
{
|
||||
coverNone,
|
||||
coverJpeg,
|
||||
coverPng,
|
||||
coverGif
|
||||
};
|
||||
|
||||
const AudioFileModel analyzeFile(const QString &filePath, int *type);
|
||||
void updateInfo(AudioFileModel &audioFile, bool *skipNext, unsigned int *id_val, cover_t *coverType, QByteArray *coverData, const QString &key, const QString &value);
|
||||
void updateInfo(AudioFileModel &audioFile, bool &skipNext, QPair<quint32, quint32> &id_val, quint32 &coverType, QByteArray &coverData, const QString &key, const QString &value);
|
||||
unsigned int parseYear(const QString &str);
|
||||
unsigned int parseDuration(const QString &str);
|
||||
bool checkFile_CDDA(QFile &file);
|
||||
void retrieveCover(AudioFileModel &audioFile, cover_t coverType, const QByteArray &coverData);
|
||||
void retrieveCover(AudioFileModel &audioFile, const quint32 coverType, const QByteArray &coverData);
|
||||
bool analyzeAvisynthFile(const QString &filePath, AudioFileModel &info);
|
||||
|
||||
const unsigned int m_taskId;
|
||||
|
Loading…
Reference in New Issue
Block a user