Minor cleanup on audio codecs
This commit is contained in:
@@ -70,83 +70,83 @@ namespace lms::audio::ffmpeg
|
|||||||
res[core::stringUtils::stringToUpper(tag->key)] = tag->value;
|
res[core::stringUtils::stringToUpper(tag->key)] = tag->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<core::media::ContainerType> avdemuxerToContainerType(std::string_view name)
|
std::optional<core::media::Container> avdemuxerToContainerType(std::string_view name)
|
||||||
{
|
{
|
||||||
if (name == "aiff")
|
if (name == "aiff")
|
||||||
return core::media::ContainerType::AIFF;
|
return core::media::Container::AIFF;
|
||||||
if (name == "ape")
|
if (name == "ape")
|
||||||
return core::media::ContainerType::APE;
|
return core::media::Container::APE;
|
||||||
if (name.starts_with("asf"))
|
if (name.starts_with("asf"))
|
||||||
return core::media::ContainerType::ASF;
|
return core::media::Container::ASF;
|
||||||
if (name == "dsf")
|
if (name == "dsf")
|
||||||
return core::media::ContainerType::DSF;
|
return core::media::Container::DSF;
|
||||||
if (name == "flac")
|
if (name == "flac")
|
||||||
return core::media::ContainerType::FLAC;
|
return core::media::Container::FLAC;
|
||||||
if (name.find("mp4") != std::string_view::npos)
|
if (name.find("mp4") != std::string_view::npos)
|
||||||
return core::media::ContainerType::MP4;
|
return core::media::Container::MP4;
|
||||||
if (name.starts_with("mpc"))
|
if (name.starts_with("mpc"))
|
||||||
return core::media::ContainerType::MPC;
|
return core::media::Container::MPC;
|
||||||
if (name == "mp3")
|
if (name == "mp3")
|
||||||
return core::media::ContainerType::MPEG;
|
return core::media::Container::MPEG;
|
||||||
if (name == "ogg")
|
if (name == "ogg")
|
||||||
return core::media::ContainerType::Ogg;
|
return core::media::Container::Ogg;
|
||||||
if (name == "shn")
|
if (name == "shn")
|
||||||
return core::media::ContainerType::Shorten;
|
return core::media::Container::Shorten;
|
||||||
if (name == "tta")
|
if (name == "tta")
|
||||||
return core::media::ContainerType::TrueAudio;
|
return core::media::Container::TrueAudio;
|
||||||
if (name == "wav")
|
if (name == "wav")
|
||||||
return core::media::ContainerType::WAV;
|
return core::media::Container::WAV;
|
||||||
if (name == "wv")
|
if (name == "wv")
|
||||||
return core::media::ContainerType::WavPack;
|
return core::media::Container::WavPack;
|
||||||
|
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<core::media::CodecType> avcodecToCodecType(AVCodecID codec)
|
std::optional<core::media::Codec> avcodecToCodecType(AVCodecID codec)
|
||||||
{
|
{
|
||||||
switch (codec)
|
switch (codec)
|
||||||
{
|
{
|
||||||
case AV_CODEC_ID_AAC:
|
case AV_CODEC_ID_AAC:
|
||||||
return core::media::CodecType::AAC;
|
return core::media::Codec::AAC;
|
||||||
case AV_CODEC_ID_AC3:
|
case AV_CODEC_ID_AC3:
|
||||||
return core::media::CodecType::AC3;
|
return core::media::Codec::AC3;
|
||||||
case AV_CODEC_ID_ALAC:
|
case AV_CODEC_ID_ALAC:
|
||||||
return core::media::CodecType::ALAC;
|
return core::media::Codec::ALAC;
|
||||||
case AV_CODEC_ID_APE:
|
case AV_CODEC_ID_APE:
|
||||||
return core::media::CodecType::APE;
|
return core::media::Codec::APE;
|
||||||
case AV_CODEC_ID_DSD_LSBF:
|
case AV_CODEC_ID_DSD_LSBF:
|
||||||
case AV_CODEC_ID_DSD_LSBF_PLANAR:
|
case AV_CODEC_ID_DSD_LSBF_PLANAR:
|
||||||
case AV_CODEC_ID_DSD_MSBF:
|
case AV_CODEC_ID_DSD_MSBF:
|
||||||
case AV_CODEC_ID_DSD_MSBF_PLANAR:
|
case AV_CODEC_ID_DSD_MSBF_PLANAR:
|
||||||
return core::media::CodecType::DSD;
|
return core::media::Codec::DSD;
|
||||||
case AV_CODEC_ID_EAC3:
|
case AV_CODEC_ID_EAC3:
|
||||||
return core::media::CodecType::EAC3;
|
return core::media::Codec::EAC3;
|
||||||
case AV_CODEC_ID_FLAC:
|
case AV_CODEC_ID_FLAC:
|
||||||
return core::media::CodecType::FLAC;
|
return core::media::Codec::FLAC;
|
||||||
case AV_CODEC_ID_MP3:
|
case AV_CODEC_ID_MP3:
|
||||||
return core::media::CodecType::MP3;
|
return core::media::Codec::MP3;
|
||||||
case AV_CODEC_ID_MP4ALS:
|
case AV_CODEC_ID_MP4ALS:
|
||||||
return core::media::CodecType::MP4ALS;
|
return core::media::Codec::MP4ALS;
|
||||||
case AV_CODEC_ID_MUSEPACK7:
|
case AV_CODEC_ID_MUSEPACK7:
|
||||||
return core::media::CodecType::MPC7;
|
return core::media::Codec::MPC7;
|
||||||
case AV_CODEC_ID_MUSEPACK8:
|
case AV_CODEC_ID_MUSEPACK8:
|
||||||
return core::media::CodecType::MPC8;
|
return core::media::Codec::MPC8;
|
||||||
case AV_CODEC_ID_OPUS:
|
case AV_CODEC_ID_OPUS:
|
||||||
return core::media::CodecType::Opus;
|
return core::media::Codec::Opus;
|
||||||
case AV_CODEC_ID_SHORTEN:
|
case AV_CODEC_ID_SHORTEN:
|
||||||
return core::media::CodecType::Shorten;
|
return core::media::Codec::Shorten;
|
||||||
case AV_CODEC_ID_VORBIS:
|
case AV_CODEC_ID_VORBIS:
|
||||||
return core::media::CodecType::Vorbis;
|
return core::media::Codec::Vorbis;
|
||||||
case AV_CODEC_ID_WAVPACK:
|
case AV_CODEC_ID_WAVPACK:
|
||||||
return core::media::CodecType::WavPack;
|
return core::media::Codec::WavPack;
|
||||||
case AV_CODEC_ID_WMALOSSLESS:
|
case AV_CODEC_ID_WMALOSSLESS:
|
||||||
return core::media::CodecType::WMA9Lossless;
|
return core::media::Codec::WMA9Lossless;
|
||||||
case AV_CODEC_ID_WMAPRO:
|
case AV_CODEC_ID_WMAPRO:
|
||||||
return core::media::CodecType::WMA9Pro;
|
return core::media::Codec::WMA9Pro;
|
||||||
case AV_CODEC_ID_WMAV1:
|
case AV_CODEC_ID_WMAV1:
|
||||||
return core::media::CodecType::WMA1;
|
return core::media::Codec::WMA1;
|
||||||
case AV_CODEC_ID_WMAV2:
|
case AV_CODEC_ID_WMAV2:
|
||||||
return core::media::CodecType::WMA2;
|
return core::media::Codec::WMA2;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
|
|||||||
@@ -27,8 +27,8 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "core/media/CodecType.hpp"
|
#include "core/media/Codec.hpp"
|
||||||
#include "core/media/ContainerType.hpp"
|
#include "core/media/Container.hpp"
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
@@ -45,7 +45,7 @@ namespace lms::audio::ffmpeg
|
|||||||
|
|
||||||
struct ContainerInfo
|
struct ContainerInfo
|
||||||
{
|
{
|
||||||
std::optional<core::media::ContainerType> container;
|
std::optional<core::media::Container> container;
|
||||||
std::string containerName;
|
std::string containerName;
|
||||||
|
|
||||||
std::optional<std::size_t> bitrate;
|
std::optional<std::size_t> bitrate;
|
||||||
@@ -55,7 +55,7 @@ namespace lms::audio::ffmpeg
|
|||||||
struct StreamInfo
|
struct StreamInfo
|
||||||
{
|
{
|
||||||
size_t index{};
|
size_t index{};
|
||||||
std::optional<core::media::CodecType> codec;
|
std::optional<core::media::Codec> codec;
|
||||||
std::string codecName;
|
std::string codecName;
|
||||||
|
|
||||||
std::optional<size_t> bitrate;
|
std::optional<size_t> bitrate;
|
||||||
|
|||||||
@@ -161,42 +161,42 @@ namespace lms::audio::ffmpeg
|
|||||||
|
|
||||||
switch (_outputParams.format->container)
|
switch (_outputParams.format->container)
|
||||||
{
|
{
|
||||||
case core::media::ContainerType::FLAC:
|
case core::media::Container::FLAC:
|
||||||
args.emplace_back("flac");
|
args.emplace_back("flac");
|
||||||
break;
|
break;
|
||||||
case core::media::ContainerType::Ogg:
|
case core::media::Container::Ogg:
|
||||||
args.emplace_back("ogg");
|
args.emplace_back("ogg");
|
||||||
break;
|
break;
|
||||||
case core::media::ContainerType::MPEG:
|
case core::media::Container::MPEG:
|
||||||
args.emplace_back("mp3");
|
args.emplace_back("mp3");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw Exception{ "Unsupported container type " + std::string{ core::media::containerTypeToString(_outputParams.format->container).str() } };
|
throw Exception{ "Unsupported container type " + std::string{ core::media::containerToString(_outputParams.format->container).str() } };
|
||||||
}
|
}
|
||||||
|
|
||||||
args.emplace_back("-acodec");
|
args.emplace_back("-acodec");
|
||||||
|
|
||||||
switch (_outputParams.format->codec)
|
switch (_outputParams.format->codec)
|
||||||
{
|
{
|
||||||
case core::media::CodecType::MP3:
|
case core::media::Codec::MP3:
|
||||||
args.emplace_back("libmp3lame");
|
args.emplace_back("libmp3lame");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case core::media::CodecType::Opus:
|
case core::media::Codec::Opus:
|
||||||
args.emplace_back("libopus");
|
args.emplace_back("libopus");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case core::media::CodecType::Vorbis:
|
case core::media::Codec::Vorbis:
|
||||||
args.emplace_back("libvorbis");
|
args.emplace_back("libvorbis");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case core::media::CodecType::FLAC:
|
case core::media::Codec::FLAC:
|
||||||
args.emplace_back("flac");
|
args.emplace_back("flac");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw Exception{ "Unhandled codec type " + std::string{ codecTypeToString(_outputParams.format->codec).str() } };
|
throw Exception{ "Unhandled codec type " + std::string{ core::media::getCodecDesc(_outputParams.format->codec).name.str() } };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -104,27 +104,27 @@ namespace lms::audio::taglib
|
|||||||
// Guess container from the file type
|
// Guess container from the file type
|
||||||
if (const auto* apeFile{ dynamic_cast<const ::TagLib::APE::File*>(&file) })
|
if (const auto* apeFile{ dynamic_cast<const ::TagLib::APE::File*>(&file) })
|
||||||
{
|
{
|
||||||
audioProperties.container = core::media::ContainerType::APE;
|
audioProperties.container = core::media::Container::APE;
|
||||||
audioProperties.codec = core::media::CodecType::APE; // TODO version?
|
audioProperties.codec = core::media::Codec::APE; // TODO version?
|
||||||
audioProperties.bitsPerSample = apeFile->audioProperties()->bitsPerSample();
|
audioProperties.bitsPerSample = apeFile->audioProperties()->bitsPerSample();
|
||||||
}
|
}
|
||||||
else if (const auto* asfFile{ dynamic_cast<const ::TagLib::ASF::File*>(&file) })
|
else if (const auto* asfFile{ dynamic_cast<const ::TagLib::ASF::File*>(&file) })
|
||||||
{
|
{
|
||||||
audioProperties.container = core::media::ContainerType::ASF;
|
audioProperties.container = core::media::Container::ASF;
|
||||||
|
|
||||||
switch (asfFile->audioProperties()->codec())
|
switch (asfFile->audioProperties()->codec())
|
||||||
{
|
{
|
||||||
case ::TagLib::ASF::Properties::Codec::WMA1:
|
case ::TagLib::ASF::Properties::Codec::WMA1:
|
||||||
audioProperties.codec = core::media::CodecType::WMA1;
|
audioProperties.codec = core::media::Codec::WMA1;
|
||||||
break;
|
break;
|
||||||
case ::TagLib::ASF::Properties::Codec::WMA2:
|
case ::TagLib::ASF::Properties::Codec::WMA2:
|
||||||
audioProperties.codec = core::media::CodecType::WMA2;
|
audioProperties.codec = core::media::Codec::WMA2;
|
||||||
break;
|
break;
|
||||||
case ::TagLib::ASF::Properties::Codec::WMA9Lossless:
|
case ::TagLib::ASF::Properties::Codec::WMA9Lossless:
|
||||||
audioProperties.codec = core::media::CodecType::WMA9Lossless;
|
audioProperties.codec = core::media::Codec::WMA9Lossless;
|
||||||
break;
|
break;
|
||||||
case ::TagLib::ASF::Properties::Codec::WMA9Pro:
|
case ::TagLib::ASF::Properties::Codec::WMA9Pro:
|
||||||
audioProperties.codec = core::media::CodecType::WMA9Pro;
|
audioProperties.codec = core::media::Codec::WMA9Pro;
|
||||||
break;
|
break;
|
||||||
case ::TagLib::ASF::Properties::Codec::Unknown:
|
case ::TagLib::ASF::Properties::Codec::Unknown:
|
||||||
LMS_LOG(AUDIO, DEBUG, "Unhandled ASF codec in " << filePath);
|
LMS_LOG(AUDIO, DEBUG, "Unhandled ASF codec in " << filePath);
|
||||||
@@ -136,27 +136,27 @@ namespace lms::audio::taglib
|
|||||||
#if LMS_TAGLIB_HAS_DSF
|
#if LMS_TAGLIB_HAS_DSF
|
||||||
else if (const auto* dsfFile{ dynamic_cast<const ::TagLib::DSF::File*>(&file) })
|
else if (const auto* dsfFile{ dynamic_cast<const ::TagLib::DSF::File*>(&file) })
|
||||||
{
|
{
|
||||||
audioProperties.container = core::media::ContainerType::DSF;
|
audioProperties.container = core::media::Container::DSF;
|
||||||
audioProperties.codec = core::media::CodecType::DSD;
|
audioProperties.codec = core::media::Codec::DSD;
|
||||||
audioProperties.bitsPerSample = dsfFile->audioProperties()->bitsPerSample();
|
audioProperties.bitsPerSample = dsfFile->audioProperties()->bitsPerSample();
|
||||||
}
|
}
|
||||||
#endif // LMS_TAGLIB_HAS_DSF
|
#endif // LMS_TAGLIB_HAS_DSF
|
||||||
else if (const auto* flacFile{ dynamic_cast<const ::TagLib::FLAC::File*>(&file) })
|
else if (const auto* flacFile{ dynamic_cast<const ::TagLib::FLAC::File*>(&file) })
|
||||||
{
|
{
|
||||||
audioProperties.container = core::media::ContainerType::FLAC;
|
audioProperties.container = core::media::Container::FLAC;
|
||||||
audioProperties.codec = core::media::CodecType::FLAC;
|
audioProperties.codec = core::media::Codec::FLAC;
|
||||||
audioProperties.bitsPerSample = flacFile->audioProperties()->bitsPerSample();
|
audioProperties.bitsPerSample = flacFile->audioProperties()->bitsPerSample();
|
||||||
}
|
}
|
||||||
else if (const auto* mp4File{ dynamic_cast<const ::TagLib::MP4::File*>(&file) })
|
else if (const auto* mp4File{ dynamic_cast<const ::TagLib::MP4::File*>(&file) })
|
||||||
{
|
{
|
||||||
audioProperties.container = core::media::ContainerType::MP4;
|
audioProperties.container = core::media::Container::MP4;
|
||||||
switch (mp4File->audioProperties()->codec())
|
switch (mp4File->audioProperties()->codec())
|
||||||
{
|
{
|
||||||
case ::TagLib::MP4::Properties::Codec::AAC:
|
case ::TagLib::MP4::Properties::Codec::AAC:
|
||||||
audioProperties.codec = core::media::CodecType::AAC;
|
audioProperties.codec = core::media::Codec::AAC;
|
||||||
break;
|
break;
|
||||||
case ::TagLib::MP4::Properties::Codec::ALAC:
|
case ::TagLib::MP4::Properties::Codec::ALAC:
|
||||||
audioProperties.codec = core::media::CodecType::ALAC;
|
audioProperties.codec = core::media::Codec::ALAC;
|
||||||
break;
|
break;
|
||||||
case ::TagLib::MP4::Properties::Codec::Unknown:
|
case ::TagLib::MP4::Properties::Codec::Unknown:
|
||||||
LMS_LOG(AUDIO, DEBUG, "Unhandled MP4 codec in " << filePath);
|
LMS_LOG(AUDIO, DEBUG, "Unhandled MP4 codec in " << filePath);
|
||||||
@@ -167,15 +167,15 @@ namespace lms::audio::taglib
|
|||||||
}
|
}
|
||||||
else if (const auto* mpcFile{ dynamic_cast<const ::TagLib::MPC::File*>(&file) })
|
else if (const auto* mpcFile{ dynamic_cast<const ::TagLib::MPC::File*>(&file) })
|
||||||
{
|
{
|
||||||
audioProperties.container = core::media::ContainerType::MPC;
|
audioProperties.container = core::media::Container::MPC;
|
||||||
|
|
||||||
switch (mpcFile->audioProperties()->mpcVersion())
|
switch (mpcFile->audioProperties()->mpcVersion())
|
||||||
{
|
{
|
||||||
case 7:
|
case 7:
|
||||||
audioProperties.codec = core::media::CodecType::MPC7;
|
audioProperties.codec = core::media::Codec::MPC7;
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
audioProperties.codec = core::media::CodecType::MPC8;
|
audioProperties.codec = core::media::Codec::MPC8;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LMS_LOG(AUDIO, DEBUG, "Unhandled MPC codec version " << mpcFile->audioProperties()->mpcVersion() << " in " << filePath);
|
LMS_LOG(AUDIO, DEBUG, "Unhandled MPC codec version " << mpcFile->audioProperties()->mpcVersion() << " in " << filePath);
|
||||||
@@ -186,13 +186,13 @@ namespace lms::audio::taglib
|
|||||||
{
|
{
|
||||||
const auto& properties{ *mpegFile->audioProperties() };
|
const auto& properties{ *mpegFile->audioProperties() };
|
||||||
|
|
||||||
audioProperties.container = core::media::ContainerType::MPEG;
|
audioProperties.container = core::media::Container::MPEG;
|
||||||
if ((properties.version() == TagLib::MPEG::Header::Version::Version1 || properties.version() == TagLib::MPEG::Header::Version::Version2 || properties.version() == TagLib::MPEG::Header::Version::Version2_5)
|
if ((properties.version() == TagLib::MPEG::Header::Version::Version1 || properties.version() == TagLib::MPEG::Header::Version::Version2 || properties.version() == TagLib::MPEG::Header::Version::Version2_5)
|
||||||
&& mpegFile->audioProperties()->layer() == 3)
|
&& mpegFile->audioProperties()->layer() == 3)
|
||||||
audioProperties.codec = core::media::CodecType::MP3; // could be MPEG-1 layer 3 or MPEG-2(.5) layer 3
|
audioProperties.codec = core::media::Codec::MP3; // could be MPEG-1 layer 3 or MPEG-2(.5) layer 3
|
||||||
#if LMS_TAGLIB_HAS_ADTS
|
#if LMS_TAGLIB_HAS_ADTS
|
||||||
else if (mpegFile->audioProperties()->isADTS()) // likely AAC
|
else if (mpegFile->audioProperties()->isADTS()) // likely AAC
|
||||||
audioProperties.codec = core::media::CodecType::AAC;
|
audioProperties.codec = core::media::Codec::AAC;
|
||||||
#endif
|
#endif
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -202,44 +202,44 @@ namespace lms::audio::taglib
|
|||||||
}
|
}
|
||||||
else if (dynamic_cast<const ::TagLib::Ogg::Opus::File*>(&file))
|
else if (dynamic_cast<const ::TagLib::Ogg::Opus::File*>(&file))
|
||||||
{
|
{
|
||||||
audioProperties.container = core::media::ContainerType::Ogg;
|
audioProperties.container = core::media::Container::Ogg;
|
||||||
audioProperties.codec = core::media::CodecType::Opus;
|
audioProperties.codec = core::media::Codec::Opus;
|
||||||
}
|
}
|
||||||
else if (dynamic_cast<const ::TagLib::Ogg::Vorbis::File*>(&file))
|
else if (dynamic_cast<const ::TagLib::Ogg::Vorbis::File*>(&file))
|
||||||
{
|
{
|
||||||
audioProperties.container = core::media::ContainerType::Ogg;
|
audioProperties.container = core::media::Container::Ogg;
|
||||||
audioProperties.codec = core::media::CodecType::Vorbis;
|
audioProperties.codec = core::media::Codec::Vorbis;
|
||||||
}
|
}
|
||||||
else if (const auto* aiffFile{ dynamic_cast<const ::TagLib::RIFF::AIFF::File*>(&file) })
|
else if (const auto* aiffFile{ dynamic_cast<const ::TagLib::RIFF::AIFF::File*>(&file) })
|
||||||
{
|
{
|
||||||
audioProperties.container = core::media::ContainerType::AIFF;
|
audioProperties.container = core::media::Container::AIFF;
|
||||||
audioProperties.codec = core::media::CodecType::PCM;
|
audioProperties.codec = core::media::Codec::PCM;
|
||||||
audioProperties.bitsPerSample = aiffFile->audioProperties()->bitsPerSample();
|
audioProperties.bitsPerSample = aiffFile->audioProperties()->bitsPerSample();
|
||||||
}
|
}
|
||||||
else if (const auto* wavFile{ dynamic_cast<const ::TagLib::RIFF::WAV::File*>(&file) })
|
else if (const auto* wavFile{ dynamic_cast<const ::TagLib::RIFF::WAV::File*>(&file) })
|
||||||
{
|
{
|
||||||
audioProperties.container = core::media::ContainerType::WAV;
|
audioProperties.container = core::media::Container::WAV;
|
||||||
audioProperties.codec = core::media::CodecType::PCM;
|
audioProperties.codec = core::media::Codec::PCM;
|
||||||
audioProperties.bitsPerSample = wavFile->audioProperties()->bitsPerSample();
|
audioProperties.bitsPerSample = wavFile->audioProperties()->bitsPerSample();
|
||||||
}
|
}
|
||||||
#if LMS_TAGLIB_HAS_SHORTEN
|
#if LMS_TAGLIB_HAS_SHORTEN
|
||||||
else if (const auto* shortenFile{ dynamic_cast<const ::TagLib::Shorten::File*>(&file) })
|
else if (const auto* shortenFile{ dynamic_cast<const ::TagLib::Shorten::File*>(&file) })
|
||||||
{
|
{
|
||||||
audioProperties.container = core::media::ContainerType::Shorten;
|
audioProperties.container = core::media::Container::Shorten;
|
||||||
audioProperties.codec = core::media::CodecType::Shorten;
|
audioProperties.codec = core::media::Codec::Shorten;
|
||||||
audioProperties.bitsPerSample = shortenFile->audioProperties()->bitsPerSample();
|
audioProperties.bitsPerSample = shortenFile->audioProperties()->bitsPerSample();
|
||||||
}
|
}
|
||||||
#endif // LMS_TAGLIB_HAS_SHORTEN
|
#endif // LMS_TAGLIB_HAS_SHORTEN
|
||||||
else if (const auto* trueAudioFile{ dynamic_cast<const ::TagLib::TrueAudio::File*>(&file) })
|
else if (const auto* trueAudioFile{ dynamic_cast<const ::TagLib::TrueAudio::File*>(&file) })
|
||||||
{
|
{
|
||||||
audioProperties.container = core::media::ContainerType::TrueAudio;
|
audioProperties.container = core::media::Container::TrueAudio;
|
||||||
audioProperties.codec = core::media::CodecType::TrueAudio;
|
audioProperties.codec = core::media::Codec::TrueAudio;
|
||||||
audioProperties.bitsPerSample = trueAudioFile->audioProperties()->bitsPerSample();
|
audioProperties.bitsPerSample = trueAudioFile->audioProperties()->bitsPerSample();
|
||||||
}
|
}
|
||||||
else if (const auto* wavPackFile{ dynamic_cast<const ::TagLib::WavPack::File*>(&file) })
|
else if (const auto* wavPackFile{ dynamic_cast<const ::TagLib::WavPack::File*>(&file) })
|
||||||
{
|
{
|
||||||
audioProperties.container = core::media::ContainerType::WavPack;
|
audioProperties.container = core::media::Container::WavPack;
|
||||||
audioProperties.codec = core::media::CodecType::WavPack;
|
audioProperties.codec = core::media::Codec::WavPack;
|
||||||
audioProperties.bitsPerSample = wavPackFile->audioProperties()->bitsPerSample();
|
audioProperties.bitsPerSample = wavPackFile->audioProperties()->bitsPerSample();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -22,15 +22,15 @@
|
|||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
#include "core/media/CodecType.hpp"
|
#include "core/media/Codec.hpp"
|
||||||
#include "core/media/ContainerType.hpp"
|
#include "core/media/Container.hpp"
|
||||||
|
|
||||||
namespace lms::audio
|
namespace lms::audio
|
||||||
{
|
{
|
||||||
struct AudioProperties
|
struct AudioProperties
|
||||||
{
|
{
|
||||||
core::media::ContainerType container;
|
core::media::Container container;
|
||||||
core::media::CodecType codec;
|
core::media::Codec codec;
|
||||||
std::chrono::milliseconds duration;
|
std::chrono::milliseconds duration;
|
||||||
unsigned bitrate;
|
unsigned bitrate;
|
||||||
unsigned channelCount;
|
unsigned channelCount;
|
||||||
|
|||||||
@@ -23,8 +23,8 @@
|
|||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
#include "core/media/CodecType.hpp"
|
#include "core/media/Codec.hpp"
|
||||||
#include "core/media/ContainerType.hpp"
|
#include "core/media/Container.hpp"
|
||||||
|
|
||||||
#include "audio/AudioProperties.hpp"
|
#include "audio/AudioProperties.hpp"
|
||||||
|
|
||||||
@@ -39,8 +39,8 @@ namespace lms::audio
|
|||||||
|
|
||||||
struct TranscodeOutputFormat
|
struct TranscodeOutputFormat
|
||||||
{
|
{
|
||||||
core::media::ContainerType container;
|
core::media::Container container;
|
||||||
core::media::CodecType codec;
|
core::media::Codec codec;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TranscodeOutputParameters
|
struct TranscodeOutputParameters
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ configure_file(
|
|||||||
add_library(lmscore STATIC
|
add_library(lmscore STATIC
|
||||||
impl/http/Client.cpp
|
impl/http/Client.cpp
|
||||||
impl/http/SendQueue.cpp
|
impl/http/SendQueue.cpp
|
||||||
impl/media/CodecType.cpp
|
impl/media/Codec.cpp
|
||||||
impl/media/ContainerType.cpp
|
impl/media/Container.cpp
|
||||||
impl/media/ImageType.cpp
|
impl/media/ImageType.cpp
|
||||||
impl/media/MimeType.cpp
|
impl/media/MimeType.cpp
|
||||||
impl/ArchiveZipper.cpp
|
impl/ArchiveZipper.cpp
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2025 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 "core/media/Codec.hpp"
|
||||||
|
#include "core/Exception.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
namespace lms::core::media
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
constexpr std::array codecDescs{
|
||||||
|
CodecDesc{ Codec::AAC, "AAC", "Advanced Audio Coding", false },
|
||||||
|
CodecDesc{ Codec::AC3, "AC3", "Dolby AC-3", false },
|
||||||
|
CodecDesc{ Codec::ALAC, "ALAC", "Apple Lossless Audio Codec", true },
|
||||||
|
CodecDesc{ Codec::APE, "APE", "Monkey's Audio", true },
|
||||||
|
CodecDesc{ Codec::DSD, "DSD", "Direct Stream Digital", true },
|
||||||
|
CodecDesc{ Codec::EAC3, "E-AC3", "Dolby Digital Plus", false },
|
||||||
|
CodecDesc{ Codec::FLAC, "FLAC", "Free Lossless Audio Codec", true },
|
||||||
|
CodecDesc{ Codec::MP3, "MP3", "MPEG-3", false },
|
||||||
|
CodecDesc{ Codec::MP4ALS, "MP4ALS", "MPEG-4 Audio Lossless Coding", true },
|
||||||
|
CodecDesc{ Codec::MPC7, "MPC7", "Musepack7", false },
|
||||||
|
CodecDesc{ Codec::MPC8, "MPC8", "Musepack8", false },
|
||||||
|
CodecDesc{ Codec::Opus, "Opus", "Opus", false },
|
||||||
|
CodecDesc{ Codec::PCM, "PCM", "Pulse-code modulation", false },
|
||||||
|
CodecDesc{ Codec::Shorten, "Shorten", "Shorten", true },
|
||||||
|
CodecDesc{ Codec::TrueAudio, "TTA", "The True Audio", true },
|
||||||
|
CodecDesc{ Codec::Vorbis, "Vorbis", "Vorbis", false },
|
||||||
|
CodecDesc{ Codec::WavPack, "WavPack", "WavPack", true },
|
||||||
|
CodecDesc{ Codec::WMA1, "WMA1", "Windows Media Audio", false },
|
||||||
|
CodecDesc{ Codec::WMA2, "WMA2", "Windows Media Audio 2", false },
|
||||||
|
CodecDesc{ Codec::WMA9Pro, "WMA9Pro", "Windows Media Audio Professional", false },
|
||||||
|
CodecDesc{ Codec::WMA9Lossless, "WMA9Lossless", "Windows Media Audio Lossless", true },
|
||||||
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
void visitCodecs(const std::function<void(const CodecDesc&)>& visitor)
|
||||||
|
{
|
||||||
|
std::for_each(std::cbegin(codecDescs), std::cend(codecDescs), visitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
const CodecDesc& getCodecDesc(Codec type)
|
||||||
|
{
|
||||||
|
const auto it{ std::find_if(codecDescs.begin(), codecDescs.end(), [type](const auto& desc) { return desc.type == type; }) };
|
||||||
|
if (it == codecDescs.end()) [[unlikely]]
|
||||||
|
throw LmsException{ "Unknown codec type" };
|
||||||
|
|
||||||
|
return *it;
|
||||||
|
}
|
||||||
|
} // namespace lms::core::media
|
||||||
@@ -1,108 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2025 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 "core/media/CodecType.hpp"
|
|
||||||
|
|
||||||
namespace lms::core::media
|
|
||||||
{
|
|
||||||
core::LiteralString codecTypeToString(CodecType type)
|
|
||||||
{
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case CodecType::AAC:
|
|
||||||
return "AAC";
|
|
||||||
case CodecType::AC3:
|
|
||||||
return "AC3";
|
|
||||||
case CodecType::ALAC:
|
|
||||||
return "ALAC";
|
|
||||||
case CodecType::APE:
|
|
||||||
return "APE";
|
|
||||||
case CodecType::DSD:
|
|
||||||
return "DSD";
|
|
||||||
case CodecType::EAC3:
|
|
||||||
return "E-AC3";
|
|
||||||
case CodecType::FLAC:
|
|
||||||
return "FLAC";
|
|
||||||
case CodecType::MP3:
|
|
||||||
return "MP3";
|
|
||||||
case CodecType::MP4ALS:
|
|
||||||
return "MP4ALS";
|
|
||||||
case CodecType::MPC7:
|
|
||||||
return "MPC7";
|
|
||||||
case CodecType::MPC8:
|
|
||||||
return "MPC8";
|
|
||||||
case CodecType::Opus:
|
|
||||||
return "Opus";
|
|
||||||
case CodecType::PCM:
|
|
||||||
return "PCM";
|
|
||||||
case CodecType::Shorten:
|
|
||||||
return "Shorten";
|
|
||||||
case CodecType::TrueAudio:
|
|
||||||
return "TrueAudio";
|
|
||||||
case CodecType::Vorbis:
|
|
||||||
return "Vorbis";
|
|
||||||
case CodecType::WavPack:
|
|
||||||
return "WavPack";
|
|
||||||
case CodecType::WMA1:
|
|
||||||
return "WMA1";
|
|
||||||
case CodecType::WMA2:
|
|
||||||
return "WMA2";
|
|
||||||
case CodecType::WMA9Pro:
|
|
||||||
return "WMA9Pro";
|
|
||||||
case CodecType::WMA9Lossless:
|
|
||||||
return "WMA9Lossless";
|
|
||||||
}
|
|
||||||
|
|
||||||
return "Unknown";
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isCodecLossless(CodecType type)
|
|
||||||
{
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case CodecType::ALAC:
|
|
||||||
case CodecType::APE:
|
|
||||||
case CodecType::DSD:
|
|
||||||
|
|
||||||
case CodecType::FLAC:
|
|
||||||
case CodecType::MP4ALS:
|
|
||||||
case CodecType::PCM:
|
|
||||||
case CodecType::Shorten:
|
|
||||||
case CodecType::TrueAudio:
|
|
||||||
case CodecType::WavPack:
|
|
||||||
case CodecType::WMA9Lossless:
|
|
||||||
return true;
|
|
||||||
|
|
||||||
case CodecType::AAC:
|
|
||||||
case CodecType::AC3:
|
|
||||||
case CodecType::EAC3:
|
|
||||||
case CodecType::MP3:
|
|
||||||
case CodecType::MPC7:
|
|
||||||
case CodecType::MPC8:
|
|
||||||
case CodecType::Opus:
|
|
||||||
case CodecType::Vorbis:
|
|
||||||
case CodecType::WMA1:
|
|
||||||
case CodecType::WMA2:
|
|
||||||
case CodecType::WMA9Pro:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} // namespace lms::core::media
|
|
||||||
+15
-15
@@ -17,39 +17,39 @@
|
|||||||
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
|
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "core/media/ContainerType.hpp"
|
#include "core/media/Container.hpp"
|
||||||
|
|
||||||
namespace lms::core::media
|
namespace lms::core::media
|
||||||
{
|
{
|
||||||
core::LiteralString containerTypeToString(ContainerType type)
|
core::LiteralString containerToString(Container type)
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case ContainerType::AIFF:
|
case Container::AIFF:
|
||||||
return "AIFF";
|
return "AIFF";
|
||||||
case ContainerType::APE:
|
case Container::APE:
|
||||||
return "APE";
|
return "APE";
|
||||||
case ContainerType::ASF:
|
case Container::ASF:
|
||||||
return "ASF";
|
return "ASF";
|
||||||
case ContainerType::DSF:
|
case Container::DSF:
|
||||||
return "DSF";
|
return "DSF";
|
||||||
case ContainerType::FLAC:
|
case Container::FLAC:
|
||||||
return "FLAC";
|
return "FLAC";
|
||||||
case ContainerType::MP4:
|
case Container::MP4:
|
||||||
return "MP4";
|
return "MP4";
|
||||||
case ContainerType::MPC:
|
case Container::MPC:
|
||||||
return "MPC";
|
return "MPC";
|
||||||
case ContainerType::MPEG:
|
case Container::MPEG:
|
||||||
return "MPEG";
|
return "MPEG";
|
||||||
case ContainerType::Ogg:
|
case Container::Ogg:
|
||||||
return "Ogg";
|
return "Ogg";
|
||||||
case ContainerType::Shorten:
|
case Container::Shorten:
|
||||||
return "Shorten";
|
return "Shorten";
|
||||||
case ContainerType::TrueAudio:
|
case Container::TrueAudio:
|
||||||
return "TrueAudio";
|
return "TrueAudio";
|
||||||
case ContainerType::WAV:
|
case Container::WAV:
|
||||||
return "WAV";
|
return "WAV";
|
||||||
case ContainerType::WavPack:
|
case Container::WavPack:
|
||||||
return "WavPack";
|
return "WavPack";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -21,57 +21,57 @@
|
|||||||
|
|
||||||
namespace lms::core::media
|
namespace lms::core::media
|
||||||
{
|
{
|
||||||
core::LiteralString getMimeType(ContainerType container, CodecType codec)
|
core::LiteralString getMimeType(Container container, Codec codec)
|
||||||
{
|
{
|
||||||
switch (container)
|
switch (container)
|
||||||
{
|
{
|
||||||
case ContainerType::AIFF:
|
case Container::AIFF:
|
||||||
return "audio/x-aiff";
|
return "audio/x-aiff";
|
||||||
case ContainerType::APE:
|
case Container::APE:
|
||||||
return "audio/x-monkeys-audio";
|
return "audio/x-monkeys-audio";
|
||||||
case ContainerType::ASF:
|
case Container::ASF:
|
||||||
return "audio/x-ms-wma";
|
return "audio/x-ms-wma";
|
||||||
case ContainerType::DSF:
|
case Container::DSF:
|
||||||
return "audio/x-dsd-dsf";
|
return "audio/x-dsd-dsf";
|
||||||
case ContainerType::FLAC:
|
case Container::FLAC:
|
||||||
return "audio/flac";
|
return "audio/flac";
|
||||||
case ContainerType::MP4:
|
case Container::MP4:
|
||||||
switch (codec)
|
switch (codec)
|
||||||
{
|
{
|
||||||
case CodecType::AAC:
|
case Codec::AAC:
|
||||||
return "audio/mp4; codecs=\"mp4a.40.2\"";
|
return "audio/mp4; codecs=\"mp4a.40.2\"";
|
||||||
case CodecType::ALAC:
|
case Codec::ALAC:
|
||||||
return "audio/mp4; codecs=\"alac\"";
|
return "audio/mp4; codecs=\"alac\"";
|
||||||
case CodecType::MP4ALS:
|
case Codec::MP4ALS:
|
||||||
return "audio/mp4; codecs=\"mp4als\"";
|
return "audio/mp4; codecs=\"mp4als\"";
|
||||||
default:
|
default:
|
||||||
return "audio/mp4";
|
return "audio/mp4";
|
||||||
}
|
}
|
||||||
|
|
||||||
case ContainerType::MPC:
|
case Container::MPC:
|
||||||
return "audio/x-musepack";
|
return "audio/x-musepack";
|
||||||
case ContainerType::MPEG:
|
case Container::MPEG:
|
||||||
return "audio/mpeg";
|
return "audio/mpeg";
|
||||||
case ContainerType::Ogg:
|
case Container::Ogg:
|
||||||
switch (codec)
|
switch (codec)
|
||||||
{
|
{
|
||||||
case CodecType::Opus:
|
case Codec::Opus:
|
||||||
return "audio/opus";
|
return "audio/opus";
|
||||||
case CodecType::Vorbis:
|
case Codec::Vorbis:
|
||||||
return "audio/ogg; codecs=\"vorbis\"";
|
return "audio/ogg; codecs=\"vorbis\"";
|
||||||
case CodecType::FLAC:
|
case Codec::FLAC:
|
||||||
return "audio/ogg; codecs=\"flac\"";
|
return "audio/ogg; codecs=\"flac\"";
|
||||||
default:
|
default:
|
||||||
return "audio/ogg";
|
return "audio/ogg";
|
||||||
}
|
}
|
||||||
|
|
||||||
case ContainerType::Shorten:
|
case Container::Shorten:
|
||||||
return "audio/x-shn";
|
return "audio/x-shn";
|
||||||
case ContainerType::TrueAudio:
|
case Container::TrueAudio:
|
||||||
return "audio/x-tta";
|
return "audio/x-tta";
|
||||||
case ContainerType::WAV:
|
case Container::WAV:
|
||||||
return "audio/wav";
|
return "audio/wav";
|
||||||
case ContainerType::WavPack:
|
case Container::WavPack:
|
||||||
return "audio/x-wavpack";
|
return "audio/x-wavpack";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+12
-4
@@ -19,11 +19,13 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
#include "core/LiteralString.hpp"
|
#include "core/LiteralString.hpp"
|
||||||
|
|
||||||
namespace lms::core::media
|
namespace lms::core::media
|
||||||
{
|
{
|
||||||
enum class CodecType
|
enum class Codec
|
||||||
{
|
{
|
||||||
AAC,
|
AAC,
|
||||||
AC3,
|
AC3,
|
||||||
@@ -48,7 +50,13 @@ namespace lms::core::media
|
|||||||
WMA9Lossless,
|
WMA9Lossless,
|
||||||
};
|
};
|
||||||
|
|
||||||
core::LiteralString codecTypeToString(CodecType type);
|
struct CodecDesc
|
||||||
|
{
|
||||||
bool isCodecLossless(CodecType type);
|
Codec type;
|
||||||
|
core::LiteralString name;
|
||||||
|
core::LiteralString longName;
|
||||||
|
bool isLossless;
|
||||||
|
};
|
||||||
|
void visitCodecs(const std::function<void(const CodecDesc&)>& visitor);
|
||||||
|
const CodecDesc& getCodecDesc(Codec type);
|
||||||
} // namespace lms::core::media
|
} // namespace lms::core::media
|
||||||
+2
-2
@@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
namespace lms::core::media
|
namespace lms::core::media
|
||||||
{
|
{
|
||||||
enum class ContainerType
|
enum class Container
|
||||||
{
|
{
|
||||||
AIFF,
|
AIFF,
|
||||||
APE, // Monkey's Audio
|
APE, // Monkey's Audio
|
||||||
@@ -40,5 +40,5 @@ namespace lms::core::media
|
|||||||
WavPack,
|
WavPack,
|
||||||
};
|
};
|
||||||
|
|
||||||
core::LiteralString containerTypeToString(ContainerType type);
|
core::LiteralString containerToString(Container type);
|
||||||
} // namespace lms::core::media
|
} // namespace lms::core::media
|
||||||
@@ -20,10 +20,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "core/LiteralString.hpp"
|
#include "core/LiteralString.hpp"
|
||||||
#include "core/media/CodecType.hpp"
|
#include "core/media/Codec.hpp"
|
||||||
#include "core/media/ContainerType.hpp"
|
#include "core/media/Container.hpp"
|
||||||
|
|
||||||
namespace lms::core::media
|
namespace lms::core::media
|
||||||
{
|
{
|
||||||
core::LiteralString getMimeType(ContainerType container, CodecType codec);
|
core::LiteralString getMimeType(Container container, Codec codec);
|
||||||
}
|
}
|
||||||
@@ -83,7 +83,7 @@ namespace lms::db
|
|||||||
query.where("t.release_id = ?").bind(params.release);
|
query.where("t.release_id = ?").bind(params.release);
|
||||||
|
|
||||||
if (params.filters.codec.has_value())
|
if (params.filters.codec.has_value())
|
||||||
query.where("t.codec = ?").bind(detail::getDbCodecType(*params.filters.codec));
|
query.where("t.codec = ?").bind(detail::getDbCodec(*params.filters.codec));
|
||||||
|
|
||||||
if (params.filters.mediaLibrary.isValid())
|
if (params.filters.mediaLibrary.isValid())
|
||||||
query.where("t.media_library_id = ?").bind(params.filters.mediaLibrary);
|
query.where("t.media_library_id = ?").bind(params.filters.mediaLibrary);
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ namespace lms::db
|
|||||||
query.join("track t ON t.id = t_a_l.track_id");
|
query.join("track t ON t.id = t_a_l.track_id");
|
||||||
|
|
||||||
if (params.filters.codec.has_value())
|
if (params.filters.codec.has_value())
|
||||||
query.where("t.codec = ?").bind(detail::getDbCodecType(*params.filters.codec));
|
query.where("t.codec = ?").bind(detail::getDbCodec(*params.filters.codec));
|
||||||
|
|
||||||
if (params.filters.mediaLibrary.isValid())
|
if (params.filters.mediaLibrary.isValid())
|
||||||
query.where("t.media_library_id = ?").bind(params.filters.mediaLibrary);
|
query.where("t.media_library_id = ?").bind(params.filters.mediaLibrary);
|
||||||
|
|||||||
@@ -99,12 +99,12 @@ namespace lms::db
|
|||||||
utils::forEachQueryRangeResult(query, params.range, func);
|
utils::forEachQueryRangeResult(query, params.range, func);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<core::media::ContainerType> PodcastEpisode::getContainer() const
|
std::optional<core::media::Container> PodcastEpisode::getContainer() const
|
||||||
{
|
{
|
||||||
return detail::getMediaContainerType(_container);
|
return detail::getMediaContainerType(_container);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<core::media::CodecType> PodcastEpisode::getCodec() const
|
std::optional<core::media::Codec> PodcastEpisode::getCodec() const
|
||||||
{
|
{
|
||||||
return detail::getMediaCodecType(_codec);
|
return detail::getMediaCodecType(_codec);
|
||||||
}
|
}
|
||||||
@@ -119,14 +119,14 @@ namespace lms::db
|
|||||||
return _artwork.id();
|
return _artwork.id();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PodcastEpisode::setContainer(core::media::ContainerType container)
|
void PodcastEpisode::setContainer(core::media::Container container)
|
||||||
{
|
{
|
||||||
_container = detail::getDbContainerType(container);
|
_container = detail::getDbContainer(container);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PodcastEpisode::setCodec(core::media::CodecType codec)
|
void PodcastEpisode::setCodec(core::media::Codec codec)
|
||||||
{
|
{
|
||||||
_codec = detail::getDbCodecType(codec);
|
_codec = detail::getDbCodec(codec);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PodcastEpisode::setArtwork(ObjectPtr<Artwork> artwork)
|
void PodcastEpisode::setArtwork(ObjectPtr<Artwork> artwork)
|
||||||
|
|||||||
@@ -220,7 +220,7 @@ namespace lms::db
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (params.filters.codec.has_value())
|
if (params.filters.codec.has_value())
|
||||||
query.where("t.codec = ?").bind(detail::getDbCodecType(params.filters.codec.value()));
|
query.where("t.codec = ?").bind(detail::getDbCodec(params.filters.codec.value()));
|
||||||
|
|
||||||
if (params.releaseGroupMBID)
|
if (params.releaseGroupMBID)
|
||||||
query.where("group_mbid = ?").bind(params.releaseGroupMBID->getAsString());
|
query.where("group_mbid = ?").bind(params.releaseGroupMBID->getAsString());
|
||||||
@@ -684,15 +684,15 @@ namespace lms::db
|
|||||||
return utils::fetchQuerySingleResult(session()->query<int>("SELECT COALESCE(AVG(t.bitrate), 0) FROM track t").where("release_id = ?").bind(getId()).where("bitrate > 0"));
|
return utils::fetchQuerySingleResult(session()->query<int>("SELECT COALESCE(AVG(t.bitrate), 0) FROM track t").where("release_id = ?").bind(getId()).where("bitrate > 0"));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<core::media::CodecType> Release::getCodecs() const
|
std::vector<core::media::Codec> Release::getCodecs() const
|
||||||
{
|
{
|
||||||
assert(session());
|
assert(session());
|
||||||
|
|
||||||
// Get the codec ordered by frequency
|
// Get the codec ordered by frequency
|
||||||
auto query{ session()->query<detail::CodecType>("SELECT t.codec FROM track t").where("release_id = ?").bind(getId()).groupBy("t.codec").orderBy("COUNT(t.id) DESC") };
|
auto query{ session()->query<detail::Codec>("SELECT t.codec FROM track t").where("release_id = ?").bind(getId()).groupBy("t.codec").orderBy("COUNT(t.id) DESC") };
|
||||||
|
|
||||||
std::vector<core::media::CodecType> res;
|
std::vector<core::media::Codec> res;
|
||||||
utils::forEachQueryResult(query, [&](detail::CodecType codec) {
|
utils::forEachQueryResult(query, [&](detail::Codec codec) {
|
||||||
if (const auto mediaCodecType{ detail::getMediaCodecType(codec) })
|
if (const auto mediaCodecType{ detail::getMediaCodecType(codec) })
|
||||||
res.push_back(*mediaCodecType);
|
res.push_back(*mediaCodecType);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -198,7 +198,7 @@ namespace lms::db
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (params.filters.codec.has_value())
|
if (params.filters.codec.has_value())
|
||||||
query.where("t.codec = ?").bind(detail::getDbCodecType(*params.filters.codec));
|
query.where("t.codec = ?").bind(detail::getDbCodec(*params.filters.codec));
|
||||||
|
|
||||||
switch (params.sortMethod)
|
switch (params.sortMethod)
|
||||||
{
|
{
|
||||||
@@ -528,14 +528,14 @@ namespace lms::db
|
|||||||
_absoluteFilePath = filePath;
|
_absoluteFilePath = filePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Track::setContainer(core::media::ContainerType container)
|
void Track::setContainer(core::media::Container container)
|
||||||
{
|
{
|
||||||
_container = detail::getDbContainerType(container);
|
_container = detail::getDbContainer(container);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Track::setCodec(core::media::CodecType codec)
|
void Track::setCodec(core::media::Codec codec)
|
||||||
{
|
{
|
||||||
_codec = detail::getDbCodecType(codec);
|
_codec = detail::getDbCodec(codec);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Track::setName(std::string_view name)
|
void Track::setName(std::string_view name)
|
||||||
@@ -618,12 +618,12 @@ namespace lms::db
|
|||||||
_preferredMediaArtwork = getDboPtr(artwork);
|
_preferredMediaArtwork = getDboPtr(artwork);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<core::media::ContainerType> Track::getContainer() const
|
std::optional<core::media::Container> Track::getContainer() const
|
||||||
{
|
{
|
||||||
return detail::getMediaContainerType(_container);
|
return detail::getMediaContainerType(_container);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<core::media::CodecType> Track::getCodec() const
|
std::optional<core::media::Codec> Track::getCodec() const
|
||||||
{
|
{
|
||||||
return detail::getMediaCodecType(_codec);
|
return detail::getMediaCodecType(_codec);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ namespace lms::db
|
|||||||
query.join("track t ON t.id = t_l_e.track_id");
|
query.join("track t ON t.id = t_l_e.track_id");
|
||||||
|
|
||||||
if (params.filters.codec.has_value())
|
if (params.filters.codec.has_value())
|
||||||
query.where("t.codec = ?").bind(detail::getDbCodecType(*params.filters.codec));
|
query.where("t.codec = ?").bind(detail::getDbCodec(*params.filters.codec));
|
||||||
|
|
||||||
if (params.filters.mediaLibrary.isValid())
|
if (params.filters.mediaLibrary.isValid())
|
||||||
query.where("t.media_library_id = ?").bind(params.filters.mediaLibrary);
|
query.where("t.media_library_id = ?").bind(params.filters.mediaLibrary);
|
||||||
|
|||||||
@@ -21,182 +21,182 @@
|
|||||||
|
|
||||||
namespace lms::db::detail
|
namespace lms::db::detail
|
||||||
{
|
{
|
||||||
std::optional<core::media::ContainerType> getMediaContainerType(db::detail::ContainerType container)
|
std::optional<core::media::Container> getMediaContainerType(db::detail::Container container)
|
||||||
{
|
{
|
||||||
switch (container)
|
switch (container)
|
||||||
{
|
{
|
||||||
case ContainerType::AIFF:
|
case Container::AIFF:
|
||||||
return core::media::ContainerType::AIFF;
|
return core::media::Container::AIFF;
|
||||||
case ContainerType::APE:
|
case Container::APE:
|
||||||
return core::media::ContainerType::APE;
|
return core::media::Container::APE;
|
||||||
case ContainerType::ASF:
|
case Container::ASF:
|
||||||
return core::media::ContainerType::ASF;
|
return core::media::Container::ASF;
|
||||||
case ContainerType::DSF:
|
case Container::DSF:
|
||||||
return core::media::ContainerType::DSF;
|
return core::media::Container::DSF;
|
||||||
case ContainerType::FLAC:
|
case Container::FLAC:
|
||||||
return core::media::ContainerType::FLAC;
|
return core::media::Container::FLAC;
|
||||||
case ContainerType::MP4:
|
case Container::MP4:
|
||||||
return core::media::ContainerType::MP4;
|
return core::media::Container::MP4;
|
||||||
case ContainerType::MPC:
|
case Container::MPC:
|
||||||
return core::media::ContainerType::MPC;
|
return core::media::Container::MPC;
|
||||||
case ContainerType::MPEG:
|
case Container::MPEG:
|
||||||
return core::media::ContainerType::MPEG;
|
return core::media::Container::MPEG;
|
||||||
case ContainerType::Ogg:
|
case Container::Ogg:
|
||||||
return core::media::ContainerType::Ogg;
|
return core::media::Container::Ogg;
|
||||||
case ContainerType::Shorten:
|
case Container::Shorten:
|
||||||
return core::media::ContainerType::Shorten;
|
return core::media::Container::Shorten;
|
||||||
case ContainerType::TrueAudio:
|
case Container::TrueAudio:
|
||||||
return core::media::ContainerType::TrueAudio;
|
return core::media::Container::TrueAudio;
|
||||||
case ContainerType::WAV:
|
case Container::WAV:
|
||||||
return core::media::ContainerType::WAV;
|
return core::media::Container::WAV;
|
||||||
case ContainerType::WavPack:
|
case Container::WavPack:
|
||||||
return core::media::ContainerType::WavPack;
|
return core::media::Container::WavPack;
|
||||||
|
|
||||||
case ContainerType::Unknown:
|
case Container::Unknown:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
db::detail::ContainerType getDbContainerType(core::media::ContainerType container)
|
db::detail::Container getDbContainer(core::media::Container container)
|
||||||
{
|
{
|
||||||
switch (container)
|
switch (container)
|
||||||
{
|
{
|
||||||
case core::media::ContainerType::AIFF:
|
case core::media::Container::AIFF:
|
||||||
return ContainerType::AIFF;
|
return Container::AIFF;
|
||||||
case core::media::ContainerType::APE:
|
case core::media::Container::APE:
|
||||||
return ContainerType::APE;
|
return Container::APE;
|
||||||
case core::media::ContainerType::ASF:
|
case core::media::Container::ASF:
|
||||||
return ContainerType::ASF;
|
return Container::ASF;
|
||||||
case core::media::ContainerType::DSF:
|
case core::media::Container::DSF:
|
||||||
return ContainerType::DSF;
|
return Container::DSF;
|
||||||
case core::media::ContainerType::FLAC:
|
case core::media::Container::FLAC:
|
||||||
return ContainerType::FLAC;
|
return Container::FLAC;
|
||||||
case core::media::ContainerType::MP4:
|
case core::media::Container::MP4:
|
||||||
return ContainerType::MP4;
|
return Container::MP4;
|
||||||
case core::media::ContainerType::MPC:
|
case core::media::Container::MPC:
|
||||||
return ContainerType::MPC;
|
return Container::MPC;
|
||||||
case core::media::ContainerType::MPEG:
|
case core::media::Container::MPEG:
|
||||||
return ContainerType::MPEG;
|
return Container::MPEG;
|
||||||
case core::media::ContainerType::Ogg:
|
case core::media::Container::Ogg:
|
||||||
return ContainerType::Ogg;
|
return Container::Ogg;
|
||||||
case core::media::ContainerType::Shorten:
|
case core::media::Container::Shorten:
|
||||||
return ContainerType::Shorten;
|
return Container::Shorten;
|
||||||
case core::media::ContainerType::TrueAudio:
|
case core::media::Container::TrueAudio:
|
||||||
return ContainerType::TrueAudio;
|
return Container::TrueAudio;
|
||||||
case core::media::ContainerType::WAV:
|
case core::media::Container::WAV:
|
||||||
return ContainerType::WAV;
|
return Container::WAV;
|
||||||
case core::media::ContainerType::WavPack:
|
case core::media::Container::WavPack:
|
||||||
return ContainerType::WavPack;
|
return Container::WavPack;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ContainerType::Unknown;
|
return Container::Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<core::media::CodecType> getMediaCodecType(db::detail::CodecType codec)
|
std::optional<core::media::Codec> getMediaCodecType(db::detail::Codec codec)
|
||||||
{
|
{
|
||||||
switch (codec)
|
switch (codec)
|
||||||
{
|
{
|
||||||
case CodecType::AAC:
|
case Codec::AAC:
|
||||||
return core::media::CodecType::AAC;
|
return core::media::Codec::AAC;
|
||||||
case CodecType::AC3:
|
case Codec::AC3:
|
||||||
return core::media::CodecType::AC3;
|
return core::media::Codec::AC3;
|
||||||
case CodecType::ALAC:
|
case Codec::ALAC:
|
||||||
return core::media::CodecType::ALAC;
|
return core::media::Codec::ALAC;
|
||||||
case CodecType::APE:
|
case Codec::APE:
|
||||||
return core::media::CodecType::APE;
|
return core::media::Codec::APE;
|
||||||
case CodecType::DSD:
|
case Codec::DSD:
|
||||||
return core::media::CodecType::DSD;
|
return core::media::Codec::DSD;
|
||||||
case CodecType::EAC3:
|
case Codec::EAC3:
|
||||||
return core::media::CodecType::EAC3;
|
return core::media::Codec::EAC3;
|
||||||
case CodecType::FLAC:
|
case Codec::FLAC:
|
||||||
return core::media::CodecType::FLAC;
|
return core::media::Codec::FLAC;
|
||||||
case CodecType::MP3:
|
case Codec::MP3:
|
||||||
return core::media::CodecType::MP3;
|
return core::media::Codec::MP3;
|
||||||
case CodecType::MP4ALS:
|
case Codec::MP4ALS:
|
||||||
return core::media::CodecType::MP4ALS;
|
return core::media::Codec::MP4ALS;
|
||||||
case CodecType::MPC7:
|
case Codec::MPC7:
|
||||||
return core::media::CodecType::MPC7;
|
return core::media::Codec::MPC7;
|
||||||
case CodecType::MPC8:
|
case Codec::MPC8:
|
||||||
return core::media::CodecType::MPC8;
|
return core::media::Codec::MPC8;
|
||||||
case CodecType::Opus:
|
case Codec::Opus:
|
||||||
return core::media::CodecType::Opus;
|
return core::media::Codec::Opus;
|
||||||
case CodecType::PCM:
|
case Codec::PCM:
|
||||||
return core::media::CodecType::PCM;
|
return core::media::Codec::PCM;
|
||||||
case CodecType::Shorten:
|
case Codec::Shorten:
|
||||||
return core::media::CodecType::Shorten;
|
return core::media::Codec::Shorten;
|
||||||
case CodecType::TrueAudio:
|
case Codec::TrueAudio:
|
||||||
return core::media::CodecType::TrueAudio;
|
return core::media::Codec::TrueAudio;
|
||||||
case CodecType::Vorbis:
|
case Codec::Vorbis:
|
||||||
return core::media::CodecType::Vorbis;
|
return core::media::Codec::Vorbis;
|
||||||
case CodecType::WavPack:
|
case Codec::WavPack:
|
||||||
return core::media::CodecType::WavPack;
|
return core::media::Codec::WavPack;
|
||||||
case CodecType::WMA1:
|
case Codec::WMA1:
|
||||||
return core::media::CodecType::WMA1;
|
return core::media::Codec::WMA1;
|
||||||
case CodecType::WMA2:
|
case Codec::WMA2:
|
||||||
return core::media::CodecType::WMA2;
|
return core::media::Codec::WMA2;
|
||||||
case CodecType::WMA9Pro:
|
case Codec::WMA9Pro:
|
||||||
return core::media::CodecType::WMA9Pro;
|
return core::media::Codec::WMA9Pro;
|
||||||
case CodecType::WMA9Lossless:
|
case Codec::WMA9Lossless:
|
||||||
return core::media::CodecType::WMA9Lossless;
|
return core::media::Codec::WMA9Lossless;
|
||||||
|
|
||||||
case CodecType::Unknown:
|
case Codec::Unknown:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
db::detail::CodecType getDbCodecType(core::media::CodecType codec)
|
db::detail::Codec getDbCodec(core::media::Codec codec)
|
||||||
{
|
{
|
||||||
switch (codec)
|
switch (codec)
|
||||||
{
|
{
|
||||||
case core::media::CodecType::AAC:
|
case core::media::Codec::AAC:
|
||||||
return CodecType::AAC;
|
return Codec::AAC;
|
||||||
case core::media::CodecType::AC3:
|
case core::media::Codec::AC3:
|
||||||
return CodecType::AC3;
|
return Codec::AC3;
|
||||||
case core::media::CodecType::ALAC:
|
case core::media::Codec::ALAC:
|
||||||
return CodecType::ALAC;
|
return Codec::ALAC;
|
||||||
case core::media::CodecType::APE:
|
case core::media::Codec::APE:
|
||||||
return CodecType::APE;
|
return Codec::APE;
|
||||||
case core::media::CodecType::DSD:
|
case core::media::Codec::DSD:
|
||||||
return CodecType::DSD;
|
return Codec::DSD;
|
||||||
case core::media::CodecType::EAC3:
|
case core::media::Codec::EAC3:
|
||||||
return CodecType::EAC3;
|
return Codec::EAC3;
|
||||||
case core::media::CodecType::FLAC:
|
case core::media::Codec::FLAC:
|
||||||
return CodecType::FLAC;
|
return Codec::FLAC;
|
||||||
case core::media::CodecType::MP3:
|
case core::media::Codec::MP3:
|
||||||
return CodecType::MP3;
|
return Codec::MP3;
|
||||||
case core::media::CodecType::MP4ALS:
|
case core::media::Codec::MP4ALS:
|
||||||
return CodecType::MP4ALS;
|
return Codec::MP4ALS;
|
||||||
case core::media::CodecType::MPC7:
|
case core::media::Codec::MPC7:
|
||||||
return CodecType::MPC7;
|
return Codec::MPC7;
|
||||||
case core::media::CodecType::MPC8:
|
case core::media::Codec::MPC8:
|
||||||
return CodecType::MPC8;
|
return Codec::MPC8;
|
||||||
case core::media::CodecType::Opus:
|
case core::media::Codec::Opus:
|
||||||
return CodecType::Opus;
|
return Codec::Opus;
|
||||||
case core::media::CodecType::PCM:
|
case core::media::Codec::PCM:
|
||||||
return CodecType::PCM;
|
return Codec::PCM;
|
||||||
case core::media::CodecType::Shorten:
|
case core::media::Codec::Shorten:
|
||||||
return CodecType::Shorten;
|
return Codec::Shorten;
|
||||||
case core::media::CodecType::TrueAudio:
|
case core::media::Codec::TrueAudio:
|
||||||
return CodecType::TrueAudio;
|
return Codec::TrueAudio;
|
||||||
case core::media::CodecType::Vorbis:
|
case core::media::Codec::Vorbis:
|
||||||
return CodecType::Vorbis;
|
return Codec::Vorbis;
|
||||||
case core::media::CodecType::WavPack:
|
case core::media::Codec::WavPack:
|
||||||
return CodecType::WavPack;
|
return Codec::WavPack;
|
||||||
case core::media::CodecType::WMA1:
|
case core::media::Codec::WMA1:
|
||||||
return CodecType::WMA1;
|
return Codec::WMA1;
|
||||||
case core::media::CodecType::WMA2:
|
case core::media::Codec::WMA2:
|
||||||
return CodecType::WMA2;
|
return Codec::WMA2;
|
||||||
case core::media::CodecType::WMA9Pro:
|
case core::media::Codec::WMA9Pro:
|
||||||
return CodecType::WMA9Pro;
|
return Codec::WMA9Pro;
|
||||||
case core::media::CodecType::WMA9Lossless:
|
case core::media::Codec::WMA9Lossless:
|
||||||
return CodecType::WMA9Lossless;
|
return Codec::WMA9Lossless;
|
||||||
}
|
}
|
||||||
|
|
||||||
return CodecType::Unknown;
|
return Codec::Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
core::media::ImageType getMediaImageType(db::detail::ImageType type)
|
core::media::ImageType getMediaImageType(db::detail::ImageType type)
|
||||||
|
|||||||
@@ -21,19 +21,19 @@
|
|||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
#include "core/media/CodecType.hpp"
|
#include "core/media/Codec.hpp"
|
||||||
#include "core/media/ContainerType.hpp"
|
#include "core/media/Container.hpp"
|
||||||
#include "core/media/ImageType.hpp"
|
#include "core/media/ImageType.hpp"
|
||||||
|
|
||||||
#include "database/objects/detail/Types.hpp"
|
#include "database/objects/detail/Types.hpp"
|
||||||
|
|
||||||
namespace lms::db::detail
|
namespace lms::db::detail
|
||||||
{
|
{
|
||||||
std::optional<core::media::ContainerType> getMediaContainerType(db::detail::ContainerType container);
|
std::optional<core::media::Container> getMediaContainerType(db::detail::Container container);
|
||||||
db::detail::ContainerType getDbContainerType(core::media::ContainerType container);
|
db::detail::Container getDbContainer(core::media::Container container);
|
||||||
|
|
||||||
std::optional<core::media::CodecType> getMediaCodecType(db::detail::CodecType codec);
|
std::optional<core::media::Codec> getMediaCodecType(db::detail::Codec codec);
|
||||||
db::detail::CodecType getDbCodecType(core::media::CodecType codec);
|
db::detail::Codec getDbCodec(core::media::Codec codec);
|
||||||
|
|
||||||
core::media::ImageType getMediaImageType(db::detail::ImageType type);
|
core::media::ImageType getMediaImageType(db::detail::ImageType type);
|
||||||
db::detail::ImageType getDbImageType(core::media::ImageType type);
|
db::detail::ImageType getDbImageType(core::media::ImageType type);
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
#include <span>
|
#include <span>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "core/media/CodecType.hpp"
|
#include "core/media/Codec.hpp"
|
||||||
|
|
||||||
#include "database/objects/ClusterId.hpp"
|
#include "database/objects/ClusterId.hpp"
|
||||||
#include "database/objects/LabelId.hpp"
|
#include "database/objects/LabelId.hpp"
|
||||||
@@ -34,11 +34,11 @@ namespace lms::db
|
|||||||
{
|
{
|
||||||
struct Filters
|
struct Filters
|
||||||
{
|
{
|
||||||
MediaLibraryId mediaLibrary; // tracks that belongs to this library
|
MediaLibraryId mediaLibrary; // tracks that belongs to this library
|
||||||
std::vector<ClusterId> clusters; // tracks that belong to *all* these clusters
|
std::vector<ClusterId> clusters; // tracks that belong to *all* these clusters
|
||||||
LabelId label; // tracks which release has this label
|
LabelId label; // tracks which release has this label
|
||||||
ReleaseTypeId releaseType; // tracks which release has this type
|
ReleaseTypeId releaseType; // tracks which release has this type
|
||||||
std::optional<core::media::CodecType> codec; // tracks that match this codec
|
std::optional<core::media::Codec> codec; // tracks that match this codec
|
||||||
|
|
||||||
Filters& setClusters(std::span<const ClusterId> _clusters)
|
Filters& setClusters(std::span<const ClusterId> _clusters)
|
||||||
{
|
{
|
||||||
@@ -60,7 +60,7 @@ namespace lms::db
|
|||||||
releaseType = _releaseType;
|
releaseType = _releaseType;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
Filters& setCodec(std::optional<core::media::CodecType> _codec)
|
Filters& setCodec(std::optional<core::media::Codec> _codec)
|
||||||
{
|
{
|
||||||
codec = _codec;
|
codec = _codec;
|
||||||
return *this;
|
return *this;
|
||||||
|
|||||||
@@ -29,8 +29,8 @@
|
|||||||
#include <Wt/Dbo/collection.h>
|
#include <Wt/Dbo/collection.h>
|
||||||
#include <Wt/WDateTime.h>
|
#include <Wt/WDateTime.h>
|
||||||
|
|
||||||
#include "core/media/CodecType.hpp"
|
#include "core/media/Codec.hpp"
|
||||||
#include "core/media/ContainerType.hpp"
|
#include "core/media/Container.hpp"
|
||||||
|
|
||||||
#include "database/Object.hpp"
|
#include "database/Object.hpp"
|
||||||
#include "database/Types.hpp"
|
#include "database/Types.hpp"
|
||||||
@@ -97,8 +97,8 @@ namespace lms::db
|
|||||||
|
|
||||||
// Audio properties
|
// Audio properties
|
||||||
std::chrono::milliseconds getDuration() const { return _duration; }
|
std::chrono::milliseconds getDuration() const { return _duration; }
|
||||||
std::optional<core::media::ContainerType> getContainer() const;
|
std::optional<core::media::Container> getContainer() const;
|
||||||
std::optional<core::media::CodecType> getCodec() const;
|
std::optional<core::media::Codec> getCodec() const;
|
||||||
std::size_t getBitrate() const { return _bitrate; }
|
std::size_t getBitrate() const { return _bitrate; }
|
||||||
std::size_t getChannelCount() const { return _channelCount; }
|
std::size_t getChannelCount() const { return _channelCount; }
|
||||||
std::size_t getSampleRate() const { return _sampleRate; }
|
std::size_t getSampleRate() const { return _sampleRate; }
|
||||||
@@ -128,8 +128,8 @@ namespace lms::db
|
|||||||
|
|
||||||
// Audio properties
|
// Audio properties
|
||||||
void setDuration(std::chrono::milliseconds duration) { _duration = duration; }
|
void setDuration(std::chrono::milliseconds duration) { _duration = duration; }
|
||||||
void setContainer(core::media::ContainerType container);
|
void setContainer(core::media::Container container);
|
||||||
void setCodec(core::media::CodecType codec);
|
void setCodec(core::media::Codec codec);
|
||||||
void setBitrate(std::size_t bitrate) { _bitrate = bitrate; }
|
void setBitrate(std::size_t bitrate) { _bitrate = bitrate; }
|
||||||
void setChannelCount(std::size_t channelCount) { _channelCount = channelCount; }
|
void setChannelCount(std::size_t channelCount) { _channelCount = channelCount; }
|
||||||
void setSampleRate(std::size_t sampleRate) { _sampleRate = sampleRate; }
|
void setSampleRate(std::size_t sampleRate) { _sampleRate = sampleRate; }
|
||||||
@@ -193,8 +193,8 @@ namespace lms::db
|
|||||||
|
|
||||||
// Audio properties
|
// Audio properties
|
||||||
std::chrono::duration<int, std::milli> _duration{ 0 };
|
std::chrono::duration<int, std::milli> _duration{ 0 };
|
||||||
detail::ContainerType _container{ detail::ContainerType::Unknown };
|
detail::Container _container{ detail::Container::Unknown };
|
||||||
detail::CodecType _codec{ detail::CodecType::Unknown };
|
detail::Codec _codec{ detail::Codec::Unknown };
|
||||||
int _bitrate{}; // in bps
|
int _bitrate{}; // in bps
|
||||||
int _channelCount{};
|
int _channelCount{};
|
||||||
int _sampleRate{};
|
int _sampleRate{};
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
#include "core/EnumSet.hpp"
|
#include "core/EnumSet.hpp"
|
||||||
#include "core/PartialDateTime.hpp"
|
#include "core/PartialDateTime.hpp"
|
||||||
#include "core/UUID.hpp"
|
#include "core/UUID.hpp"
|
||||||
#include "core/media/CodecType.hpp"
|
#include "core/media/Codec.hpp"
|
||||||
|
|
||||||
#include "database/IdRange.hpp"
|
#include "database/IdRange.hpp"
|
||||||
#include "database/Object.hpp"
|
#include "database/Object.hpp"
|
||||||
@@ -280,7 +280,7 @@ namespace lms::db
|
|||||||
std::optional<std::string> getCopyright() const;
|
std::optional<std::string> getCopyright() const;
|
||||||
std::optional<std::string> getCopyrightURL() const;
|
std::optional<std::string> getCopyrightURL() const;
|
||||||
std::size_t getMeanBitrate() const;
|
std::size_t getMeanBitrate() const;
|
||||||
std::vector<core::media::CodecType> getCodecs() const;
|
std::vector<core::media::Codec> getCodecs() const;
|
||||||
|
|
||||||
// Accessors
|
// Accessors
|
||||||
std::string_view getName() const { return _name; }
|
std::string_view getName() const { return _name; }
|
||||||
|
|||||||
@@ -34,8 +34,8 @@
|
|||||||
#include "core/EnumSet.hpp"
|
#include "core/EnumSet.hpp"
|
||||||
#include "core/PartialDateTime.hpp"
|
#include "core/PartialDateTime.hpp"
|
||||||
#include "core/UUID.hpp"
|
#include "core/UUID.hpp"
|
||||||
#include "core/media/CodecType.hpp"
|
#include "core/media/Codec.hpp"
|
||||||
#include "core/media/ContainerType.hpp"
|
#include "core/media/Container.hpp"
|
||||||
|
|
||||||
#include "database/IdRange.hpp"
|
#include "database/IdRange.hpp"
|
||||||
#include "database/Object.hpp"
|
#include "database/Object.hpp"
|
||||||
@@ -232,8 +232,8 @@ namespace lms::db
|
|||||||
|
|
||||||
// Audio properties
|
// Audio properties
|
||||||
void setDuration(std::chrono::milliseconds duration) { _duration = duration; }
|
void setDuration(std::chrono::milliseconds duration) { _duration = duration; }
|
||||||
void setContainer(core::media::ContainerType container);
|
void setContainer(core::media::Container container);
|
||||||
void setCodec(core::media::CodecType codec);
|
void setCodec(core::media::Codec codec);
|
||||||
void setBitrate(std::size_t bitrate) { _bitrate = bitrate; }
|
void setBitrate(std::size_t bitrate) { _bitrate = bitrate; }
|
||||||
void setChannelCount(std::size_t channelCount) { _channelCount = channelCount; }
|
void setChannelCount(std::size_t channelCount) { _channelCount = channelCount; }
|
||||||
void setSampleRate(std::size_t sampleRate) { _sampleRate = sampleRate; }
|
void setSampleRate(std::size_t sampleRate) { _sampleRate = sampleRate; }
|
||||||
@@ -278,8 +278,8 @@ namespace lms::db
|
|||||||
|
|
||||||
// Audio properties
|
// Audio properties
|
||||||
std::chrono::milliseconds getDuration() const { return _duration; }
|
std::chrono::milliseconds getDuration() const { return _duration; }
|
||||||
std::optional<core::media::ContainerType> getContainer() const;
|
std::optional<core::media::Container> getContainer() const;
|
||||||
std::optional<core::media::CodecType> getCodec() const;
|
std::optional<core::media::Codec> getCodec() const;
|
||||||
std::size_t getBitrate() const { return _bitrate; }
|
std::size_t getBitrate() const { return _bitrate; }
|
||||||
std::size_t getChannelCount() const { return _channelCount; }
|
std::size_t getChannelCount() const { return _channelCount; }
|
||||||
std::size_t getSampleRate() const { return _sampleRate; }
|
std::size_t getSampleRate() const { return _sampleRate; }
|
||||||
@@ -383,8 +383,8 @@ namespace lms::db
|
|||||||
|
|
||||||
// Audio properties
|
// Audio properties
|
||||||
std::chrono::duration<int, std::milli> _duration{};
|
std::chrono::duration<int, std::milli> _duration{};
|
||||||
detail::ContainerType _container{ detail::ContainerType::Unknown };
|
detail::Container _container{ detail::Container::Unknown };
|
||||||
detail::CodecType _codec{ detail::CodecType::Unknown };
|
detail::Codec _codec{ detail::Codec::Unknown };
|
||||||
int _bitrate{}; // in bps
|
int _bitrate{}; // in bps
|
||||||
int _channelCount{};
|
int _channelCount{};
|
||||||
int _sampleRate{};
|
int _sampleRate{};
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ namespace lms::db::detail
|
|||||||
PublisherLogo = 21
|
PublisherLogo = 21
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class ContainerType
|
enum class Container
|
||||||
{
|
{
|
||||||
Unknown = 0,
|
Unknown = 0,
|
||||||
|
|
||||||
@@ -68,7 +68,7 @@ namespace lms::db::detail
|
|||||||
WavPack = 13,
|
WavPack = 13,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class CodecType
|
enum class Codec
|
||||||
{
|
{
|
||||||
Unknown = 0,
|
Unknown = 0,
|
||||||
|
|
||||||
|
|||||||
@@ -530,15 +530,15 @@ namespace lms::db::tests
|
|||||||
TrackArtistLink::create(session, track1.get(), artist1.get(), TrackArtistLinkType::Artist);
|
TrackArtistLink::create(session, track1.get(), artist1.get(), TrackArtistLinkType::Artist);
|
||||||
TrackArtistLink::create(session, track2.get(), artist2.get(), TrackArtistLinkType::Artist);
|
TrackArtistLink::create(session, track2.get(), artist2.get(), TrackArtistLinkType::Artist);
|
||||||
|
|
||||||
track1.get().modify()->setCodec(core::media::CodecType::MP3);
|
track1.get().modify()->setCodec(core::media::Codec::MP3);
|
||||||
track2.get().modify()->setCodec(core::media::CodecType::FLAC);
|
track2.get().modify()->setCodec(core::media::Codec::FLAC);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto transaction{ session.createReadTransaction() };
|
auto transaction{ session.createReadTransaction() };
|
||||||
|
|
||||||
Artist::FindParameters params;
|
Artist::FindParameters params;
|
||||||
params.setFilters(Filters{}.setCodec(core::media::CodecType::FLAC));
|
params.setFilters(Filters{}.setCodec(core::media::Codec::FLAC));
|
||||||
|
|
||||||
const auto artists{ Artist::find(session, params) };
|
const auto artists{ Artist::find(session, params) };
|
||||||
ASSERT_EQ(artists.results.size(), 1);
|
ASSERT_EQ(artists.results.size(), 1);
|
||||||
|
|||||||
@@ -1229,22 +1229,22 @@ namespace lms::db::tests
|
|||||||
|
|
||||||
{
|
{
|
||||||
auto transaction{ session.createWriteTransaction() };
|
auto transaction{ session.createWriteTransaction() };
|
||||||
track1.get().modify()->setCodec(core::media::CodecType::FLAC);
|
track1.get().modify()->setCodec(core::media::Codec::FLAC);
|
||||||
track1.get().modify()->setRelease(release1.get());
|
track1.get().modify()->setRelease(release1.get());
|
||||||
|
|
||||||
track2.get().modify()->setCodec(core::media::CodecType::MP3);
|
track2.get().modify()->setCodec(core::media::Codec::MP3);
|
||||||
track2.get().modify()->setRelease(release1.get());
|
track2.get().modify()->setRelease(release1.get());
|
||||||
|
|
||||||
track3.get().modify()->setCodec(core::media::CodecType::MP3);
|
track3.get().modify()->setCodec(core::media::Codec::MP3);
|
||||||
track3.get().modify()->setRelease(release1.get());
|
track3.get().modify()->setRelease(release1.get());
|
||||||
|
|
||||||
track4.get().modify()->setCodec(core::media::CodecType::AAC);
|
track4.get().modify()->setCodec(core::media::Codec::AAC);
|
||||||
track4.get().modify()->setRelease(release1.get());
|
track4.get().modify()->setRelease(release1.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto transaction{ session.createReadTransaction() };
|
auto transaction{ session.createReadTransaction() };
|
||||||
EXPECT_EQ(release1->getCodecs(), (std::vector<core::media::CodecType>{ core::media::CodecType::MP3, core::media::CodecType::FLAC, core::media::CodecType::AAC }));
|
EXPECT_EQ(release1->getCodecs(), (std::vector<core::media::Codec>{ core::media::Codec::MP3, core::media::Codec::FLAC, core::media::Codec::AAC }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1263,10 +1263,10 @@ namespace lms::db::tests
|
|||||||
|
|
||||||
{
|
{
|
||||||
auto transaction{ session.createWriteTransaction() };
|
auto transaction{ session.createWriteTransaction() };
|
||||||
track1.get().modify()->setCodec(core::media::CodecType::FLAC);
|
track1.get().modify()->setCodec(core::media::Codec::FLAC);
|
||||||
track1.get().modify()->setRelease(release1.get());
|
track1.get().modify()->setRelease(release1.get());
|
||||||
|
|
||||||
track2.get().modify()->setCodec(core::media::CodecType::MP3);
|
track2.get().modify()->setCodec(core::media::Codec::MP3);
|
||||||
track2.get().modify()->setRelease(release2.get());
|
track2.get().modify()->setRelease(release2.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1274,7 +1274,7 @@ namespace lms::db::tests
|
|||||||
auto transaction{ session.createReadTransaction() };
|
auto transaction{ session.createReadTransaction() };
|
||||||
|
|
||||||
Release::FindParameters params;
|
Release::FindParameters params;
|
||||||
params.setFilters(Filters{}.setCodec(core::media::CodecType::MP3));
|
params.setFilters(Filters{}.setCodec(core::media::Codec::MP3));
|
||||||
|
|
||||||
auto releases{ Release::findIds(session, params) };
|
auto releases{ Release::findIds(session, params) };
|
||||||
ASSERT_EQ(releases.results.size(), 1);
|
ASSERT_EQ(releases.results.size(), 1);
|
||||||
|
|||||||
@@ -245,15 +245,15 @@ namespace lms::db::tests
|
|||||||
|
|
||||||
{
|
{
|
||||||
auto transaction{ session.createWriteTransaction() };
|
auto transaction{ session.createWriteTransaction() };
|
||||||
track1.get().modify()->setCodec(core::media::CodecType::MP3);
|
track1.get().modify()->setCodec(core::media::Codec::MP3);
|
||||||
track2.get().modify()->setCodec(core::media::CodecType::FLAC);
|
track2.get().modify()->setCodec(core::media::Codec::FLAC);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto transaction{ session.createReadTransaction() };
|
auto transaction{ session.createReadTransaction() };
|
||||||
|
|
||||||
Track::FindParameters params;
|
Track::FindParameters params;
|
||||||
params.setFilters(Filters{}.setCodec(core::media::CodecType::FLAC));
|
params.setFilters(Filters{}.setCodec(core::media::Codec::FLAC));
|
||||||
|
|
||||||
const auto tracks{ Track::find(session, params) };
|
const auto tracks{ Track::find(session, params) };
|
||||||
ASSERT_EQ(tracks.results.size(), 1);
|
ASSERT_EQ(tracks.results.size(), 1);
|
||||||
|
|||||||
@@ -53,13 +53,13 @@ namespace lms::api::subsonic
|
|||||||
struct OutputFormat
|
struct OutputFormat
|
||||||
{
|
{
|
||||||
std::string name;
|
std::string name;
|
||||||
core::media::ContainerType container;
|
core::media::Container container;
|
||||||
core::media::CodecType codec;
|
core::media::Codec codec;
|
||||||
};
|
};
|
||||||
constexpr std::array outputFormats{
|
constexpr std::array outputFormats{
|
||||||
OutputFormat{ "mp3", core::media::ContainerType::MPEG, core::media::CodecType::MP3 },
|
OutputFormat{ "mp3", core::media::Container::MPEG, core::media::Codec::MP3 },
|
||||||
OutputFormat{ "opus", core::media::ContainerType::Ogg, core::media::CodecType::Opus },
|
OutputFormat{ "opus", core::media::Container::Ogg, core::media::Codec::Opus },
|
||||||
OutputFormat{ "vorbis", core::media::ContainerType::Ogg, core::media::CodecType::Vorbis },
|
OutputFormat{ "vorbis", core::media::Container::Ogg, core::media::Codec::Vorbis },
|
||||||
};
|
};
|
||||||
|
|
||||||
std::optional<OutputFormat> getOutputFormatByName(std::string_view format)
|
std::optional<OutputFormat> getOutputFormatByName(std::string_view format)
|
||||||
|
|||||||
@@ -48,8 +48,8 @@ namespace lms::api::subsonic
|
|||||||
{
|
{
|
||||||
StreamDetails res;
|
StreamDetails res;
|
||||||
res.protocol = "http";
|
res.protocol = "http";
|
||||||
res.container = core::media::containerTypeToString(audioProperties.container).str();
|
res.container = core::media::containerToString(audioProperties.container).str();
|
||||||
res.codec = core::media::codecTypeToString(audioProperties.codec).str();
|
res.codec = core::media::getCodecDesc(audioProperties.codec).name.str();
|
||||||
res.audioChannels = audioProperties.channelCount;
|
res.audioChannels = audioProperties.channelCount;
|
||||||
res.audioBitrate = audioProperties.bitrate;
|
res.audioBitrate = audioProperties.bitrate;
|
||||||
res.audioProfile = ""; // TODO
|
res.audioProfile = ""; // TODO
|
||||||
|
|||||||
@@ -34,13 +34,13 @@ namespace lms::api::subsonic::detail
|
|||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
constexpr std::array supportedTranscodeOutputFormats{
|
constexpr std::array supportedTranscodeOutputFormats{
|
||||||
audio::TranscodeOutputFormat{ .container = core::media::ContainerType::MPEG, .codec = core::media::CodecType::MP3 },
|
audio::TranscodeOutputFormat{ .container = core::media::Container::MPEG, .codec = core::media::Codec::MP3 },
|
||||||
audio::TranscodeOutputFormat{ .container = core::media::ContainerType::Ogg, .codec = core::media::CodecType::Vorbis },
|
audio::TranscodeOutputFormat{ .container = core::media::Container::Ogg, .codec = core::media::Codec::Vorbis },
|
||||||
audio::TranscodeOutputFormat{ .container = core::media::ContainerType::Ogg, .codec = core::media::CodecType::Opus },
|
audio::TranscodeOutputFormat{ .container = core::media::Container::Ogg, .codec = core::media::Codec::Opus },
|
||||||
audio::TranscodeOutputFormat{ .container = core::media::ContainerType::FLAC, .codec = core::media::CodecType::FLAC },
|
audio::TranscodeOutputFormat{ .container = core::media::Container::FLAC, .codec = core::media::Codec::FLAC },
|
||||||
};
|
};
|
||||||
|
|
||||||
bool isMatchingContainerName(core::media::ContainerType container, std::string_view containerStr)
|
bool isMatchingContainerName(core::media::Container container, std::string_view containerStr)
|
||||||
{
|
{
|
||||||
using namespace std::literals; // for "..."sv
|
using namespace std::literals; // for "..."sv
|
||||||
|
|
||||||
@@ -62,43 +62,43 @@ namespace lms::api::subsonic::detail
|
|||||||
|
|
||||||
switch (container)
|
switch (container)
|
||||||
{
|
{
|
||||||
case core::media::ContainerType::AIFF:
|
case core::media::Container::AIFF:
|
||||||
containerNames = aiffNames;
|
containerNames = aiffNames;
|
||||||
break;
|
break;
|
||||||
case core::media::ContainerType::APE:
|
case core::media::Container::APE:
|
||||||
containerNames = apeNames;
|
containerNames = apeNames;
|
||||||
break;
|
break;
|
||||||
case core::media::ContainerType::ASF:
|
case core::media::Container::ASF:
|
||||||
containerNames = asfNames;
|
containerNames = asfNames;
|
||||||
break;
|
break;
|
||||||
case core::media::ContainerType::DSF:
|
case core::media::Container::DSF:
|
||||||
containerNames = dsfNames;
|
containerNames = dsfNames;
|
||||||
break;
|
break;
|
||||||
case core::media::ContainerType::MPC:
|
case core::media::Container::MPC:
|
||||||
containerNames = mpcNames;
|
containerNames = mpcNames;
|
||||||
break;
|
break;
|
||||||
case core::media::ContainerType::MPEG:
|
case core::media::Container::MPEG:
|
||||||
containerNames = mpegNames;
|
containerNames = mpegNames;
|
||||||
break;
|
break;
|
||||||
case core::media::ContainerType::Ogg:
|
case core::media::Container::Ogg:
|
||||||
containerNames = oggNames;
|
containerNames = oggNames;
|
||||||
break;
|
break;
|
||||||
case core::media::ContainerType::FLAC:
|
case core::media::Container::FLAC:
|
||||||
containerNames = flacNames;
|
containerNames = flacNames;
|
||||||
break;
|
break;
|
||||||
case core::media::ContainerType::MP4:
|
case core::media::Container::MP4:
|
||||||
containerNames = mp4Names;
|
containerNames = mp4Names;
|
||||||
break;
|
break;
|
||||||
case core::media::ContainerType::Shorten:
|
case core::media::Container::Shorten:
|
||||||
containerNames = shortenNames;
|
containerNames = shortenNames;
|
||||||
break;
|
break;
|
||||||
case core::media::ContainerType::TrueAudio:
|
case core::media::Container::TrueAudio:
|
||||||
containerNames = trueAudioNames;
|
containerNames = trueAudioNames;
|
||||||
break;
|
break;
|
||||||
case core::media::ContainerType::WAV:
|
case core::media::Container::WAV:
|
||||||
containerNames = wavNames;
|
containerNames = wavNames;
|
||||||
break;
|
break;
|
||||||
case core::media::ContainerType::WavPack:
|
case core::media::Container::WavPack:
|
||||||
containerNames = wavPackNames;
|
containerNames = wavPackNames;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -106,7 +106,7 @@ namespace lms::api::subsonic::detail
|
|||||||
return std::any_of(std::cbegin(containerNames), std::cend(containerNames), [&](std::string_view containerName) { return core::stringUtils::stringCaseInsensitiveEqual(containerName, containerStr); });
|
return std::any_of(std::cbegin(containerNames), std::cend(containerNames), [&](std::string_view containerName) { return core::stringUtils::stringCaseInsensitiveEqual(containerName, containerStr); });
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isMatchingCodecName(core::media::CodecType codec, std::string_view codecStr)
|
bool isMatchingCodecName(core::media::Codec codec, std::string_view codecStr)
|
||||||
{
|
{
|
||||||
using namespace std::literals; // for "..."sv
|
using namespace std::literals; // for "..."sv
|
||||||
|
|
||||||
@@ -135,67 +135,67 @@ namespace lms::api::subsonic::detail
|
|||||||
std::span<const std::string_view> codecNames;
|
std::span<const std::string_view> codecNames;
|
||||||
switch (codec)
|
switch (codec)
|
||||||
{
|
{
|
||||||
case core::media::CodecType::AAC:
|
case core::media::Codec::AAC:
|
||||||
codecNames = aacCodecNames;
|
codecNames = aacCodecNames;
|
||||||
break;
|
break;
|
||||||
case core::media::CodecType::AC3:
|
case core::media::Codec::AC3:
|
||||||
codecNames = ac3CodecNames;
|
codecNames = ac3CodecNames;
|
||||||
break;
|
break;
|
||||||
case core::media::CodecType::ALAC:
|
case core::media::Codec::ALAC:
|
||||||
codecNames = alacCodecNames;
|
codecNames = alacCodecNames;
|
||||||
break;
|
break;
|
||||||
case core::media::CodecType::APE:
|
case core::media::Codec::APE:
|
||||||
codecNames = apeCodecNames;
|
codecNames = apeCodecNames;
|
||||||
break;
|
break;
|
||||||
case core::media::CodecType::DSD:
|
case core::media::Codec::DSD:
|
||||||
codecNames = dsdCodecNames;
|
codecNames = dsdCodecNames;
|
||||||
break;
|
break;
|
||||||
case core::media::CodecType::EAC3:
|
case core::media::Codec::EAC3:
|
||||||
codecNames = eac3CodecNames;
|
codecNames = eac3CodecNames;
|
||||||
break;
|
break;
|
||||||
case core::media::CodecType::FLAC:
|
case core::media::Codec::FLAC:
|
||||||
codecNames = flacCodecNames;
|
codecNames = flacCodecNames;
|
||||||
break;
|
break;
|
||||||
case core::media::CodecType::MP3:
|
case core::media::Codec::MP3:
|
||||||
codecNames = mp3CodecNames;
|
codecNames = mp3CodecNames;
|
||||||
break;
|
break;
|
||||||
case core::media::CodecType::MP4ALS:
|
case core::media::Codec::MP4ALS:
|
||||||
codecNames = mp4alsCodecNames;
|
codecNames = mp4alsCodecNames;
|
||||||
break;
|
break;
|
||||||
case core::media::CodecType::MPC7:
|
case core::media::Codec::MPC7:
|
||||||
codecNames = mpc7CodecNames;
|
codecNames = mpc7CodecNames;
|
||||||
break;
|
break;
|
||||||
case core::media::CodecType::MPC8:
|
case core::media::Codec::MPC8:
|
||||||
codecNames = mpc8CodecNames;
|
codecNames = mpc8CodecNames;
|
||||||
break;
|
break;
|
||||||
case core::media::CodecType::Opus:
|
case core::media::Codec::Opus:
|
||||||
codecNames = opusCodecNames;
|
codecNames = opusCodecNames;
|
||||||
break;
|
break;
|
||||||
case core::media::CodecType::PCM:
|
case core::media::Codec::PCM:
|
||||||
codecNames = pcmCodecNames;
|
codecNames = pcmCodecNames;
|
||||||
break;
|
break;
|
||||||
case core::media::CodecType::Shorten:
|
case core::media::Codec::Shorten:
|
||||||
codecNames = shortenCodecNames;
|
codecNames = shortenCodecNames;
|
||||||
break;
|
break;
|
||||||
case core::media::CodecType::TrueAudio:
|
case core::media::Codec::TrueAudio:
|
||||||
codecNames = trueAudioCodecNames;
|
codecNames = trueAudioCodecNames;
|
||||||
break;
|
break;
|
||||||
case core::media::CodecType::Vorbis:
|
case core::media::Codec::Vorbis:
|
||||||
codecNames = vorbisCodecNames;
|
codecNames = vorbisCodecNames;
|
||||||
break;
|
break;
|
||||||
case core::media::CodecType::WavPack:
|
case core::media::Codec::WavPack:
|
||||||
codecNames = wavPackCodecNames;
|
codecNames = wavPackCodecNames;
|
||||||
break;
|
break;
|
||||||
case core::media::CodecType::WMA1:
|
case core::media::Codec::WMA1:
|
||||||
codecNames = wma1CodecNames;
|
codecNames = wma1CodecNames;
|
||||||
break;
|
break;
|
||||||
case core::media::CodecType::WMA2:
|
case core::media::Codec::WMA2:
|
||||||
codecNames = wma2CodecNames;
|
codecNames = wma2CodecNames;
|
||||||
break;
|
break;
|
||||||
case core::media::CodecType::WMA9Lossless:
|
case core::media::Codec::WMA9Lossless:
|
||||||
codecNames = wma9LosslessCodecNames;
|
codecNames = wma9LosslessCodecNames;
|
||||||
break;
|
break;
|
||||||
case core::media::CodecType::WMA9Pro:
|
case core::media::Codec::WMA9Pro:
|
||||||
codecNames = wma9ProCodecNames;
|
codecNames = wma9ProCodecNames;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -343,7 +343,7 @@ namespace lms::api::subsonic::detail
|
|||||||
return adjustResult.type == AdjustResult::Type::None;
|
return adjustResult.type == AdjustResult::Type::None;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CodecProfile* getAudioCodecProfile(std::span<const CodecProfile> codecProfiles, core::media::CodecType codec)
|
const CodecProfile* getAudioCodecProfile(std::span<const CodecProfile> codecProfiles, core::media::Codec codec)
|
||||||
{
|
{
|
||||||
for (const CodecProfile& profile : codecProfiles)
|
for (const CodecProfile& profile : codecProfiles)
|
||||||
{
|
{
|
||||||
@@ -463,9 +463,9 @@ namespace lms::api::subsonic::detail
|
|||||||
transcodedStream.container = profile.container; // put back what was requested instead of our internal names
|
transcodedStream.container = profile.container; // put back what was requested instead of our internal names
|
||||||
transcodedStream.codec = profile.audioCodec; // put back what was requested instead of our internal names
|
transcodedStream.codec = profile.audioCodec; // put back what was requested instead of our internal names
|
||||||
|
|
||||||
if (core::media::isCodecLossless(source.codec))
|
if (core::media::getCodecDesc(source.codec).isLossless)
|
||||||
{
|
{
|
||||||
if (!core::media::isCodecLossless(transcodeFormat->codec))
|
if (!core::media::getCodecDesc(transcodeFormat->codec).isLossless)
|
||||||
{
|
{
|
||||||
// If coming from lossless source, maximize the bitrate if going to a non lossless source
|
// If coming from lossless source, maximize the bitrate if going to a non lossless source
|
||||||
// otherwise, pick a good enough value as we don't want to keep the original bitrate which does not make sense for lossy codecs
|
// otherwise, pick a good enough value as we don't want to keep the original bitrate which does not make sense for lossy codecs
|
||||||
@@ -486,7 +486,7 @@ namespace lms::api::subsonic::detail
|
|||||||
{
|
{
|
||||||
// source is lossy
|
// source is lossy
|
||||||
|
|
||||||
if (core::media::isCodecLossless(transcodeFormat->codec))
|
if (core::media::getCodecDesc(transcodeFormat->codec).isLossless)
|
||||||
return std::nullopt; // not compatible with lossless codecs
|
return std::nullopt; // not compatible with lossless codecs
|
||||||
|
|
||||||
// let's pick the same bitrate as the lossy source
|
// let's pick the same bitrate as the lossy source
|
||||||
@@ -504,7 +504,7 @@ namespace lms::api::subsonic::detail
|
|||||||
for (const Limitation& limitation : codecProfile->limitations)
|
for (const Limitation& limitation : codecProfile->limitations)
|
||||||
{
|
{
|
||||||
const AdjustResult result{ applyLimitation(source, limitation, transcodedStream) };
|
const AdjustResult result{ applyLimitation(source, limitation, transcodedStream) };
|
||||||
if (limitation.name == Limitation::Type::AudioBitrate && core::media::isCodecLossless(transcodeFormat->codec) && result.type == AdjustResult::Type::Adjusted)
|
if (limitation.name == Limitation::Type::AudioBitrate && core::media::getCodecDesc(transcodeFormat->codec).isLossless && result.type == AdjustResult::Type::Adjusted)
|
||||||
return std::nullopt; // not compatible with lossless codecs
|
return std::nullopt; // not compatible with lossless codecs
|
||||||
|
|
||||||
if (result.type == AdjustResult::Type::CannotAdjust)
|
if (result.type == AdjustResult::Type::CannotAdjust)
|
||||||
|
|||||||
@@ -22,8 +22,8 @@
|
|||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
#include "core/Utils.hpp"
|
#include "core/Utils.hpp"
|
||||||
#include "core/media/CodecType.hpp"
|
#include "core/media/Codec.hpp"
|
||||||
#include "core/media/ContainerType.hpp"
|
#include "core/media/Container.hpp"
|
||||||
|
|
||||||
#include "endpoints/transcoding/TranscodeDecision.hpp"
|
#include "endpoints/transcoding/TranscodeDecision.hpp"
|
||||||
#include "payloads/ClientInfo.hpp"
|
#include "payloads/ClientInfo.hpp"
|
||||||
@@ -111,8 +111,8 @@ namespace lms::api::subsonic
|
|||||||
} } },
|
} } },
|
||||||
},
|
},
|
||||||
.source = {
|
.source = {
|
||||||
.container = core::media::ContainerType::MPEG,
|
.container = core::media::Container::MPEG,
|
||||||
.codec = core::media::CodecType::MP3,
|
.codec = core::media::Codec::MP3,
|
||||||
.duration = std::chrono::seconds{ 60 },
|
.duration = std::chrono::seconds{ 60 },
|
||||||
.bitrate = 128'000,
|
.bitrate = 128'000,
|
||||||
.channelCount = 2,
|
.channelCount = 2,
|
||||||
@@ -141,8 +141,8 @@ namespace lms::api::subsonic
|
|||||||
} } },
|
} } },
|
||||||
},
|
},
|
||||||
.source = {
|
.source = {
|
||||||
.container = core::media::ContainerType::MPEG,
|
.container = core::media::Container::MPEG,
|
||||||
.codec = core::media::CodecType::MP3,
|
.codec = core::media::Codec::MP3,
|
||||||
.duration = std::chrono::seconds{ 60 },
|
.duration = std::chrono::seconds{ 60 },
|
||||||
.bitrate = 128'000,
|
.bitrate = 128'000,
|
||||||
.channelCount = 2,
|
.channelCount = 2,
|
||||||
@@ -171,8 +171,8 @@ namespace lms::api::subsonic
|
|||||||
} } },
|
} } },
|
||||||
},
|
},
|
||||||
.source = {
|
.source = {
|
||||||
.container = core::media::ContainerType::MPEG,
|
.container = core::media::Container::MPEG,
|
||||||
.codec = core::media::CodecType::MP3,
|
.codec = core::media::Codec::MP3,
|
||||||
.duration = std::chrono::seconds{ 60 },
|
.duration = std::chrono::seconds{ 60 },
|
||||||
.bitrate = 128'000,
|
.bitrate = 128'000,
|
||||||
.channelCount = 2,
|
.channelCount = 2,
|
||||||
@@ -201,8 +201,8 @@ namespace lms::api::subsonic
|
|||||||
} } },
|
} } },
|
||||||
},
|
},
|
||||||
.source = {
|
.source = {
|
||||||
.container = core::media::ContainerType::MPEG,
|
.container = core::media::Container::MPEG,
|
||||||
.codec = core::media::CodecType::MP3,
|
.codec = core::media::Codec::MP3,
|
||||||
.duration = std::chrono::seconds{ 60 },
|
.duration = std::chrono::seconds{ 60 },
|
||||||
.bitrate = 192'000,
|
.bitrate = 192'000,
|
||||||
.channelCount = 2,
|
.channelCount = 2,
|
||||||
@@ -231,8 +231,8 @@ namespace lms::api::subsonic
|
|||||||
} } },
|
} } },
|
||||||
},
|
},
|
||||||
.source = {
|
.source = {
|
||||||
.container = core::media::ContainerType::MPEG,
|
.container = core::media::Container::MPEG,
|
||||||
.codec = core::media::CodecType::MP3,
|
.codec = core::media::Codec::MP3,
|
||||||
.duration = std::chrono::seconds{ 60 },
|
.duration = std::chrono::seconds{ 60 },
|
||||||
.bitrate = 192'000,
|
.bitrate = 192'000,
|
||||||
.channelCount = 2,
|
.channelCount = 2,
|
||||||
@@ -255,8 +255,8 @@ namespace lms::api::subsonic
|
|||||||
.codecProfiles = { { .type = "AudioCodec", .name = "mp3", .limitations = {} } },
|
.codecProfiles = { { .type = "AudioCodec", .name = "mp3", .limitations = {} } },
|
||||||
},
|
},
|
||||||
.source = {
|
.source = {
|
||||||
.container = core::media::ContainerType::MPEG,
|
.container = core::media::Container::MPEG,
|
||||||
.codec = core::media::CodecType::MP3,
|
.codec = core::media::Codec::MP3,
|
||||||
.duration = std::chrono::seconds{ 60 },
|
.duration = std::chrono::seconds{ 60 },
|
||||||
.bitrate = 192'000,
|
.bitrate = 192'000,
|
||||||
.channelCount = 5,
|
.channelCount = 5,
|
||||||
@@ -283,8 +283,8 @@ namespace lms::api::subsonic
|
|||||||
.codecProfiles = { { .type = "AudioCodec", .name = "mp3", .limitations = { { .name = Limitation::Type::AudioChannels, .comparison = Limitation::ComparisonOperator::LessThanEqual, .values = { "2" }, .required = true } } } },
|
.codecProfiles = { { .type = "AudioCodec", .name = "mp3", .limitations = { { .name = Limitation::Type::AudioChannels, .comparison = Limitation::ComparisonOperator::LessThanEqual, .values = { "2" }, .required = true } } } },
|
||||||
},
|
},
|
||||||
.source = {
|
.source = {
|
||||||
.container = core::media::ContainerType::MPEG,
|
.container = core::media::Container::MPEG,
|
||||||
.codec = core::media::CodecType::MP3,
|
.codec = core::media::Codec::MP3,
|
||||||
.duration = std::chrono::seconds{ 60 },
|
.duration = std::chrono::seconds{ 60 },
|
||||||
.bitrate = 192'000,
|
.bitrate = 192'000,
|
||||||
.channelCount = 5,
|
.channelCount = 5,
|
||||||
@@ -311,8 +311,8 @@ namespace lms::api::subsonic
|
|||||||
.codecProfiles = { { .type = "AudioCodec", .name = "mp3", .limitations = { { .name = Limitation::Type::AudioChannels, .comparison = Limitation::ComparisonOperator::LessThanEqual, .values = { "2" }, .required = true } } } },
|
.codecProfiles = { { .type = "AudioCodec", .name = "mp3", .limitations = { { .name = Limitation::Type::AudioChannels, .comparison = Limitation::ComparisonOperator::LessThanEqual, .values = { "2" }, .required = true } } } },
|
||||||
},
|
},
|
||||||
.source = {
|
.source = {
|
||||||
.container = core::media::ContainerType::Ogg,
|
.container = core::media::Container::Ogg,
|
||||||
.codec = core::media::CodecType::Opus,
|
.codec = core::media::Codec::Opus,
|
||||||
.duration = std::chrono::seconds{ 60 },
|
.duration = std::chrono::seconds{ 60 },
|
||||||
.bitrate = 128'000,
|
.bitrate = 128'000,
|
||||||
.channelCount = 2,
|
.channelCount = 2,
|
||||||
@@ -339,8 +339,8 @@ namespace lms::api::subsonic
|
|||||||
.codecProfiles = { { .type = "AudioCodec", .name = "mp3", .limitations = {} } },
|
.codecProfiles = { { .type = "AudioCodec", .name = "mp3", .limitations = {} } },
|
||||||
},
|
},
|
||||||
.source = {
|
.source = {
|
||||||
.container = core::media::ContainerType::FLAC,
|
.container = core::media::Container::FLAC,
|
||||||
.codec = core::media::CodecType::FLAC,
|
.codec = core::media::Codec::FLAC,
|
||||||
.duration = std::chrono::seconds{ 60 },
|
.duration = std::chrono::seconds{ 60 },
|
||||||
.bitrate = 750'000,
|
.bitrate = 750'000,
|
||||||
.channelCount = 2,
|
.channelCount = 2,
|
||||||
@@ -362,8 +362,8 @@ namespace lms::api::subsonic
|
|||||||
},
|
},
|
||||||
.codecProfiles = {} },
|
.codecProfiles = {} },
|
||||||
.source = {
|
.source = {
|
||||||
.container = core::media::ContainerType::FLAC,
|
.container = core::media::Container::FLAC,
|
||||||
.codec = core::media::CodecType::FLAC,
|
.codec = core::media::Codec::FLAC,
|
||||||
.duration = std::chrono::seconds{ 60 },
|
.duration = std::chrono::seconds{ 60 },
|
||||||
.bitrate = 750'000,
|
.bitrate = 750'000,
|
||||||
.channelCount = 2,
|
.channelCount = 2,
|
||||||
@@ -388,8 +388,8 @@ namespace lms::api::subsonic
|
|||||||
.codecProfiles = {},
|
.codecProfiles = {},
|
||||||
},
|
},
|
||||||
.source = {
|
.source = {
|
||||||
.container = core::media::ContainerType::MPEG,
|
.container = core::media::Container::MPEG,
|
||||||
.codec = core::media::CodecType::MP3,
|
.codec = core::media::Codec::MP3,
|
||||||
.duration = std::chrono::seconds{ 60 },
|
.duration = std::chrono::seconds{ 60 },
|
||||||
.bitrate = 128'000,
|
.bitrate = 128'000,
|
||||||
.channelCount = 2,
|
.channelCount = 2,
|
||||||
@@ -414,8 +414,8 @@ namespace lms::api::subsonic
|
|||||||
.codecProfiles = {},
|
.codecProfiles = {},
|
||||||
},
|
},
|
||||||
.source = {
|
.source = {
|
||||||
.container = core::media::ContainerType::MPEG,
|
.container = core::media::Container::MPEG,
|
||||||
.codec = core::media::CodecType::MP3,
|
.codec = core::media::Codec::MP3,
|
||||||
.duration = std::chrono::seconds{ 60 },
|
.duration = std::chrono::seconds{ 60 },
|
||||||
.bitrate = 128'000,
|
.bitrate = 128'000,
|
||||||
.channelCount = 2,
|
.channelCount = 2,
|
||||||
@@ -440,8 +440,8 @@ namespace lms::api::subsonic
|
|||||||
.codecProfiles = {},
|
.codecProfiles = {},
|
||||||
},
|
},
|
||||||
.source = {
|
.source = {
|
||||||
.container = core::media::ContainerType::FLAC,
|
.container = core::media::Container::FLAC,
|
||||||
.codec = core::media::CodecType::FLAC,
|
.codec = core::media::Codec::FLAC,
|
||||||
.duration = std::chrono::seconds{ 60 },
|
.duration = std::chrono::seconds{ 60 },
|
||||||
.bitrate = 1'000'000,
|
.bitrate = 1'000'000,
|
||||||
.channelCount = 2,
|
.channelCount = 2,
|
||||||
@@ -478,8 +478,8 @@ namespace lms::api::subsonic
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
.source = {
|
.source = {
|
||||||
.container = core::media::ContainerType::FLAC,
|
.container = core::media::Container::FLAC,
|
||||||
.codec = core::media::CodecType::FLAC,
|
.codec = core::media::Codec::FLAC,
|
||||||
.duration = std::chrono::seconds{ 60 },
|
.duration = std::chrono::seconds{ 60 },
|
||||||
.bitrate = 950'000,
|
.bitrate = 950'000,
|
||||||
.channelCount = 2,
|
.channelCount = 2,
|
||||||
@@ -517,8 +517,8 @@ namespace lms::api::subsonic
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
.source = {
|
.source = {
|
||||||
.container = core::media::ContainerType::FLAC,
|
.container = core::media::Container::FLAC,
|
||||||
.codec = core::media::CodecType::FLAC,
|
.codec = core::media::Codec::FLAC,
|
||||||
.duration = std::chrono::seconds{ 60 },
|
.duration = std::chrono::seconds{ 60 },
|
||||||
.bitrate = 950'000,
|
.bitrate = 950'000,
|
||||||
.channelCount = 2,
|
.channelCount = 2,
|
||||||
@@ -555,8 +555,8 @@ namespace lms::api::subsonic
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
.source = {
|
.source = {
|
||||||
.container = core::media::ContainerType::Ogg,
|
.container = core::media::Container::Ogg,
|
||||||
.codec = core::media::CodecType::Vorbis,
|
.codec = core::media::Codec::Vorbis,
|
||||||
.duration = std::chrono::seconds{ 60 },
|
.duration = std::chrono::seconds{ 60 },
|
||||||
.bitrate = 128'000,
|
.bitrate = 128'000,
|
||||||
.channelCount = 2,
|
.channelCount = 2,
|
||||||
@@ -593,8 +593,8 @@ namespace lms::api::subsonic
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
.source = {
|
.source = {
|
||||||
.container = core::media::ContainerType::DSF,
|
.container = core::media::Container::DSF,
|
||||||
.codec = core::media::CodecType::DSD,
|
.codec = core::media::Codec::DSD,
|
||||||
.duration = std::chrono::seconds{ 60 },
|
.duration = std::chrono::seconds{ 60 },
|
||||||
.bitrate = 950'000,
|
.bitrate = 950'000,
|
||||||
.channelCount = 2,
|
.channelCount = 2,
|
||||||
@@ -623,8 +623,8 @@ namespace lms::api::subsonic
|
|||||||
} } },
|
} } },
|
||||||
},
|
},
|
||||||
.source = {
|
.source = {
|
||||||
.container = core::media::ContainerType::MPEG,
|
.container = core::media::Container::MPEG,
|
||||||
.codec = core::media::CodecType::MP3,
|
.codec = core::media::Codec::MP3,
|
||||||
.duration = std::chrono::seconds{ 60 },
|
.duration = std::chrono::seconds{ 60 },
|
||||||
.bitrate = 128'000,
|
.bitrate = 128'000,
|
||||||
.channelCount = 2,
|
.channelCount = 2,
|
||||||
|
|||||||
@@ -142,11 +142,11 @@ namespace lms::ui
|
|||||||
// Codecs
|
// Codecs
|
||||||
{
|
{
|
||||||
std::string codecStr;
|
std::string codecStr;
|
||||||
for (core::media::CodecType codec : release->getCodecs())
|
for (core::media::Codec codec : release->getCodecs())
|
||||||
{
|
{
|
||||||
if (!codecStr.empty())
|
if (!codecStr.empty())
|
||||||
codecStr += " · ";
|
codecStr += " · ";
|
||||||
codecStr += core::media::codecTypeToString(codec).str();
|
codecStr += core::media::getCodecDesc(codec).name.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!codecStr.empty())
|
if (!codecStr.empty())
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ namespace lms::ui::TrackListHelpers
|
|||||||
if (const auto codec{ track->getCodec() })
|
if (const auto codec{ track->getCodec() })
|
||||||
{
|
{
|
||||||
trackInfo->setCondition("if-has-codec", true);
|
trackInfo->setCondition("if-has-codec", true);
|
||||||
trackInfo->bindString("codec", core::media::codecTypeToString(*codec).c_str(), Wt::TextFormat::Plain);
|
trackInfo->bindString("codec", core::media::getCodecDesc(*codec).name.c_str(), Wt::TextFormat::Plain);
|
||||||
}
|
}
|
||||||
|
|
||||||
trackInfo->bindString("duration", utils::durationToString(track->getDuration()));
|
trackInfo->bindString("duration", utils::durationToString(track->getDuration()));
|
||||||
|
|||||||
@@ -124,11 +124,11 @@ namespace lms::ui
|
|||||||
switch (format)
|
switch (format)
|
||||||
{
|
{
|
||||||
case db::TranscodingOutputFormat::MP3:
|
case db::TranscodingOutputFormat::MP3:
|
||||||
return audio::TranscodeOutputFormat{ core::media::ContainerType::MPEG, core::media::CodecType::MP3 };
|
return audio::TranscodeOutputFormat{ core::media::Container::MPEG, core::media::Codec::MP3 };
|
||||||
case db::TranscodingOutputFormat::OGG_OPUS:
|
case db::TranscodingOutputFormat::OGG_OPUS:
|
||||||
return audio::TranscodeOutputFormat{ core::media::ContainerType::Ogg, core::media::CodecType::Opus };
|
return audio::TranscodeOutputFormat{ core::media::Container::Ogg, core::media::Codec::Opus };
|
||||||
case db::TranscodingOutputFormat::OGG_VORBIS:
|
case db::TranscodingOutputFormat::OGG_VORBIS:
|
||||||
return audio::TranscodeOutputFormat{ core::media::ContainerType::Ogg, core::media::CodecType::Vorbis };
|
return audio::TranscodeOutputFormat{ core::media::Container::Ogg, core::media::Codec::Vorbis };
|
||||||
}
|
}
|
||||||
|
|
||||||
TRANSCODE_LOG(ERROR, "Cannot convert from db audio format to transcoding format");
|
TRANSCODE_LOG(ERROR, "Cannot convert from db audio format to transcoding format");
|
||||||
|
|||||||
@@ -41,8 +41,8 @@ namespace lms::audio
|
|||||||
std::ostream& operator<<(std::ostream& os, const AudioProperties& audioProperties)
|
std::ostream& operator<<(std::ostream& os, const AudioProperties& audioProperties)
|
||||||
{
|
{
|
||||||
os << "\tDuration: " << std::fixed << std::setprecision(2) << std::chrono::duration_cast<std::chrono::duration<float>>(audioProperties.duration) << '\n';
|
os << "\tDuration: " << std::fixed << std::setprecision(2) << std::chrono::duration_cast<std::chrono::duration<float>>(audioProperties.duration) << '\n';
|
||||||
os << "\tContainer: " << core::media::containerTypeToString(audioProperties.container) << '\n';
|
os << "\tContainer: " << core::media::containerToString(audioProperties.container) << '\n';
|
||||||
os << "\tCodec: " << core::media::codecTypeToString(audioProperties.codec) << '\n';
|
os << "\tCodec: " << core::media::getCodecDesc(audioProperties.codec).name << '\n';
|
||||||
os << "\tMimeType: " << core::media::getMimeType(audioProperties.container, audioProperties.codec) << '\n';
|
os << "\tMimeType: " << core::media::getMimeType(audioProperties.container, audioProperties.codec) << '\n';
|
||||||
os << "\tBitrate: " << audioProperties.bitrate << " bps" << '\n';
|
os << "\tBitrate: " << audioProperties.bitrate << " bps" << '\n';
|
||||||
if (audioProperties.bitsPerSample)
|
if (audioProperties.bitsPerSample)
|
||||||
|
|||||||
Reference in New Issue
Block a user