file: Read more metadata from audio files

We can always read the basic format information (sample rate, bit depth,
etc.), but we will also print artist, album, and title if available in
the metadata.
This commit is contained in:
kleines Filmröllchen 2023-03-07 16:59:02 +01:00 committed by Tim Flynn
parent a8963a270f
commit 0563048949
Notes: sideshowbarker 2024-07-18 05:37:06 +09:00
4 changed files with 51 additions and 8 deletions

View file

@ -492,7 +492,7 @@ if (BUILD_LAGOM)
if (NOT EMSCRIPTEN)
# LibELF is part of LibC in SerenityOS builds, but not in Lagom.
add_executable(file ../../Userland/Utilities/file.cpp)
target_link_libraries(file LibCompress LibCore LibELF LibGfx LibIPC LibMain)
target_link_libraries(file LibAudio LibCompress LibCore LibELF LibGfx LibIPC LibMain)
endif()
add_executable(gml-format ../../Userland/Utilities/gml-format.cpp)

View file

@ -41,7 +41,7 @@ set(utility_srcs
serenity_bin(BuggieBox)
target_sources(BuggieBox PRIVATE main.cpp)
target_link_libraries(BuggieBox PRIVATE LibMain LibShell LibCompress LibCore LibCrypto LibGfx LibLine LibRegex)
target_link_libraries(BuggieBox PRIVATE LibMain LibShell LibCompress LibCore LibCrypto LibGfx LibLine LibRegex LibAudio)
foreach(file IN LISTS utility_srcs)
buggiebox_utility(${file})

View file

@ -87,7 +87,7 @@ target_link_libraries(diff PRIVATE LibDiff)
target_link_libraries(disasm PRIVATE LibX86)
target_link_libraries(expr PRIVATE LibRegex)
target_link_libraries(fdtdump PRIVATE LibDeviceTree)
target_link_libraries(file PRIVATE LibGfx LibIPC LibCompress)
target_link_libraries(file PRIVATE LibGfx LibIPC LibCompress LibAudio)
target_link_libraries(functrace PRIVATE LibDebug LibX86)
target_link_libraries(gml-format PRIVATE LibGUI)
target_link_libraries(grep PRIVATE LibRegex)

View file

@ -5,6 +5,7 @@
*/
#include <AK/Vector.h>
#include <LibAudio/Loader.h>
#include <LibCompress/Gzip.h>
#include <LibCore/ArgsParser.h>
#include <LibCore/File.h>
@ -51,6 +52,48 @@ static Optional<DeprecatedString> image_details(StringView description, StringVi
return builder.to_deprecated_string();
}
static Optional<DeprecatedString> audio_details(StringView description, StringView path)
{
auto loader_or_error = Audio::Loader::create(path);
if (loader_or_error.is_error())
return {};
auto loader = loader_or_error.release_value();
StringBuilder builder;
builder.appendff("{}, {} Hz, {}-bit {}, {} samples ({} s)",
description,
loader->sample_rate(),
loader->bits_per_sample(),
loader->num_channels() == 1 ? "Mono" : "Stereo",
loader->total_samples(),
loader->total_samples() / loader->sample_rate());
auto metadata = loader->metadata();
Vector<String> metadata_parts;
if (metadata.title.has_value()) {
// FIXME: Use “pretty quotation” once our terminal fonts support these characters.
if (auto title_text = String::formatted("\"{}\"", metadata.title.value_or({})); !title_text.is_error()) {
// We intentionally discard the error, because not printing part of the metadata due to OOM is not a problem.
(void)metadata_parts.try_append(title_text.release_value());
}
}
if (metadata.album.has_value()) {
if (auto album_text = String::formatted("(Album: {})", metadata.album.value_or({})); !album_text.is_error())
(void)metadata_parts.try_append(album_text.release_value());
}
if (auto all_artists = metadata.all_artists(); !all_artists.is_error() && all_artists.value().has_value()) {
if (auto artist_text = String::formatted("by {}", all_artists.release_value().release_value()); !artist_text.is_error())
(void)metadata_parts.try_append(artist_text.release_value());
}
if (!metadata_parts.is_empty()) {
// New line for the metadata.
builder.append_code_point('\n');
builder.join(" "sv, metadata_parts);
}
return builder.to_deprecated_string();
}
static Optional<DeprecatedString> gzip_details(StringView description, StringView path)
{
auto file_or_error = Core::MappedFile::map(path);
@ -113,11 +156,11 @@ static Optional<DeprecatedString> elf_details(StringView description, StringView
__ENUMERATE_MIME_TYPE_DESCRIPTION("application/tar"sv, "tape archive"sv, description_only) \
__ENUMERATE_MIME_TYPE_DESCRIPTION("application/wasm"sv, "WebAssembly bytecode"sv, description_only) \
__ENUMERATE_MIME_TYPE_DESCRIPTION("application/x-7z-compressed"sv, "7-Zip archive"sv, description_only) \
__ENUMERATE_MIME_TYPE_DESCRIPTION("audio/flac"sv, "FLAC audio"sv, description_only) \
__ENUMERATE_MIME_TYPE_DESCRIPTION("audio/midi"sv, "MIDI notes"sv, description_only) \
__ENUMERATE_MIME_TYPE_DESCRIPTION("audio/mpeg"sv, "MP3 audio"sv, description_only) \
__ENUMERATE_MIME_TYPE_DESCRIPTION("audio/qoa"sv, "Quite OK Audio"sv, description_only) \
__ENUMERATE_MIME_TYPE_DESCRIPTION("audio/wave"sv, "WAVE audio"sv, description_only) \
__ENUMERATE_MIME_TYPE_DESCRIPTION("audio/flac"sv, "FLAC audio"sv, audio_details) \
__ENUMERATE_MIME_TYPE_DESCRIPTION("audio/midi"sv, "MIDI notes"sv, audio_details) \
__ENUMERATE_MIME_TYPE_DESCRIPTION("audio/mpeg"sv, "MP3 audio"sv, audio_details) \
__ENUMERATE_MIME_TYPE_DESCRIPTION("audio/qoa"sv, "Quite OK Audio"sv, audio_details) \
__ENUMERATE_MIME_TYPE_DESCRIPTION("audio/wave"sv, "WAVE audio"sv, audio_details) \
__ENUMERATE_MIME_TYPE_DESCRIPTION("extra/blender"sv, "Blender project file"sv, description_only) \
__ENUMERATE_MIME_TYPE_DESCRIPTION("extra/elf"sv, "ELF"sv, elf_details) \
__ENUMERATE_MIME_TYPE_DESCRIPTION("extra/ext"sv, "ext filesystem"sv, description_only) \