Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(386)

Unified Diff: third_party/WebKit/Source/modules/mediacapturefromelement/HTMLMediaElementCapture.cpp

Issue 2727583007: HTMLMediaElement capture: teach the captured MStream to follow up source events (Closed)
Patch Set: Made the media element and the MediaStream Members of MediaElementEventListener Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/modules/mediacapturefromelement/HTMLMediaElementCapture.cpp
diff --git a/third_party/WebKit/Source/modules/mediacapturefromelement/HTMLMediaElementCapture.cpp b/third_party/WebKit/Source/modules/mediacapturefromelement/HTMLMediaElementCapture.cpp
index 53b90572d80ae6893decad49b02d28ac6807d988..23de329dcaedf1192c1a42ef30f9bc663bdf6c92 100644
--- a/third_party/WebKit/Source/modules/mediacapturefromelement/HTMLMediaElementCapture.cpp
+++ b/third_party/WebKit/Source/modules/mediacapturefromelement/HTMLMediaElementCapture.cpp
@@ -5,6 +5,7 @@
#include "modules/mediacapturefromelement/HTMLMediaElementCapture.h"
#include "core/dom/ExceptionCode.h"
+#include "core/events/EventListener.h"
#include "core/html/HTMLMediaElement.h"
#include "core/html/track/AudioTrackList.h"
#include "core/html/track/VideoTrackList.h"
@@ -19,16 +20,89 @@
namespace blink {
+namespace {
+
+// Class to register to the events of |m_mediaElement|, acting accordingly on
+// the tracks of |m_mediaStream|.
+class MediaElementEventListener final : public EventListener {
+ WTF_MAKE_NONCOPYABLE(MediaElementEventListener);
+
+ public:
+ MediaElementEventListener(HTMLMediaElement* element, MediaStream* stream)
+ : EventListener(CPPEventListenerType),
+ m_mediaElement(element),
+ m_mediaStream(stream) {}
+
+ DECLARE_VIRTUAL_TRACE();
+
+ private:
+ // EventListener implementation.
+ void handleEvent(ExecutionContext*, Event*) override;
+ bool operator==(const EventListener& other) const override {
+ return this == &other;
+ }
+
+ Member<HTMLMediaElement> m_mediaElement;
+ Member<MediaStream> m_mediaStream;
+};
+
+void MediaElementEventListener::handleEvent(ExecutionContext* context,
+ Event* event) {
+ DVLOG(2) << __func__ << " " << event->type();
+ DCHECK(m_mediaStream);
+
+ if (event->type() == EventTypeNames::ended) {
+ MediaStreamTrackVector tracks = m_mediaStream->getTracks();
+ for (size_t i = 0; i < tracks.size(); ++i) {
haraken 2017/03/06 18:37:29 iterator is preferred, since tracks[i] involves CH
mcasas 2017/03/06 19:38:59 Oh I thought WebVector didn't have iterators. Awes
+ tracks[i]->stopTrack(ASSERT_NO_EXCEPTION);
+ m_mediaStream->removeTrackByComponent(tracks[i]->component());
+ }
+
+ m_mediaStream->streamEnded();
+ return;
+ }
+ if (event->type() != EventTypeNames::loadedmetadata)
+ return;
+
+ WebMediaStream webStream;
+ webStream.initialize(WebVector<WebMediaStreamTrack>(),
+ WebVector<WebMediaStreamTrack>());
+
+ if (m_mediaElement->hasVideo()) {
+ Platform::current()->createHTMLVideoElementCapturer(
+ &webStream, m_mediaElement->webMediaPlayer());
+ }
+ if (m_mediaElement->hasAudio()) {
+ Platform::current()->createHTMLAudioElementCapturer(
+ &webStream, m_mediaElement->webMediaPlayer());
+ }
+
+ WebVector<WebMediaStreamTrack> videoTracks;
+ webStream.videoTracks(videoTracks);
+ for (size_t i = 0; i < videoTracks.size(); ++i)
haraken 2017/03/06 18:37:29 Ditto.
mcasas 2017/03/06 19:38:59 Done.
+ m_mediaStream->addTrackByComponent(videoTracks[i]);
+
+ WebVector<WebMediaStreamTrack> audioTracks;
+ webStream.audioTracks(audioTracks);
+ for (size_t i = 0; i < audioTracks.size(); ++i)
haraken 2017/03/06 18:37:29 Ditto.
mcasas 2017/03/06 19:38:59 Done.
+ m_mediaStream->addTrackByComponent(audioTracks[i]);
+
+ DVLOG(2) << "#videotracks: " << videoTracks.size()
+ << " #audiotracks: " << audioTracks.size();
+}
+
+DEFINE_TRACE(MediaElementEventListener) {
+ visitor->trace(m_mediaElement);
+ visitor->trace(m_mediaStream);
+ EventListener::trace(visitor);
+}
+
+} // anonymous namespace
+
// static
MediaStream* HTMLMediaElementCapture::captureStream(
HTMLMediaElement& element,
ExceptionState& exceptionState) {
- if (element.currentSrc().isNull()) {
- exceptionState.throwDOMException(NotSupportedError,
- "The media element must have a source.");
- return nullptr;
- }
-
// Avoid capturing from EME-protected Media Elements.
if (HTMLMediaElementEncryptedMedia::mediaKeys(element)) {
// This exception is not defined in the spec, see
@@ -38,26 +112,39 @@ MediaStream* HTMLMediaElementCapture::captureStream(
return nullptr;
}
+ WebMediaStream webStream;
+ webStream.initialize(WebVector<WebMediaStreamTrack>(),
+ WebVector<WebMediaStreamTrack>());
+
+ // create() duplicates the MediaStreamTracks inside |webStream|.
+ MediaStream* stream =
+ MediaStream::create(element.getExecutionContext(), webStream);
+
+ EventListener* listener = new MediaElementEventListener(&element, stream);
+ element.addEventListener(EventTypeNames::loadedmetadata, listener, false);
+ element.addEventListener(EventTypeNames::ended, listener, false);
+
// If |element| is actually playing a MediaStream, just clone it.
- if (HTMLMediaElement::isMediaStreamURL(element.currentSrc().getString())) {
+ if (!element.currentSrc().isNull() &&
+ HTMLMediaElement::isMediaStreamURL(element.currentSrc().getString())) {
return MediaStream::create(
element.getExecutionContext(),
MediaStreamRegistry::registry().lookupMediaStreamDescriptor(
element.currentSrc().getString()));
}
- WebMediaStream webStream;
- webStream.initialize(WebVector<WebMediaStreamTrack>(),
- WebVector<WebMediaStreamTrack>());
- MediaStreamCenter::instance().didCreateMediaStream(webStream);
-
- if (element.hasVideo())
+ if (element.hasVideo()) {
Platform::current()->createHTMLVideoElementCapturer(
&webStream, element.webMediaPlayer());
- if (element.hasAudio())
+ }
+ if (element.hasAudio()) {
Platform::current()->createHTMLAudioElementCapturer(
&webStream, element.webMediaPlayer());
- return MediaStream::create(element.getExecutionContext(), webStream);
+ }
+
+ // If element.currentSrc().isNull() then |stream| will have no tracks, those
+ // will be added eventually afterwards via MediaElementEventListener.
+ return stream;
}
} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698