Added Opus transcode support
This commit is contained in:
@@ -11,6 +11,8 @@ lms_SOURCES = \
|
||||
$(srcdir)/av/AvInfo.hpp \
|
||||
$(srcdir)/av/AvTranscoder.cpp \
|
||||
$(srcdir)/av/AvTranscoder.hpp \
|
||||
$(srcdir)/av/AvTypes.cpp \
|
||||
$(srcdir)/av/AvTypes.hpp \
|
||||
$(srcdir)/cover/CoverArtGrabber.cpp \
|
||||
$(srcdir)/cover/CoverArtGrabber.hpp \
|
||||
$(srcdir)/database/Artist.cpp \
|
||||
|
||||
+1
-7
@@ -38,7 +38,7 @@ extern "C"
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/filesystem/path.hpp>
|
||||
|
||||
#include "utils/Exception.hpp"
|
||||
#include "AvTypes.hpp"
|
||||
|
||||
namespace Av
|
||||
{
|
||||
@@ -57,12 +57,6 @@ struct StreamInfo
|
||||
std::size_t bitrate;
|
||||
};
|
||||
|
||||
class AvException : public LmsException
|
||||
{
|
||||
public:
|
||||
AvException(const std::string& msg) : LmsException(msg) {}
|
||||
};
|
||||
|
||||
class MediaFileException : public AvException
|
||||
{
|
||||
public:
|
||||
|
||||
+10
-59
@@ -29,54 +29,6 @@ namespace Av {
|
||||
|
||||
#define LMS_LOG_TRANSCODE(sev) LMS_LOG(TRANSCODE, INFO) << "[" << _id << "] - "
|
||||
|
||||
struct EncodingInfo
|
||||
{
|
||||
Encoding encoding;
|
||||
std::string mimetype;
|
||||
int id;
|
||||
};
|
||||
|
||||
static std::vector<EncodingInfo> encodingInfos =
|
||||
{
|
||||
{Encoding::MP3, "audio/mp3", 0},
|
||||
{Encoding::OGA, "audio/ogg", 1},
|
||||
{Encoding::WEBMA, "audio/webm", 3},
|
||||
{Encoding::M4A, "audio/mp4", 5},
|
||||
};
|
||||
|
||||
std::string encodingToMimetype(Encoding encoding)
|
||||
{
|
||||
for (auto encodingInfo : encodingInfos)
|
||||
{
|
||||
if (encodingInfo.encoding == encoding)
|
||||
return encodingInfo.mimetype;
|
||||
}
|
||||
|
||||
throw AvException("Invalid encoding");
|
||||
}
|
||||
|
||||
int encodingToInt(Encoding encoding)
|
||||
{
|
||||
for (auto encodingInfo : encodingInfos)
|
||||
{
|
||||
if (encodingInfo.encoding == encoding)
|
||||
return encodingInfo.id;
|
||||
}
|
||||
|
||||
throw AvException("Invalid encoding");
|
||||
}
|
||||
|
||||
Encoding encodingFromInt(int encodingId)
|
||||
{
|
||||
for (auto encodingInfo : encodingInfos)
|
||||
{
|
||||
if (encodingInfo.id == encodingId)
|
||||
return encodingInfo.encoding;
|
||||
}
|
||||
|
||||
throw AvException("Invalid encodingId");
|
||||
}
|
||||
|
||||
// TODO, parametrize?
|
||||
static const std::vector<std::string> execNames =
|
||||
{
|
||||
@@ -176,28 +128,27 @@ Transcoder::start()
|
||||
args.push_back("mp3");
|
||||
break;
|
||||
|
||||
case Encoding::OGA:
|
||||
case Encoding::OGG_OPUS:
|
||||
args.push_back("-acodec");
|
||||
args.push_back("libopus");
|
||||
args.push_back("-f");
|
||||
args.push_back("ogg");
|
||||
break;
|
||||
|
||||
case Encoding::OGG_VORBIS:
|
||||
args.push_back("-acodec");
|
||||
args.push_back("libvorbis");
|
||||
args.push_back("-f");
|
||||
args.push_back("ogg");
|
||||
break;
|
||||
|
||||
case Encoding::WEBMA:
|
||||
args.push_back("-codec:a");
|
||||
case Encoding::WEBM_VORBIS:
|
||||
args.push_back("-acodec");
|
||||
args.push_back("libvorbis");
|
||||
args.push_back("-f");
|
||||
args.push_back("webm");
|
||||
break;
|
||||
|
||||
case Encoding::M4A:
|
||||
args.push_back("-acodec");
|
||||
args.push_back("aac");
|
||||
args.push_back("-f");
|
||||
args.push_back("mp4");
|
||||
args.push_back("-strict");
|
||||
args.push_back("experimental");
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
|
||||
+1
-10
@@ -28,20 +28,11 @@
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
#include "AvInfo.hpp"
|
||||
#include "AvTypes.hpp"
|
||||
|
||||
namespace Av {
|
||||
|
||||
|
||||
enum class Encoding
|
||||
{
|
||||
OGA,
|
||||
OGV,
|
||||
MP3,
|
||||
WEBMA,
|
||||
M4A,
|
||||
};
|
||||
|
||||
std::string encodingToMimetype(Encoding encoding);
|
||||
|
||||
struct TranscodeParameters
|
||||
{
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Emeric Poupon
|
||||
*
|
||||
* This file is part of LMS.
|
||||
*
|
||||
* LMS 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.
|
||||
*
|
||||
* LMS 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 LMS. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "AvTypes.hpp"
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace Av {
|
||||
|
||||
std::string encodingToMimetype(Encoding encoding)
|
||||
{
|
||||
static const std::map<Encoding, std::string> encodings
|
||||
{
|
||||
{Encoding::MP3, "audio/mp3"},
|
||||
{Encoding::OGG_VORBIS, "audio/ogg"},
|
||||
{Encoding::OGG_OPUS, "audio/opus"},
|
||||
{Encoding::WEBM_VORBIS, "audio/webm"},
|
||||
};
|
||||
|
||||
auto it {encodings.find(encoding)};
|
||||
if (it == encodings.end())
|
||||
throw AvException("Invalid encoding");
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Emeric Poupon
|
||||
*
|
||||
* This file is part of LMS.
|
||||
*
|
||||
* LMS 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.
|
||||
*
|
||||
* LMS 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 LMS. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "utils/Exception.hpp"
|
||||
|
||||
namespace Av {
|
||||
|
||||
class AvException : public LmsException
|
||||
{
|
||||
public:
|
||||
AvException(const std::string& msg) : LmsException(msg) {}
|
||||
};
|
||||
|
||||
enum class Encoding
|
||||
{
|
||||
// Values are important and must not be changed
|
||||
MP3 = 0,
|
||||
OGG_OPUS = 1,
|
||||
OGG_VORBIS = 2,
|
||||
WEBM_VORBIS = 3,
|
||||
};
|
||||
|
||||
std::string encodingToMimetype(Encoding encoding);
|
||||
|
||||
}
|
||||
|
||||
@@ -36,10 +36,11 @@ class TrackList;
|
||||
// User selectable audio formats
|
||||
enum class AudioEncoding
|
||||
{
|
||||
AUTO,
|
||||
MP3,
|
||||
OGA,
|
||||
WEBMA,
|
||||
AUTO = 0,
|
||||
MP3 = 1,
|
||||
OGG_OPUS = 2,
|
||||
OGG_VORBIS = 3,
|
||||
WEBM_VORBIS = 4,
|
||||
};
|
||||
|
||||
class User : public Wt::Dbo::Dbo<User>
|
||||
|
||||
@@ -224,17 +224,20 @@ class SettingsModel : public Wt::WFormModel
|
||||
|
||||
_encodingModel = std::make_shared<Wt::WStringListModel>();
|
||||
|
||||
_encodingModel->addString(Wt::WString::tr("Lms.Settings.auto"));
|
||||
_encodingModel->addString(Wt::WString::tr("Lms.Settings.encoding.auto"));
|
||||
_encodingModel->setData(0, 0, Database::AudioEncoding::AUTO, Wt::ItemDataRole::User);
|
||||
|
||||
_encodingModel->addString(Wt::WString::tr("Lms.Settings.mp3"));
|
||||
_encodingModel->addString(Wt::WString::tr("Lms.Settings.encoding.mp3"));
|
||||
_encodingModel->setData(1, 0, Database::AudioEncoding::MP3, Wt::ItemDataRole::User);
|
||||
|
||||
_encodingModel->addString(Wt::WString::tr("Lms.Settings.oga"));
|
||||
_encodingModel->setData(2, 0, Database::AudioEncoding::OGA, Wt::ItemDataRole::User);
|
||||
_encodingModel->addString(Wt::WString::tr("Lms.Settings.encoding.ogg_opus"));
|
||||
_encodingModel->setData(2, 0, Database::AudioEncoding::OGG_OPUS, Wt::ItemDataRole::User);
|
||||
|
||||
_encodingModel->addString(Wt::WString::tr("Lms.Settings.webma"));
|
||||
_encodingModel->setData(3, 0, Database::AudioEncoding::WEBMA, Wt::ItemDataRole::User);
|
||||
_encodingModel->addString(Wt::WString::tr("Lms.Settings.encoding.ogg_vorbis"));
|
||||
_encodingModel->setData(3, 0, Database::AudioEncoding::OGG_VORBIS, Wt::ItemDataRole::User);
|
||||
|
||||
_encodingModel->addString(Wt::WString::tr("Lms.Settings.encoding.webm_vorbis"));
|
||||
_encodingModel->setData(4, 0, Database::AudioEncoding::WEBM_VORBIS, Wt::ItemDataRole::User);
|
||||
}
|
||||
|
||||
std::shared_ptr<Wt::WStringListModel> _bitrateModel;
|
||||
|
||||
@@ -102,18 +102,22 @@ AudioResource::handleRequest(const Wt::Http::Request& request,
|
||||
|
||||
switch (LmsApp->getUser()->getAudioEncoding())
|
||||
{
|
||||
case Database::AudioEncoding::OGA:
|
||||
parameters.encoding = Av::Encoding::OGA;
|
||||
break;
|
||||
case Database::AudioEncoding::WEBMA:
|
||||
parameters.encoding = Av::Encoding::WEBMA;
|
||||
break;
|
||||
case Database::AudioEncoding::AUTO:
|
||||
case Database::AudioEncoding::MP3:
|
||||
parameters.encoding = Av::Encoding::MP3;
|
||||
break;
|
||||
case Database::AudioEncoding::AUTO:
|
||||
case Database::AudioEncoding::OGG_OPUS:
|
||||
parameters.encoding = Av::Encoding::OGG_OPUS;
|
||||
break;
|
||||
case Database::AudioEncoding::OGG_VORBIS:
|
||||
parameters.encoding = Av::Encoding::OGG_VORBIS;
|
||||
break;
|
||||
case Database::AudioEncoding::WEBM_VORBIS:
|
||||
parameters.encoding = Av::Encoding::WEBM_VORBIS;
|
||||
break;
|
||||
default:
|
||||
parameters.encoding = Av::Encoding::MP3;
|
||||
break;
|
||||
}
|
||||
transcoder = std::make_shared<Av::Transcoder>(track->getPath(), parameters);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user