fix(microphone): resolve ALSA cards from sysfs

This commit is contained in:
linbo 2026-08-25 16:11:36 +08:00
parent 41b112efb7
commit 92c56e0de9
2 changed files with 20 additions and 5 deletions

View File

@ -10,7 +10,6 @@ add_library(cmvr_es::device::ffmpeg_microphone ALIAS ffmpeg_microphone)
target_link_libraries(ffmpeg_microphone PRIVATE
avfilter
avdevice
-lasound
-lpulse
cmvr_es::proto
)

View File

@ -2,6 +2,7 @@
#include <cerrno>
#include <cstdlib>
#include <fstream>
#include <limits>
#include <memory>
#include <optional>
@ -12,7 +13,6 @@
#include <utility>
extern "C" {
#include <alsa/asoundlib.h>
#include <libavdevice/avdevice.h>
#include <libavutil/error.h>
#include <pulse/pulseaudio.h>
@ -53,6 +53,22 @@ std::optional<int> parseNonNegativeInt(const char* value)
return static_cast<int>(parsed);
}
std::optional<int> findAlsaCardIndex(const std::string& card_name)
{
constexpr int kMaxAlsaCards = 256;
const auto numeric_card_index = parseNonNegativeInt(card_name.c_str());
for (int index = 0; index < kMaxAlsaCards; ++index) {
std::ifstream id_file(
"/sys/class/sound/card" + std::to_string(index) + "/id");
std::string id;
if (id_file && std::getline(id_file, id) &&
(id == card_name || (numeric_card_index && *numeric_card_index == index))) {
return index;
}
}
return std::nullopt;
}
std::optional<AlsaEndpoint> parseFfmpegCaptureEndpoint(const char* device_name)
{
constexpr std::string_view kPlugHardwarePrefix = "plughw:";
@ -78,12 +94,12 @@ std::optional<AlsaEndpoint> parseFfmpegCaptureEndpoint(const char* device_name)
const std::string card_name(name.substr(card_key + kCardKey.size(),
card_end - card_key - kCardKey.size()));
const std::string device_text(name.substr(device_key + kDeviceKey.size()));
const int card_index = snd_card_get_index(card_name.c_str());
const auto card_index = findAlsaCardIndex(card_name);
const auto device_index = parseNonNegativeInt(device_text.c_str());
if (card_index < 0 || !device_index) {
if (!card_index || !device_index) {
return std::nullopt;
}
return AlsaEndpoint{card_index, *device_index};
return AlsaEndpoint{*card_index, *device_index};
}
struct PulseSourceQuery {