Воспроизведение MediaStream с использованием AudioContext.createMediaStreamSource и HTMLAudioElement.srcObject

Я пытаюсь воспроизвести 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?

Скорее всего, вы не генерируете свой AudioContext из события, которому доверяет пользователь. Вам нужно возобновить() его в Chrome (правила для AudioContext несколько строже, чем для MediaElements). Кроме того, почему вы не можете использовать MediaElement?

Kaiido 19.02.2019 09:31

Я пытался сделать .resume() после некоторого клика, но это не помогло. Свойство FWIW AudioContext.state всегда равно running (developer.mozilla.org/en-US/docs/Web/API/BaseAudioContext/s‌​tate)

Adam Szmyd 19.02.2019 11:40

А можно воспроизвести на разных браузерах?

Kaiido 19.02.2019 11:44

Firefox и Chrome ведут себя одинаково

Adam Szmyd 19.02.2019 12:23

Интересно... А если подключить AnalyserNode к sourceNode, что-то получится? Откуда берется поток? (Мысли вслух: может ли это быть проблемой кросс-происхождения?)

Kaiido 19.02.2019 12:29

Похоже, что AnalyserNode ничего не получает из этого потока. Я попытаюсь сделать воспроизводимую демонстрацию с этим

Adam Szmyd 19.02.2019 14:28

Для меня это похоже на ошибку Chrome. ВФМ в Firefox.

jib 19.02.2019 15:29

@jib Я подтверждаю, что он работает в FF и не работает в Chrome (даже после перемещения всех пользовательских событий). Похоже, AudioContext не может пометить поток как потребляемый или что-то в этом роде, но обходной путь в любом случае довольно прост, хотя и довольно странный: new Audio().srcObject = mediaStream это все, что нужно, даже не нужно воспроизводить этот MediaElement... jsfiddle.net/agmbwzft Адам, по каким причинам вы можете не использовать MediaElement? А можете перепроверить, что у вас не сработало в FF?

Kaiido 19.02.2019 16:14

@Kaiido FWIW, это код plnkr.co/edit/ZlZV5R11Su5CKqLfFyAX?p=предварительный просмотр, который пытался выполнить требование в Chromium. Еще не рассматривал часть captureStream для Firefox. Звук воспроизводится на Chromium. Не уверен, что полный код использует OP.

guest271314 19.02.2019 17:23
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
5
9
4 074
1

Ответы 1

Как продемонстрировал @jib, это ошибка Chrome.
Я открыл новый выпуск, чтобы сообщить им об этом.

Я думал, что нашел обходной путь, просто назначив этот MediaStream srcObject фиктивного HTMLAudioElement,

new Audio().srcObject = mediaStream;

но почему-то при тестировании на моем локальном хосте он не сохранялся во времени, а в эта рабочий пример - сохраняется.

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

Добавьте к этому другие неисправленные ошибки в области, которая заставляет меня думать о ложных срабатываниях и вообще, я боюсь, что нет правильного решения, чем ждать, пока они это исправят...

Спасибо за это. Это похоже на общую проблему с веб-китом, поскольку я проверял это в Safari и Opera, и все страдают одинаково. Firefox действительно работает с jsfiddle

Adam Szmyd 20.02.2019 11:33

@AdamSzmyd а, у меня это работает в Safari12.0.3 без обходного пути, используя модифицированную версию html, которую я предоставил в crbug (более высокая совместимость с браузером): jsfiddle.net/px1ymj90 Так что я бы сказал, что это ошибка Blink (Opera, к сожалению, теперь просто скин над Chrome), что имеет смысл, поскольку разделение произошло до того, как webkit реализует что-либо из API MediaStream/WebRTC.

Kaiido 20.02.2019 13:30

Вы получили ответ на ошибку. На самом деле он предлагает мне обходной путь для ошибки, и кажется, что он работает: после присоединения потока к API веб-аудио, прикрепите его также к временному элементу HTML audio. После этого вы можете удалить весь элемент audio, и звук будет хорошо воспроизводиться через AudioContext!

Adam Szmyd 22.02.2019 07:57

@AdamSzmyd это обходной путь, о котором я говорю в своем ответе и в своем отчете об ошибке, но я также обнаружил, что он ненадежен, так как иногда он перестает работать через несколько секунд.

Kaiido 22.02.2019 09:14

Другие вопросы по теме