1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 06:17:35 +00:00

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
4 changed files with 51 additions and 8 deletions

View file

@ -492,7 +492,7 @@ if (BUILD_LAGOM)
if (NOT EMSCRIPTEN) if (NOT EMSCRIPTEN)
# LibELF is part of LibC in SerenityOS builds, but not in Lagom. # LibELF is part of LibC in SerenityOS builds, but not in Lagom.
add_executable(file ../../Userland/Utilities/file.cpp) 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() endif()
add_executable(gml-format ../../Userland/Utilities/gml-format.cpp) add_executable(gml-format ../../Userland/Utilities/gml-format.cpp)

View file

@ -41,7 +41,7 @@ set(utility_srcs
serenity_bin(BuggieBox) serenity_bin(BuggieBox)
target_sources(BuggieBox PRIVATE main.cpp) 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) foreach(file IN LISTS utility_srcs)
buggiebox_utility(${file}) buggiebox_utility(${file})

View file

@ -87,7 +87,7 @@ target_link_libraries(diff PRIVATE LibDiff)
target_link_libraries(disasm PRIVATE LibX86) target_link_libraries(disasm PRIVATE LibX86)
target_link_libraries(expr PRIVATE LibRegex) target_link_libraries(expr PRIVATE LibRegex)
target_link_libraries(fdtdump PRIVATE LibDeviceTree) 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(functrace PRIVATE LibDebug LibX86)
target_link_libraries(gml-format PRIVATE LibGUI) target_link_libraries(gml-format PRIVATE LibGUI)
target_link_libraries(grep PRIVATE LibRegex) target_link_libraries(grep PRIVATE LibRegex)

View file

@ -5,6 +5,7 @@
*/ */
#include <AK/Vector.h> #include <AK/Vector.h>
#include <LibAudio/Loader.h>
#include <LibCompress/Gzip.h> #include <LibCompress/Gzip.h>
#include <LibCore/ArgsParser.h> #include <LibCore/ArgsParser.h>
#include <LibCore/File.h> #include <LibCore/File.h>
@ -51,6 +52,48 @@ static Optional<DeprecatedString> image_details(StringView description, StringVi
return builder.to_deprecated_string(); 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) static Optional<DeprecatedString> gzip_details(StringView description, StringView path)
{ {
auto file_or_error = Core::MappedFile::map(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/tar"sv, "tape archive"sv, description_only) \
__ENUMERATE_MIME_TYPE_DESCRIPTION("application/wasm"sv, "WebAssembly bytecode"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("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/flac"sv, "FLAC audio"sv, audio_details) \
__ENUMERATE_MIME_TYPE_DESCRIPTION("audio/midi"sv, "MIDI notes"sv, description_only) \ __ENUMERATE_MIME_TYPE_DESCRIPTION("audio/midi"sv, "MIDI notes"sv, audio_details) \
__ENUMERATE_MIME_TYPE_DESCRIPTION("audio/mpeg"sv, "MP3 audio"sv, description_only) \ __ENUMERATE_MIME_TYPE_DESCRIPTION("audio/mpeg"sv, "MP3 audio"sv, audio_details) \
__ENUMERATE_MIME_TYPE_DESCRIPTION("audio/qoa"sv, "Quite OK Audio"sv, description_only) \ __ENUMERATE_MIME_TYPE_DESCRIPTION("audio/qoa"sv, "Quite OK Audio"sv, audio_details) \
__ENUMERATE_MIME_TYPE_DESCRIPTION("audio/wave"sv, "WAVE audio"sv, description_only) \ __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/blender"sv, "Blender project file"sv, description_only) \
__ENUMERATE_MIME_TYPE_DESCRIPTION("extra/elf"sv, "ELF"sv, elf_details) \ __ENUMERATE_MIME_TYPE_DESCRIPTION("extra/elf"sv, "ELF"sv, elf_details) \
__ENUMERATE_MIME_TYPE_DESCRIPTION("extra/ext"sv, "ext filesystem"sv, description_only) \ __ENUMERATE_MIME_TYPE_DESCRIPTION("extra/ext"sv, "ext filesystem"sv, description_only) \