Bug 1306999 - Make HTMLMediaElement::CanActivateAutoplay() spec compliant. r=jya,jib
HTMLMediaElement::CanActivateAutoplay() had an exception for MediaStreams in its check for whether autoplay can be activated. This removes that exception and requires us to be in HAVE_ENOUGH_DATA regardless of source, per spec. Doing this broke autoplay of an ended media element that's playing a MediaStream, since autoplay of this MediaStream could no longer be immediately activated. The exact sequence algorithm for autoplaying the stream in this case is not defined in mediacapture-main, but we know we must reach HAVE_ENOUGH_DATA to play, and we must run the load algorithm to reach HAVE_ENOUGH_DATA, that's what we do: When the MediaStream we're autoplaying once again becomes active, we run the media element load algorithm. Differential Revision: https://phabricator.services.mozilla.com/D33298
This commit is contained in:
@@ -4584,9 +4584,36 @@ class HTMLMediaElement::MediaStreamTrackListener
|
||||
if (!mElement) {
|
||||
return;
|
||||
}
|
||||
LOG(LogLevel::Debug, ("%p, mSrcStream %p became active", mElement.get(),
|
||||
mElement->mSrcStream.get()));
|
||||
mElement->CheckAutoplayDataReady();
|
||||
|
||||
// mediacapture-main says:
|
||||
// Note that once ended equals true the HTMLVideoElement will not play media
|
||||
// even if new MediaStreamTracks are added to the MediaStream (causing it to
|
||||
// return to the active state) unless autoplay is true or the web
|
||||
// application restarts the element, e.g., by calling play().
|
||||
//
|
||||
// This is vague on exactly how to go from becoming active to playing, when
|
||||
// autoplaying. However, per the media element spec, to play an autoplaying
|
||||
// media element, we must load the source and reach readyState
|
||||
// HAVE_ENOUGH_DATA [1]. Hence, a MediaStream being assigned to a media
|
||||
// element and becoming active runs the load algorithm, so that it can
|
||||
// eventually be played.
|
||||
//
|
||||
// [1]
|
||||
// https://html.spec.whatwg.org/multipage/media.html#ready-states:event-media-play
|
||||
|
||||
LOG(LogLevel::Debug, ("%p, mSrcStream %p became active, checking if we "
|
||||
"need to run the load algorithm",
|
||||
mElement.get(), mElement->mSrcStream.get()));
|
||||
if (!mElement->IsPlaybackEnded()) {
|
||||
return;
|
||||
}
|
||||
if (!mElement->Autoplay()) {
|
||||
return;
|
||||
}
|
||||
LOG(LogLevel::Info, ("%p, mSrcStream %p became active on autoplaying, "
|
||||
"ended element. Reloading.",
|
||||
mElement.get(), mElement->mSrcStream.get()));
|
||||
mElement->DoLoad();
|
||||
}
|
||||
|
||||
void NotifyInactive() override {
|
||||
@@ -4737,7 +4764,6 @@ void HTMLMediaElement::SetupSrcMediaStreamPlayback(DOMMediaStream* aStream) {
|
||||
|
||||
ChangeNetworkState(NETWORK_IDLE);
|
||||
ChangeDelayLoadStatus(false);
|
||||
CheckAutoplayDataReady();
|
||||
|
||||
// FirstFrameLoaded() will be called when the stream has tracks.
|
||||
}
|
||||
@@ -5573,9 +5599,6 @@ void HTMLMediaElement::ChangeNetworkState(nsMediaNetworkState aState) {
|
||||
}
|
||||
|
||||
bool HTMLMediaElement::CanActivateAutoplay() {
|
||||
// For stream inputs, we activate autoplay on HAVE_NOTHING because
|
||||
// this element itself might be blocking the stream from making progress by
|
||||
// being paused. We only check that it has data by checking its active state.
|
||||
// We also activate autoplay when playing a media source since the data
|
||||
// download is controlled by the script and there is no way to evaluate
|
||||
// MediaDecoder::CanPlayThrough().
|
||||
@@ -5618,10 +5641,7 @@ bool HTMLMediaElement::CanActivateAutoplay() {
|
||||
}
|
||||
}
|
||||
|
||||
bool hasData = (mDecoder && mReadyState >= HAVE_ENOUGH_DATA) ||
|
||||
(mSrcStream && mSrcStream->Active());
|
||||
|
||||
return hasData;
|
||||
return mReadyState >= HAVE_ENOUGH_DATA;
|
||||
}
|
||||
|
||||
void HTMLMediaElement::CheckAutoplayDataReady() {
|
||||
|
||||
Reference in New Issue
Block a user