Я пытаюсь воспроизвести MediaStream с удаленного узла (WebRTC) с помощью Web Audio API. Когда я присоединяю поток к элементу audio с помощью audio.srcObject = stream, он воспроизводится нормально, но когда я пытаюсь использовать AudioContext, он вообще не воспроизводит звук (мне нужно избегать HTML-тега audio/video).
Эта штука работает:
<audio controls>
<script>
const audioEl = document.getElementsByTagName('audio')[0];
audioEl.srcObject = MY_STREAM;
audioEl.play();
</script>
Этот не:
const audioContext = new AudioContext();
const sourceNode = audioContext.createMediaStreamSource(MY_STREAM);
sourceNode.connect(audioContext.destination);
// Trying even 'audioContext.resume()' after user gesture with no luck
Что странно, так это то, что когда MY_STREAM имеет значение мой микрофон, тогда он прекрасно воспроизводится для API веб-аудио (я слышу обратную связь со своего микрофона).
Таким образом, можно предположить, что между микрофонным MediaStream и тем, который я получаю от соединения WebRTC, есть что-то другое, но почему он воспроизводится для простого тега HTML audio?
Я пытался сделать .resume() после некоторого клика, но это не помогло. Свойство FWIW AudioContext.state всегда равно running (developer.mozilla.org/en-US/docs/Web/API/BaseAudioContext/state)
А можно воспроизвести на разных браузерах?
Firefox и Chrome ведут себя одинаково
Интересно... А если подключить AnalyserNode к sourceNode, что-то получится? Откуда берется поток? (Мысли вслух: может ли это быть проблемой кросс-происхождения?)
Похоже, что AnalyserNode ничего не получает из этого потока. Я попытаюсь сделать воспроизводимую демонстрацию с этим
Для меня это похоже на ошибку Chrome. ВФМ в Firefox.
@jib Я подтверждаю, что он работает в FF и не работает в Chrome (даже после перемещения всех пользовательских событий). Похоже, AudioContext не может пометить поток как потребляемый или что-то в этом роде, но обходной путь в любом случае довольно прост, хотя и довольно странный: new Audio().srcObject = mediaStream это все, что нужно, даже не нужно воспроизводить этот MediaElement... jsfiddle.net/agmbwzft Адам, по каким причинам вы можете не использовать MediaElement? А можете перепроверить, что у вас не сработало в FF?
@Kaiido FWIW, это код plnkr.co/edit/ZlZV5R11Su5CKqLfFyAX?p=предварительный просмотр, который пытался выполнить требование в Chromium. Еще не рассматривал часть captureStream для Firefox. Звук воспроизводится на Chromium. Не уверен, что полный код использует OP.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Как продемонстрировал @jib, это ошибка Chrome.
Я открыл новый выпуск, чтобы сообщить им об этом.
Я думал, что нашел обходной путь, просто назначив этот MediaStream srcObject фиктивного HTMLAudioElement,
new Audio().srcObject = mediaStream;
но почему-то при тестировании на моем локальном хосте он не сохранялся во времени, а в эта рабочий пример - сохраняется.
Я также столкнулся с множеством других странных действий, играя, например, разные вкладки, попадающие на другие и тому подобное.
Добавьте к этому другие неисправленные ошибки в области, которая заставляет меня думать о ложных срабатываниях и вообще, я боюсь, что нет правильного решения, чем ждать, пока они это исправят...
Спасибо за это. Это похоже на общую проблему с веб-китом, поскольку я проверял это в Safari и Opera, и все страдают одинаково. Firefox действительно работает с jsfiddle
@AdamSzmyd а, у меня это работает в Safari12.0.3 без обходного пути, используя модифицированную версию html, которую я предоставил в crbug (более высокая совместимость с браузером): jsfiddle.net/px1ymj90 Так что я бы сказал, что это ошибка Blink (Opera, к сожалению, теперь просто скин над Chrome), что имеет смысл, поскольку разделение произошло до того, как webkit реализует что-либо из API MediaStream/WebRTC.
Вы получили ответ на ошибку. На самом деле он предлагает мне обходной путь для ошибки, и кажется, что он работает: после присоединения потока к API веб-аудио, прикрепите его также к временному элементу HTML audio. После этого вы можете удалить весь элемент audio, и звук будет хорошо воспроизводиться через AudioContext!
@AdamSzmyd это обходной путь, о котором я говорю в своем ответе и в своем отчете об ошибке, но я также обнаружил, что он ненадежен, так как иногда он перестает работать через несколько секунд.
Скорее всего, вы не генерируете свой AudioContext из события, которому доверяет пользователь. Вам нужно возобновить() его в Chrome (правила для AudioContext несколько строже, чем для MediaElements). Кроме того, почему вы не можете использовать MediaElement?