📄 htmlmediaelement.cpp
字号:
ec = 0; load(ec); if (ec) return; } if (!m_paused) { m_paused = true; dispatchEventAsync(eventNames().timeupdateEvent); dispatchEventAsync(eventNames().pauseEvent); } m_autoplaying = false; updatePlayState();}bool HTMLMediaElement::loop() const{ return hasAttribute(loopAttr);}void HTMLMediaElement::setLoop(bool b){ setBooleanAttribute(loopAttr, b);}bool HTMLMediaElement::controls() const{ Frame* frame = document()->frame(); // always show controls when scripting is disabled if (frame && !frame->script()->isEnabled()) return true; return hasAttribute(controlsAttr);}void HTMLMediaElement::setControls(bool b){ setBooleanAttribute(controlsAttr, b);}float HTMLMediaElement::volume() const{ return m_volume;}void HTMLMediaElement::setVolume(float vol, ExceptionCode& ec){ if (vol < 0.0f || vol > 1.0f) { ec = INDEX_SIZE_ERR; return; } if (m_volume != vol) { m_volume = vol; updateVolume(); dispatchEventAsync(eventNames().volumechangeEvent); }}bool HTMLMediaElement::muted() const{ return m_muted;}void HTMLMediaElement::setMuted(bool muted){ if (m_muted != muted) { m_muted = muted; updateVolume(); dispatchEventAsync(eventNames().volumechangeEvent); }}void HTMLMediaElement::togglePlayState(ExceptionCode& ec){ // We can safely call the internal play/pause methods, which don't check restrictions, because // this method is only called from the built-in media controller if (canPlay()) playInternal(ec); else pauseInternal(ec);}void HTMLMediaElement::beginScrubbing(){ if (!paused()) { if (ended()) { // Because a media element stays in non-paused state when it reaches end, playback resumes // when the slider is dragged from the end to another position unless we pause first. Do // a "hard pause" so an event is generated, since we want to stay paused after scrubbing finishes. ExceptionCode ec; pause(ec); } else { // Not at the end but we still want to pause playback so the media engine doesn't try to // continue playing during scrubbing. Pause without generating an event as we will // unpause after scrubbing finishes. setPausedInternal(true); } }}void HTMLMediaElement::endScrubbing(){ if (m_pausedInternal) setPausedInternal(false);}bool HTMLMediaElement::canPlay() const{ return paused() || ended() || networkState() < LOADED_METADATA;}String HTMLMediaElement::selectMediaURL(ContentType& contentType){ // 3.14.9.2. Location of the media resource String mediaSrc = getAttribute(srcAttr); if (mediaSrc.isEmpty()) { for (Node* n = firstChild(); n; n = n->nextSibling()) { if (n->hasTagName(sourceTag)) { HTMLSourceElement* source = static_cast<HTMLSourceElement*>(n); if (!source->hasAttribute(srcAttr)) continue; if (source->hasAttribute(mediaAttr)) { MediaQueryEvaluator screenEval("screen", document()->frame(), renderer() ? renderer()->style() : 0); RefPtr<MediaList> media = MediaList::createAllowingDescriptionSyntax(source->media()); if (!screenEval.eval(media.get())) continue; } if (source->hasAttribute(typeAttr)) { ContentType type(source->type()); if (!MediaPlayer::supportsType(type)) continue; // return type with all parameters in place so the media engine can use them contentType = type; } mediaSrc = source->src().string(); break; } } } if (!mediaSrc.isEmpty()) mediaSrc = document()->completeURL(mediaSrc).string(); return mediaSrc;}void HTMLMediaElement::mediaPlayerTimeChanged(MediaPlayer*){ beginProcessingMediaPlayerCallback(); if (readyState() >= CAN_PLAY) m_seeking = false; float now = currentTime(); if (now >= duration()) { if (loop()) { ExceptionCode ec; seek(0, ec); dispatchEventForType(eventNames().timeupdateEvent, false, true); } else { dispatchEventForType(eventNames().timeupdateEvent, false, true); dispatchEventForType(eventNames().endedEvent, false, true); } } updatePlayState(); endProcessingMediaPlayerCallback();}void HTMLMediaElement::mediaPlayerRepaint(MediaPlayer*){ beginProcessingMediaPlayerCallback(); if (renderer()) renderer()->repaint(); endProcessingMediaPlayerCallback();}void HTMLMediaElement::mediaPlayerVolumeChanged(MediaPlayer*){ beginProcessingMediaPlayerCallback(); updateVolume(); endProcessingMediaPlayerCallback();}PassRefPtr<TimeRanges> HTMLMediaElement::buffered() const{ // FIXME real ranges support if (!m_player || !m_player->maxTimeBuffered()) return TimeRanges::create(); return TimeRanges::create(0, m_player->maxTimeBuffered());}PassRefPtr<TimeRanges> HTMLMediaElement::played() const{ // FIXME track played return TimeRanges::create();}PassRefPtr<TimeRanges> HTMLMediaElement::seekable() const{ // FIXME real ranges support if (!m_player || !m_player->maxTimeSeekable()) return TimeRanges::create(); return TimeRanges::create(0, m_player->maxTimeSeekable());}bool HTMLMediaElement::activelyPlaying() const{ return !paused() && readyState() >= CAN_PLAY && !endedPlayback(); // && !stoppedDueToErrors() && !pausedForUserInteraction();}bool HTMLMediaElement::endedPlayback() const{ return networkState() >= LOADED_METADATA && currentTime() >= duration() && !loop();} void HTMLMediaElement::updateVolume(){ if (!m_player) return; // Avoid recursion when the player reports volume changes. if (!processingMediaPlayerCallback()) { Page* page = document()->page(); float volumeMultiplier = page ? page->mediaVolume() : 1; m_player->setVolume(m_muted ? 0 : m_volume * volumeMultiplier); } if (renderer()) renderer()->updateFromElement();}void HTMLMediaElement::updatePlayState(){ if (!m_player) return; if (m_pausedInternal) { if (!m_player->paused()) m_player->pause(); return; } bool shouldBePlaying = activelyPlaying(); if (shouldBePlaying && m_player->paused()) m_player->play(); else if (!shouldBePlaying && !m_player->paused()) m_player->pause(); if (renderer()) renderer()->updateFromElement();} void HTMLMediaElement::setPausedInternal(bool b){ m_pausedInternal = b; updatePlayState();}void HTMLMediaElement::documentWillBecomeInactive(){ // 3.14.9.4. Loading the media resource // 14 if (m_begun) { // For simplicity cancel the incomplete load by deleting the player m_player.clear(); m_progressEventTimer.stop(); m_error = MediaError::create(MediaError::MEDIA_ERR_ABORTED); m_begun = false; initAndDispatchProgressEvent(eventNames().abortEvent); if (m_networkState >= LOADING) { m_networkState = EMPTY; m_readyState = DATA_UNAVAILABLE; dispatchEventForType(eventNames().emptiedEvent, false, true); } } m_inActiveDocument = false; // Stop the playback without generating events setPausedInternal(true); if (renderer()) renderer()->updateFromElement();}void HTMLMediaElement::documentDidBecomeActive(){ m_inActiveDocument = true; setPausedInternal(false); if (m_error && m_error->code() == MediaError::MEDIA_ERR_ABORTED) { // Restart the load if it was aborted in the middle by moving the document to the page cache. // This behavior is not specified but it seems like a sensible thing to do. ExceptionCode ec; load(ec); } if (renderer()) renderer()->updateFromElement();}void HTMLMediaElement::mediaVolumeDidChange(){ updateVolume();}void HTMLMediaElement::defaultEventHandler(Event* event){#if ENABLE(PLUGIN_PROXY_FOR_VIDEO) RenderObject* r = renderer(); if (!r || !r->isWidget()) return; Widget* widget = static_cast<RenderWidget*>(r)->widget(); if (widget) widget->handleEvent(event);#else if (renderer() && renderer()->isMedia()) static_cast<RenderMedia*>(renderer())->forwardEvent(event); if (event->defaultHandled()) return; HTMLElement::defaultEventHandler(event);#endif}bool HTMLMediaElement::processingUserGesture() const{ Frame* frame = document()->frame(); FrameLoader* loader = frame ? frame->loader() : 0; // return 'true' for safety if we don't know the answer return loader ? loader->userGestureHint() : true;}#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)void HTMLMediaElement::deliverNotification(MediaPlayerProxyNotificationType notification){ if (notification == MediaPlayerNotificationPlayPauseButtonPressed) { ExceptionCode ec; togglePlayState(ec); return; } if (m_player) m_player->deliverNotification(notification);}void HTMLMediaElement::setMediaPlayerProxy(WebMediaPlayerProxy* proxy){ if (m_player) m_player->setMediaPlayerProxy(proxy);}String HTMLMediaElement::initialURL(){ ContentType ignoredType; String initialSrc = selectMediaURL(ignoredType); m_currentSrc = initialSrc; return initialSrc;}void HTMLMediaElement::finishParsingChildren(){ HTMLElement::finishParsingChildren(); if (!m_player) m_player.set(new MediaPlayer(this)); document()->updateRendering(); if (m_needWidgetUpdate && renderer()) static_cast<RenderPartObject*>(renderer())->updateWidget(true);}#endif}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -