Chromium Code Reviews| 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 |