Используя Alsa, как я могу получить текущие уровни воспроизведения звука через ffmpeg или mpg123 для отображения на веб-панели инструментов?

Мне не хочется копаться в источниках 25 -летних снарядов, но

Это может быть уязвимость формата -строки .

Если оболочка содержит такой код, как

printf(str);

где str— некоторая строка, полученная из пользовательского ввода, содержимое строки будет строкой формата, используемой printf. %sговорит printfнапечатать строку, на которую указывает аргумент. Если аргументы не заданы (, как указано выше, есть только строка формата ), функция будет считывать некоторые другие данные из стека и следовать за ними в качестве указателей. Вероятно, доступ к неотображенной памяти и сбой процесса.

В некотором смысле, я думаю, что формулировка сообщения также намекает на подобное решение. Если вы наберете !xxx,что оболочка явно делает, так это печатает сообщение об ошибке, например !xxx: event not found. Оттуда несложно попытаться также напечатать !xxx%s%s%s%s%s%s%s%s: event not foundс последствиями уязвимости строки формата.


Я не должен был, но я заглянул в источник здесь (4.3BSD-Tahoe/usr/src/bin/csh, даты от 1988 ).

findev(cp, anyarg)вsh.lex.cпохоже, это функция поиска соответствующего события истории :это просматривает связанный список struct Histс именем Histlist. Если ничего не находит, вызывается с seterr2(cp, ": Event not found");по noev(). cpздесь выглядит искомая строка в истории.

seterr2()устанавливает переменную errкак конкатенацию аргументов, а errиспользуется как if (err) error(err);в паре мест в process(), вsh.c. Наконец,error()sh.err.c)содержит классическую уязвимость строки формата :if (s) printf(s, arg), printf(".\n");

.

В некоторых других местах error()вызывается с аргументом, например error("Unknown user: %s", gpath + 1);, так что ясно, что идея состоит в том, что первый аргумент error()может быть строкой формата.

Я был бы нечестным, если бы сказал, что полностью разобрался в функциях подстановки истории. Это в значительной степени некомментарированная ручная обработка строк в C. %действительно имеет особое значение в подстановке истории, но я вижу, что она обрабатывается только как первый символ (, как в!%)или после того, как findev()вызывается.

1
22.08.2019, 21:12
1 ответ

Самый простой (хотя определенно не самый дешевый, -мудрый )способ сделать это, который я могу придумать, это заставить ffmpeg время от времени выводить изображение с измерителем громкости, вдобавок к его нормальному выходу. Вы можете сделать это примерно так:

ffmpeg -i «INPUT» \
    -filter_complex '[0:a]ebur128=video=1:meter=18:metadata=0[g][j], [j]anullsink, [g]fps=1[g]' \
    -map '[g]' -f image2 -update 1 -y «IMAGEFILE».png \
    -map '0:a' -c:a copy -y «AUDIO_OUTPUT»

Это должно выводить изображение один раз в секунду (хотя обратите внимание, что это происходит каждую секунду обработанного звука; ffmpeg будет работать так быстро, как позволяет ЦП, по крайней мере, если выходные данные будут принимать данные так быстро. Я предполагаю, что ваш вывод ограничивает его работой со скоростью 1x ). Вы можете изменить частоту обновления изображения, изменив значение fps=; 2 будет означать два раза в секунду, а 0,5 — каждые 2 секунды.

Очевидно, что если ffmpeg выйдет из строя, изображение просто перестанет обновляться. Точно так же, если он остановлен, например, потому что на выходе не будет больше данных или если на входе их нет. Время модификации на изображении сделает очевидным, что это произошло. Вы также можете добавить временную метку ffmpeg поверх изображения с текущим временем, используя фильтр drawtext:

.
⋮
    -filter_complex '[0:a]ebur128=video=1:meter=18:metadata=0[g][j], [j]anullsink, [g]fps=1, drawtext=text=%{localtime} %{pts}:x=60:y=460:fontcolor=Cyan[g]'
⋮

Тогда вам даже не нужен PHP — вам просто нужно обслуживать статическое изображение:

ffmpeg ebur128 output image showing fairly loud, minimal dynamic range audio playing

PS :Что касается написания сценариев, если он бесшумный, лучше всего это сделать в вашем приложении — и, к вашему сведению, у вас могут быть одни и те же метаданные вывода фильтра ebur128 в различных форматах (, например, JSON ), так что вы можно проверить, не замолчал ли он. К сожалению, он смешивается с другим выводом ffmpeg, поэтому синтаксический анализ может немного раздражать. Я написал Perl-код для этого , но вы, вероятно, сочтете, что это достаточно легко сделать на выбранном вами языке сценариев.

2
27.01.2020, 23:30

Теги

Похожие вопросы