Почему завершенное событие не запускается для этого MediaStreamTrack? - PullRequest
2 голосов
/ 02 мая 2019

Я хотел бы получить информацию о конце MediaStreamTrack.Согласно MDN событие ended имеет значение

Отправляется, когда заканчивается воспроизведение трека (когда значение readyState изменяется на ended).Также доступно с использованием свойства обработчика событий onended.

Так что я должен иметь возможность настраивать свои обратные вызовы, например:

const [track] = stream.getVideoTracks();
track.addEventListener('ended', () => console.log('track ended'));
track.onended = () => console.log('track onended');

, и я ожидаю, что они будут вызваны, как только я остановил трек с помощью:

tracks.forEach(track => track.stop());
// for good measure? See
// https://developer.mozilla.org/en-US/docs/Web/API/MediaStreamTrack/stop#Stopping_a_video_stream
videoElem.srcObject = null;

Проблема, с которой я столкнулся, заключается в том, что обратные вызовы не вызываются .Я построил следующее JSFiddle , где 3 MediaStream создаются 3 различными способами:

  1. getUserMedia
  2. getDisplayMedia
  3. getCaptureStream (элемент canvas)

У меня также есть 3 кнопки, которые останавливают все дорожки для соответствующих MediaStream.Поведение выглядит следующим образом:

  • Все 3 потока inactive, обратный вызов MediaStream oninactive запущен (в Chrome похоже, что Firefox не поддерживает это ).
  • После остановки все дорожки имеют readyState из ended.
  • Если я остановлю поток экрана (2. getDisplayMedia) через пользовательский интерфейс Chrome, дорожка завершит обратный вызов (и)

Chrome's stop sharing button

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

Поскольку несколько дорожек могут использовать один и тот же источник (например, если две вкладки используют микрофон устройства), сам источник не обязательно сразу останавливается.Вместо этого он отсоединяется от дорожки, и объект дорожки останавливается.Как только медиа-треки не используют источник, источник может быть фактически остановлен.

1 Ответ

2 голосов
/ 03 мая 2019

Почему событие «завершено» не запускается для этого MediaStreamTrack?

Поскольку закончилась явно не срабатывает, когда вы сами вызываете track.stop () . Он срабатывает только когда трек заканчивается по другим причинам. Из спецификации:

Запускается, когда ...

Источник объекта MediaStreamTrack больше не будет предоставлять никаких данных, либо потому, что пользователь отменил разрешения, либо потому, что исходное устройство было извлечено, либо потому, что удаленный узел навсегда прекратил отправку данных.

Это по замыслу. Мысль была в том, что вам не нужно событие, когда вы сами его останавливаете. Чтобы обойти это, сделайте:

track.stop();
track.dispatchEvent(new Event("ended"));

Включается неактивный обратный вызов MediaStream (в Chrome кажется, что Firefox этого не поддерживает).

stream.oninactive и событие inactive устарели и больше не указаны в спецификации.

В качестве обходного пути для этого вы можете использовать подобное оконченное событие для медиа-элемента:

video.srcObject = stream;
await new Promise(resolve => video.onloadedmetadata = resolve);
video.addEventListener("ended", () => console.log("inactive!")); 

Увы, в Chrome он еще не работает, но в Firefox работает .

...