очищает ли веб-аудио API исходный узел после окончания воспроизведения?

когда пользователь нажимает кнопку, воспроизводится звук, а если он нажимает ее снова, воспроизводится новый экземпляр того же самого звука.

я делаю это, подключая новый исходный узел к аудио-контексту при каждом щелчке.

теперь скажем, что пользователь нажимает кнопку в течение 1 часа, удаляется ли каждый исходный узел, который закончил воспроизведение, или он остается подключенным к аудио-контексту?


person soufiane yakoubi    schedule 17.03.2019    source источник
comment
в вашем браузере нажмите cntrl+shift+i, чтобы отобразить инструменты разработчика --› Сеть --> выполните клик и наблюдайте за трафиком --- тогда вы вооружены навыками, чтобы ответить на этот вопрос и поставить вас на большой путь к другим вопросам   -  person Scott Stensland    schedule 18.03.2019


Ответы (2)


Вот соответствующие спецификации:

Следующие поведения обеспечивают нормативное описание условий, при которых AudioNode жив, что означает, что он ДОЛЖЕН быть сохранен в графе реализацией. Если эти условия не применяются, AudioNodes МОГУТ быть освобождены реализацией.

Существует несколько типов ссылок:

  1. Обычная ссылка, подчиняющаяся обычным правилам сборки мусора.

  2. Эталон воспроизведения для AudioBufferSourceNodes, MediaElementAudioSourceNodes, MediaStreamAudioSourceNodes и OscillatorNodes. Эти узлы сохраняют игровую ссылку на себя, пока они в данный момент играют.

  3. Ссылка на соединение, которая возникает, если другой AudioNode подключен к одному или нескольким его входам. Соединения с AudioParams узла не подразумевают ссылку на соединение.

  4. Ссылка на хвостовое время, которую AudioNode поддерживает сам по себе, пока у него есть какое-либо внутреннее состояние обработки, которое еще не было передано. Например, ConvolverNode имеет хвост, который продолжает играть даже после получения беззвучного ввода (представьте, что вы хлопаете в ладоши в большом концертном зале и продолжаете слышать, как звук разносится по всему залу). Некоторые AudioNodes имеют это свойство. См. подробности для конкретных узлов.

  5. MediaStreams поддерживает MediaStreamAudioSourceNode в активном состоянии до тех пор, пока базовый MediaStreamTrack, который воспроизводится через MediaStreamAudioSourceNode, не закончился (согласно [mediacapture-streams]).

  6. HTMLMediaElements поддерживает связанный с ними MediaElementAudioSourceNode, пока HTMLMediaElement находится в состоянии, когда звук может быть воспроизведен в будущем.

Таким образом, в случае, например, AudioBufferSourceNode, поскольку он не имеет ни input(3), ни tail-time(4), он не связан с внешним MediaStream( 5) или MediaElement(6), если вы не сохраняете ссылку на узел в своем js-коде(1), и что узел закончил воспроизведение(2), то его можно удалить из графа, а затем мусор Собрано.


Также обратите внимание, что большинство узлов source в любом случае имеют очень небольшой отпечаток пальца.

Если мы снова возьмем в качестве примера AudioBufferSourceNodes, то вы должны понимать, что они не дублируют AudioBuffer, они просто ссылаются на него.
Таким образом, создавая тысячи AudioBufferSourceNodes из одного и того же AudioBuffer.

Однако создавать тысячи AudioBuffers из одного и того же ArrayBuffer или тысячи ArrayBuffers из одного и того же файла или и то, и другое совсем не годится, так что Убедитесь, что при обработке события щелчка все, что вы делаете, — это создаете новый AudioBufferSourceNode из уже существующего AudioBuffer.

person Kaiido    schedule 20.03.2019
comment
все, что я делаю прямо сейчас, это вызов функции play(buffer), которая создает исходный узел со ссылкой на Audiobuffer, а затем подключает его к контексту. Итак, если я правильно понимаю, поскольку исходный узел нигде не упоминается, он будет собирать мусор, потому что на него нет ссылки нигде в коде, верно? - person soufiane yakoubi; 20.03.2019
comment
Да, это правильно. Как только он закончит играть. - person Kaiido; 20.03.2019
comment
как насчет создания нескольких аудиоконтекстов? это плохая практика? мне нужно использовать два. - person soufiane yakoubi; 20.03.2019
comment
Да, AudioContexts вряд ли привязаны к оборудованию, поэтому лучше избегать слишком большого количества одновременных контекстов, некоторые браузеры даже установили ограничение на количество одновременных контекстов, которые вы можете иметь. Но я не могу придумать ни одной причины, по которой вам может понадобиться более одного контекста в вашем собственном коде. - person Kaiido; 20.03.2019
comment
я пытаюсь практиковать API веб-аудио, делая драм-машину. Итак, моя проблема заключалась в том, что если пользователь выбирает некоторые ранее записанные треки, а затем воспроизводит их одновременно, он все еще может использовать пэды, и то же самое происходит, когда он ставит на паузу те же самые треки. после некоторых исследований я закончил с этой идеей использования двух аудиоконтекстов, один для пэдов и один для записанных дорожек, поэтому я могу приостановить их по отдельности, вызвав tracksContext.suspend() и tracksContext.resume(), и tracksContext.close(), чтобы закрыть контекст, когда дорожка не воспроизводится. - person soufiane yakoubi; 20.03.2019
comment
Хм, интересно... Должен признаться, я никогда не думал об использовании context.suspend как средства приостановить все за один раз. Это действительно звучит как хороший вариант использования. Но будьте осторожны, вы можете столкнуться с неожиданным поведением. Например, при быстром тестировании я увидел, что Chrome выполняет GC всех неподключенных узлов в состоянии suspend, это означает, что в эта скрипта, где я использовал AnalyserNode в качестве листа, он собирал мусор при приостановке. (таким образом, обходным путем является подключение AnalyserNode к месту назначения через отключенный узел здесь). - person Kaiido; 21.03.2019
comment
в моем случае я буду использовать исходные узлы (по одному на каждую дорожку), некоторые из них будут зациклены, возможно, подключены к узлу задержки/усиления и т. д., и, наконец, подключены к месту назначения. так что я не думаю, что у меня будет эта проблема сейчас. - person soufiane yakoubi; 21.03.2019

BufferSourceNode не будет удален, если он все еще подключен к аудиоконтексту. Вы можете проверить это, используя инструменты разработчика Firefox Web Audio или установив расширение Audion Chrome.

Вы можете добавить функцию onended в BufferSourceNode, чтобы отключить его после использования. Затем, пока ничто другое не имеет ссылки на этот исходный узел буфера, он будет очищен сборщиком мусора.

Источник: https://developer.mozilla.org/en-US/docs/Web/API/AudioScheduledSourceNode/onended

person Anonymous    schedule 20.03.2019
comment
Сама причина, по которой у нас нет обратной ссылки на соединения, заключалась в том, чтобы разрешить сборку мусора для узлов после того, как мы закончим с ними. Я бы очень удивился, если бы их не было. Возможно, вам следует обвинить свой Dev-инструмент/расширение в сохранении ссылки на эти узлы. - person Kaiido; 20.03.2019