Fixed bitrate detection for av parser
This commit is contained in:
@@ -101,12 +101,14 @@ namespace Av
|
|||||||
return _p;
|
return _p;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::chrono::milliseconds AudioFile::getDuration() const
|
ContainerInfo AudioFile::getContainerInfo() const
|
||||||
{
|
{
|
||||||
if (_context->duration == AV_NOPTS_VALUE)
|
ContainerInfo info;
|
||||||
return std::chrono::milliseconds{ 0 }; // TODO estimate
|
info.bitrate = _context->bit_rate;
|
||||||
|
info.duration = std::chrono::milliseconds{ _context->duration == AV_NOPTS_VALUE ? 0 : _context->duration / AV_TIME_BASE * 1000 };
|
||||||
|
info.name = _context->iformat->name;
|
||||||
|
|
||||||
return std::chrono::milliseconds{ _context->duration / AV_TIME_BASE * 1000 };
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioFile::MetadataMap AudioFile::getMetaData() const
|
AudioFile::MetadataMap AudioFile::getMetaData() const
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ namespace Av
|
|||||||
~AudioFile();
|
~AudioFile();
|
||||||
|
|
||||||
const std::filesystem::path& getPath() const override;
|
const std::filesystem::path& getPath() const override;
|
||||||
std::chrono::milliseconds getDuration() const override;
|
ContainerInfo getContainerInfo() const override;
|
||||||
MetadataMap getMetaData() const override;
|
MetadataMap getMetaData() const override;
|
||||||
std::vector<StreamInfo> getStreamInfo() const override;
|
std::vector<StreamInfo> getStreamInfo() const override;
|
||||||
std::optional<StreamInfo> getBestStreamInfo() const override;
|
std::optional<StreamInfo> getBestStreamInfo() const override;
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
|
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* This file contains some classes in order to get info from file using the libavconv */
|
/* This file contains some classes in order to get info from file using the libavconv */
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
@@ -34,46 +34,53 @@
|
|||||||
|
|
||||||
namespace Av
|
namespace Av
|
||||||
{
|
{
|
||||||
struct Picture
|
struct Picture
|
||||||
{
|
{
|
||||||
std::string mimeType;
|
std::string mimeType;
|
||||||
const std::byte* data {};
|
const std::byte* data{};
|
||||||
std::size_t dataSize {};
|
std::size_t dataSize{};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct StreamInfo
|
struct ContainerInfo
|
||||||
{
|
{
|
||||||
size_t index {};
|
std::size_t bitrate{};
|
||||||
std::size_t bitrate {};
|
std::string name{};
|
||||||
std::string codec;
|
std::chrono::milliseconds duration{};
|
||||||
};
|
};
|
||||||
|
|
||||||
class IAudioFile
|
struct StreamInfo
|
||||||
{
|
{
|
||||||
public:
|
size_t index{};
|
||||||
virtual ~IAudioFile() = default;
|
std::size_t bitrate{};
|
||||||
|
std::string codec;
|
||||||
|
};
|
||||||
|
|
||||||
using MetadataMap = std::unordered_map<std::string, std::string>;
|
class IAudioFile
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~IAudioFile() = default;
|
||||||
|
|
||||||
virtual const std::filesystem::path& getPath() const = 0;
|
using MetadataMap = std::unordered_map<std::string, std::string>;
|
||||||
virtual std::chrono::milliseconds getDuration() const = 0;
|
|
||||||
virtual MetadataMap getMetaData() const = 0;
|
|
||||||
virtual std::vector<StreamInfo> getStreamInfo() const = 0;
|
|
||||||
virtual std::optional<StreamInfo> getBestStreamInfo() const = 0; // none if failure/unknown
|
|
||||||
virtual std::optional<std::size_t> getBestStreamIndex() const = 0; // none if failure/unknown
|
|
||||||
virtual bool hasAttachedPictures() const = 0;
|
|
||||||
virtual void visitAttachedPictures(std::function<void(const Picture&)> func) const = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::unique_ptr<IAudioFile> parseAudioFile(const std::filesystem::path& p);
|
virtual const std::filesystem::path& getPath() const = 0;
|
||||||
|
virtual ContainerInfo getContainerInfo() const = 0;
|
||||||
|
virtual MetadataMap getMetaData() const = 0;
|
||||||
|
virtual std::vector<StreamInfo> getStreamInfo() const = 0;
|
||||||
|
virtual std::optional<StreamInfo> getBestStreamInfo() const = 0; // none if failure/unknown
|
||||||
|
virtual std::optional<std::size_t> getBestStreamIndex() const = 0; // none if failure/unknown
|
||||||
|
virtual bool hasAttachedPictures() const = 0;
|
||||||
|
virtual void visitAttachedPictures(std::function<void(const Picture&)> func) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
struct AudioFileFormat
|
std::unique_ptr<IAudioFile> parseAudioFile(const std::filesystem::path& p);
|
||||||
{
|
|
||||||
std::string mimeType;
|
|
||||||
std::string format;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::string_view getMimeType(const std::filesystem::path& fileExtension);
|
struct AudioFileFormat
|
||||||
|
{
|
||||||
|
std::string mimeType;
|
||||||
|
std::string format;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string_view getMimeType(const std::filesystem::path& fileExtension);
|
||||||
|
|
||||||
} // namespace Av
|
} // namespace Av
|
||||||
|
|
||||||
|
|||||||
@@ -186,18 +186,9 @@ AvFormatParser::parse(const std::filesystem::path& p, bool debug)
|
|||||||
{
|
{
|
||||||
const auto mediaFile {Av::parseAudioFile(p)};
|
const auto mediaFile {Av::parseAudioFile(p)};
|
||||||
|
|
||||||
// Stream info
|
Av::ContainerInfo info{ mediaFile->getContainerInfo() };
|
||||||
if (const auto stream{ mediaFile->getBestStreamInfo() })
|
track.duration = info.duration;
|
||||||
{
|
track.bitrate = info.bitrate;
|
||||||
track.bitrate = stream->bitrate;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LMS_LOG(METADATA, INFO) << "File '" << p.string() << "': cannot get best audio stream";
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
|
|
||||||
track.duration = mediaFile->getDuration();
|
|
||||||
track.hasCover = mediaFile->hasAttachedPictures();
|
track.hasCover = mediaFile->hasAttachedPictures();
|
||||||
|
|
||||||
MetaData::Tags tags;
|
MetaData::Tags tags;
|
||||||
|
|||||||
Reference in New Issue
Block a user