Fixed bitrate detection for av parser
This commit is contained in:
@@ -101,12 +101,14 @@ namespace Av
|
||||
return _p;
|
||||
}
|
||||
|
||||
std::chrono::milliseconds AudioFile::getDuration() const
|
||||
ContainerInfo AudioFile::getContainerInfo() const
|
||||
{
|
||||
if (_context->duration == AV_NOPTS_VALUE)
|
||||
return std::chrono::milliseconds{ 0 }; // TODO estimate
|
||||
ContainerInfo info;
|
||||
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
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace Av
|
||||
~AudioFile();
|
||||
|
||||
const std::filesystem::path& getPath() const override;
|
||||
std::chrono::milliseconds getDuration() const override;
|
||||
ContainerInfo getContainerInfo() const override;
|
||||
MetadataMap getMetaData() const override;
|
||||
std::vector<StreamInfo> getStreamInfo() const override;
|
||||
std::optional<StreamInfo> getBestStreamInfo() const override;
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* 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
|
||||
|
||||
@@ -34,46 +34,53 @@
|
||||
|
||||
namespace Av
|
||||
{
|
||||
struct Picture
|
||||
{
|
||||
std::string mimeType;
|
||||
const std::byte* data {};
|
||||
std::size_t dataSize {};
|
||||
};
|
||||
struct Picture
|
||||
{
|
||||
std::string mimeType;
|
||||
const std::byte* data{};
|
||||
std::size_t dataSize{};
|
||||
};
|
||||
|
||||
struct StreamInfo
|
||||
{
|
||||
size_t index {};
|
||||
std::size_t bitrate {};
|
||||
std::string codec;
|
||||
};
|
||||
struct ContainerInfo
|
||||
{
|
||||
std::size_t bitrate{};
|
||||
std::string name{};
|
||||
std::chrono::milliseconds duration{};
|
||||
};
|
||||
|
||||
class IAudioFile
|
||||
{
|
||||
public:
|
||||
virtual ~IAudioFile() = default;
|
||||
struct StreamInfo
|
||||
{
|
||||
size_t index{};
|
||||
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;
|
||||
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;
|
||||
};
|
||||
using MetadataMap = std::unordered_map<std::string, std::string>;
|
||||
|
||||
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::string mimeType;
|
||||
std::string format;
|
||||
};
|
||||
std::unique_ptr<IAudioFile> parseAudioFile(const std::filesystem::path& p);
|
||||
|
||||
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
|
||||
|
||||
|
||||
@@ -186,18 +186,9 @@ AvFormatParser::parse(const std::filesystem::path& p, bool debug)
|
||||
{
|
||||
const auto mediaFile {Av::parseAudioFile(p)};
|
||||
|
||||
// Stream info
|
||||
if (const auto stream{ mediaFile->getBestStreamInfo() })
|
||||
{
|
||||
track.bitrate = stream->bitrate;
|
||||
}
|
||||
else
|
||||
{
|
||||
LMS_LOG(METADATA, INFO) << "File '" << p.string() << "': cannot get best audio stream";
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
track.duration = mediaFile->getDuration();
|
||||
Av::ContainerInfo info{ mediaFile->getContainerInfo() };
|
||||
track.duration = info.duration;
|
||||
track.bitrate = info.bitrate;
|
||||
track.hasCover = mediaFile->hasAttachedPictures();
|
||||
|
||||
MetaData::Tags tags;
|
||||
|
||||
Reference in New Issue
Block a user