From 7a8dad33b463ad980e2fb88b3d82a32cfa16773b Mon Sep 17 00:00:00 2001 From: Vladimir Date: Wed, 26 Aug 2026 09:52:54 +0300 Subject: [PATCH] =?UTF-8?q?fix(web):=20libopus=20=D0=B8=D1=89=D0=B5=D1=82?= =?UTF-8?q?=D1=81=D1=8F=20=D0=BF=D0=BE=20=D0=BD=D0=B5=D1=81=D0=BA=D0=BE?= =?UTF-8?q?=D0=BB=D1=8C=D0=BA=D0=B8=D0=BC=20=D0=B8=D0=BC=D0=B5=D0=BD=D0=B0?= =?UTF-8?q?=D0=BC,=20=D0=B0=20=D0=BD=D0=B5=20=D0=BF=D0=BE=20=D0=BE=D0=B4?= =?UTF-8?q?=D0=BD=D0=BE=D0=BC=D1=83=20=D0=B7=D0=B0=D1=88=D0=B8=D1=82=D0=BE?= =?UTF-8?q?=D0=BC=D1=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Файл библиотеки в каждой сборке называется по-своему: MSYS2 кладёт libopus-0.dll, взятая из чужого дистрибутива или собранная руками — libopus.dll, у Unix это soname libopus.so.0, у Homebrew — .dylib в своём префиксе. Одно жёстко зашитое имя означало немой web там, где библиотека в системе есть: именно в это упирался инсталлятор, куда libopus приехал как libopus.dll (a2a12a0), тогда как LoadLibrary просил libopus-0.dll. Перебор кандидатов сделан ровно как у загрузчика PortAudio (AudioOutput.LoadLib): локальный массив имён и цикл до первой удачи. Проверено демоном на изолированном конфиге: с битой libopus.so.0 в LD_LIBRARY_PATH и целой libopus.so состояние отдаёт "opus":true (до правки на том же стенде было false), с битыми всеми тремя именами — false, и страница поднимает баннер. --- WebServer.pas | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/WebServer.pas b/WebServer.pas index 30536fd..9781ffe 100644 --- a/WebServer.pas +++ b/WebServer.pas @@ -81,6 +81,9 @@ unit WebServer; libopus в системе нет, LoadOpus молча возвращает False, кадры 'A' не уходят и микрофон не декодируется — раньше это выглядело как немой звук без объяснений. Теперь страница показывает баннер. + - (Audio fix 7) LoadOpus перебирает имена библиотеки (OPUS_LIBS), как + загрузчик PortAudio, а не грузит одно жёстко зашитое: libopus-0.dll / + libopus.dll / opus.dll, libopus.so.0 / .so, .dylib для macOS. } {$IFDEF FPC} @@ -756,14 +759,42 @@ end; ═══════════════════════════════════════════════════════════════════════════ } function TWebServer.LoadOpus: Boolean; +// Имя файла у каждой сборки libopus своё: MSYS2 кладёт рядом с exe libopus-0.dll, +// собранная руками или взятая из чужого дистрибутива — libopus.dll, у Unix это +// soname libopus.so.0, у Homebrew — .dylib в своём префиксе. Поэтому перебираем +// кандидатов, как это давно делает загрузчик PortAudio (AudioOutput.LoadLib): +// одно жёстко зашитое имя означало бы немой web там, где библиотека есть. const - {$IFDEF WINDOWS} LIBNAME = 'libopus-0.dll'; - {$ELSE} LIBNAME = 'libopus.so.0'; +{$IFDEF DARWIN} + OPUS_LIBS: array[0..3] of AnsiString = ( + 'libopus.dylib', + 'libopus.0.dylib', + '/usr/local/lib/libopus.dylib', + '/opt/homebrew/lib/libopus.dylib' + ); +{$ELSE} + {$IFDEF UNIX} + OPUS_LIBS: array[0..2] of AnsiString = ( + 'libopus.so.0', + 'libopus.so', + 'libopus.so.0.8.0' + ); + {$ELSE} + OPUS_LIBS: array[0..2] of AnsiString = ( + 'libopus-0.dll', + 'libopus.dll', + 'opus.dll' + ); {$ENDIF} -var Err: Integer; +{$ENDIF} +var Err, i: Integer; begin Result := False; - FOpusLib := LoadLibrary(LIBNAME); + for i := 0 to High(OPUS_LIBS) do + begin + FOpusLib := LoadLibrary(OPUS_LIBS[i]); + if FOpusLib <> 0 then Break; + end; if FOpusLib = 0 then Exit; FOpusCreate := TOpus_encoder_create( GetProcAddress(FOpusLib, 'opus_encoder_create'));