本文介绍了为什么没有为此MediaStreamTrack触发“结束"事件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道事件是

所以我应该能够设置我的回调,例如:

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种不同方式创建了3个MediaStream:

  1. getUserMedia
  2. getDisplayMedia
  3. getCaptureStream (画布元素)

我还有3个按钮,用于停止各个MediaStream的所有曲目.行为如下:

  • 所有3个流均为inactive,并触发了MediaStream的oninactive回调(在Chrome浏览器中,似乎Firefox不支持此功能).
  • 所有曲目在停止后的readyState均为ended.
  • 如果我通过Chrome的UI停止屏幕流(2. getDisplayMedia),则会调用跟踪结束的回调.

我知道您必须当心多个来源正在使用的曲目,但是这里不应该是这样吗?我缺少明显的东西吗?

解决方案

为什么未为此MediaStreamTrack触发结束"事件?

因为已结束明确地是 track.stop()自己.仅在轨道由于其他原因而结束时才会触发.根据规格:

这是设计使然.当时的想法是,当您自己停止事件时,您不需要事件.要解决此问题,请执行以下操作:

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

MediaStream的oninactive回调被触发(在Chrome中,似乎Firefox不支持此回调.)

stream.oninactive和inactive事件已弃用,不再在规范中.

为此,您可以使用类似的已结束事件:

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

可惜,这似乎无法在Chrome浏览器中使用,但它在Firefox中可以使用./p>

I'd like to be informed about a MediaStreamTrack's end. According to MDN an ended event is

So I should be able to setup my callback(s) like:

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

and I expect those to be invoked, once I stop the track via:

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;

The problem I'm having is that the callbacks are not invoked. I built the following JSFiddle, where 3 MediaStreams are created in 3 different ways:

  1. getUserMedia
  2. getDisplayMedia
  3. getCaptureStream (canvas element)

I also have 3 buttons which stop all tracks for the respective MediaStream. The behaviour is as follows:

  • All 3 streams are inactive, the MediaStream's oninactive callback is triggered (in Chrome, seems like Firefox doesn't support this).
  • All tracks have a readyState of ended after being stopped.
  • If I stop the screen stream (2. getDisplayMedia) via Chrome's UI, the track ended callback(s) are invoked.

I know that you have to watch out for the track being used by multiple sources, but that shouldn't be the case here, right? Am I missing something obvious?

解决方案

Why is the 'ended' event not firing for this MediaStreamTrack?

Because ended is explicitly not fired when you call track.stop() yourself. It only fires when a track ends for other reasons. From the spec:

This is by design. The thinking was you don't need an event when you stop it yourself. To work around it do:

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

MediaStream's oninactive callback is triggered (in Chrome, seems like Firefox doesn't support this).

stream.oninactive and the inactive event are deprecated, and no longer in the spec.

As a workaround for that, you can use the similar ended event on a media element:

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

Alas, that does not appear to work in Chrome yet, but it works in Firefox.

这篇关于为什么没有为此MediaStreamTrack触发“结束"事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-24 09:28