fix(web): libopus ищется по нескольким именам, а не по одному зашитому

Файл библиотеки в каждой сборке называется по-своему: 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, и страница
поднимает баннер.
This commit is contained in:
2026-08-26 09:52:54 +03:00
parent a2a12a0d24
commit 7a8dad33b4
+35 -4
View File
@@ -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'));