У меня есть встроенное устройство Linux, на котором работает ядро Linux 4.4 и QT5.9.1 с busybox. У меня есть два приложения, написанные на QT, одно с графическим интерфейсом пользователя, а другое - с серверной службой, также написанное на QT, но не имеющее графического интерфейса или каких-либо виджетов, только консоль. Недавно я пытался соединить и подключить аудиоустройства Bluetooth для записи и воспроизведения звука с помощью pulseaudio и bluez. У меня также есть камера, которая записывает видео в реальном времени, отображаемое в графическом интерфейсе пользователя, во время записи звука с гарнитуры Bluetooth. Это делается с помощью gstreamer в службе беспроводного контроллера.
Все это работает нормально, но когда я собираюсь воспроизвести сохраненные видео со звуком, я использую виджет «Видео» в графическом интерфейсе для упрощения. К сожалению, он не распознает аудиоустройство по умолчанию от pulseaudio как bluetooth-гарнитуру / динамик и вместо этого всегда выталкивает его из аудиоразъема 3,5 мм. Я попытался использовать этот код, чтобы распечатать список доступных аудиоустройств, а также то, что QT считает аудиоустройством по умолчанию:
const auto deviceInfos = QAudioDeviceInfo::availableDevices(QAudio::AudioOutput);
for (const QAudioDeviceInfo &deviceInfo : deviceInfos)
qDebug() << "Device name: " << deviceInfo.deviceName();
qWarning() << "default device: " << QAudioDeviceInfo::defaultOutputDevice().deviceName();
Первоначально я пробовал это в серверной службе беспроводного контроллера, и он печатает следующее:
[M] qWirelessController WirelessControllerMain::init - Device name: "default"
[M] qWirelessController WirelessControllerMain::init - Device name: "default:CARD=rockchipwitorch"
[M] qWirelessController WirelessControllerMain::init - Device name: "sysdefault:CARD=rockchipwitorch"
[M] qWirelessController WirelessControllerMain::init - Device name: "bluez_sink.0C_A6_94_E4_22_B9.headset_head_unit"
[M] qWirelessController WirelessControllerMain::init - Device name: "alsa_output.0.stereo-fallback"
[W] qWirelessController WirelessControllerMain::init - default device: "bluez_sink.0C_A6_94_E4_22_B9.headset_head_unit"
Таким образом, у серверной службы нет проблем с распознаванием аудиоустройства по умолчанию. Я попытался добавить этот же фрагмент кода в свое приложение с графическим интерфейсом и получил следующее сообщение об ошибке:
[W] MyGUI - PulseAudioService: pa_context_connect() failed with return: -1
[M] MyGUI HMIMain::init - Device name: "default"
[M] MyGUI HMIMain::init - Device name: "default:CARD=rockchipwitorch"
[M] MyGUI HMIMain::init - Device name: "sysdefault:CARD=rockchipwitorch"
[M] MyGUI HMIMain::init - Device name: ""
[W] MyGUI HMIMain::init - default device: ""
Это приводит к ошибке при попытке подключиться к услуге pulseaudio. Я много искал эту ошибку, и до сих пор ничего из найденного не имеет отношения к моей настройке или устраняет мою проблему. Я также обнаружил, что эта ошибка возникает во ВСЕХ приложениях с графическим интерфейсом пользователя. Я построил несколько примеров QT с графическим интерфейсом пользователя и без него и поместил в них этот фрагмент кода. Все приложения с графическим интерфейсом выдают одну и ту же ошибку pa_context_connect (), тогда как все консольные приложения не имеют проблем с подключением к импульсной аудио-службе.
Насколько я могу судить, не имеет значения, сколько консольных приложений QT запущено, все они могут подключаться к службе pulseaudio. Я также удостоверился, что никакие другие пользовательские приложения не работают, когда я пытаюсь подключить мое приложение с графическим интерфейсом к pulseaudio. В настоящее время я запускаю pulseaudio со следующими параметрами:
/usr/bin/pulseaudio -D --exit-idle-time=-1
Я попытался запустить его с параметром --system, а также установить переменную среды PULSE_SERVER = localhost, и в обоих случаях я получил следующую ошибку:
"PulseAudioService: Connection failure: Connection refused"
Если я запускаю pulseaudio в фоновом режиме (не как демон) и --vvvv, я вижу, что он распечатывает много информации, когда моя серверная служба подключается к нему, но, естественно, я ничего не вижу, когда мое приложение с графическим интерфейсом пытается подключиться к нему.
Я также попытался удалить все мои файлы cookie pulseaudio в папке .config / pulse /, как предложил один поток, но это также ничего не изменило.
Что касается файлов конфигурации в / etc / pulse /, я вернул их все в исходное состояние. Однако единственное изменение, которое мне пришлось сделать, - это добавить load-module module-stream-restore restore_device = false в default.pa, чтобы сохранить приемник по умолчанию.
Я действительно не хочу добавлять больше кода gstreamer для воспроизведения видео, поэтому мне бы очень хотелось разобраться, что здесь происходит.
РЕДАКТИРОВАТЬ: я недавно нашел переменную среды QT_DEBUG_PLUGINS и запустил свое приложение с установленным значением 1 и получил следующий результат:
[M] MyGUI - QFactoryLoader::QFactoryLoader() checking directory path "/usr/lib/qt/plugins/audio" ...
[M] MyGUI - QFactoryLoader::QFactoryLoader() looking at "/usr/lib/qt/plugins/audio/libqtaudio_alsa.so"
[W] MyGUI - Found metadata in lib /usr/lib/qt/plugins/audio/libqtaudio_alsa.so, metadata=
{
"IID": "org.qt-project.qt.audiosystemfactory/5.0",
"MetaData": {
"Keys": [
"alsa"
]
},
"className": "QAlsaPlugin",
"debug": false,
"version": 329988
}
[M] MyGUI - Got keys from plugin meta data ("alsa")
[M] MyGUI - QFactoryLoader::QFactoryLoader() looking at "/usr/lib/qt/plugins/audio/libqtmedia_pulse.so"
[W] MyGUI - Found metadata in lib /usr/lib/qt/plugins/audio/libqtmedia_pulse.so, metadata=
{
"IID": "org.qt-project.qt.audiosystemfactory/5.0",
"MetaData": {
"Keys": [
"default"
]
},
"className": "QPulseAudioPlugin",
"debug": false,
"version": 329988
}
[M] MyGUI - Got keys from plugin meta data ("default")
[M] MyGUI - QFactoryLoader::QFactoryLoader() checking directory path "/mnt/app/bin/audio" ...
[M] MyGUI - loaded library "/usr/lib/qt/plugins/audio/libqtaudio_alsa.so"
[M] MyGUI - loaded library "/usr/lib/qt/plugins/audio/libqtmedia_pulse.so"
[W] MyGUI - PulseAudioService: pa_context_connect() failed with return: -1
[M] MyGUI HMIMain::init - Device name: "default"
[M] MyGUI HMIMain::init - Device name: "default:CARD=rockchipwitorch"
[M] MyGUI HMIMain::init - Device name: "sysdefault:CARD=rockchipwitorch"
[M] MyGUI HMIMain::init - Device name: ""
[W] MyGUI HMIMain::init - default device: ""