void MediaControlTextTrackContainerElement::updateSizes() { HTMLMediaElement* mediaElement = toParentMediaElement(this); if (!mediaElement) return; if (!document().isActive()) return; IntRect videoBox; if (!mediaElement->renderer() || !mediaElement->renderer()->isVideo()) return; videoBox = toRenderVideo(mediaElement->renderer())->videoBox(); if (m_videoDisplaySize == videoBox) return; m_videoDisplaySize = videoBox; float smallestDimension = std::min(m_videoDisplaySize.size().height(), m_videoDisplaySize.size().width()); float fontSize = smallestDimension * 0.05f; if (fontSize != m_fontSize) { m_fontSize = fontSize; setInlineStyleProperty(CSSPropertyFontSize, fontSize, CSSPrimitiveValue::CSS_PX); } }
void MediaControlTextTrackContainerElement::updateSizes(bool forceUpdate) { HTMLMediaElement* mediaElement = toParentMediaElement(this); if (!mediaElement) return; if (!document()->page()) return; IntRect videoBox; if (!mediaElement->renderer() || !mediaElement->renderer()->isVideo()) return; videoBox = toRenderVideo(mediaElement->renderer())->videoBox(); if (!forceUpdate && m_videoDisplaySize == videoBox) return; m_videoDisplaySize = videoBox; float smallestDimension = std::min(m_videoDisplaySize.size().height(), m_videoDisplaySize.size().width()); float fontSize = smallestDimension * 0.05f; if (fontSize != m_fontSize) { m_fontSize = fontSize; setInlineStyleProperty(CSSPropertyFontSize, String::number(fontSize) + "px"); } CueList activeCues = mediaElement->currentlyActiveCues(); for (size_t i = 0; i < activeCues.size(); ++i) { TextTrackCue* cue = activeCues[i].data(); cue->videoSizeDidChange(m_videoDisplaySize.size()); } }
void WebMediaPlayerProxy::initEngine() { HTMLMediaElement* element = static_cast<HTMLMediaElement*>(m_mediaPlayer->mediaPlayerClient()); String url = element->initialURL(); if (url.isEmpty()) return; Frame* frame = element->document()->frame(); Vector<String> paramNames; Vector<String> paramValues; String serviceType; // add all attributes set on the embed object if (NamedNodeMap* attributes = element->attributes()) { for (unsigned i = 0; i < attributes->length(); ++i) { Attribute* it = attributes->attributeItem(i); paramNames.append(it->name().localName().string()); paramValues.append(it->value().string()); } } serviceType = "application/x-mplayer2"; frame->loader()->requestObject(static_cast<RenderPartObject*>(element->renderer()), url, nullAtom, serviceType, paramNames, paramValues); m_init = true; }
void MediaControlTextTrackContainerElement::updateSizes() { HTMLMediaElement* mediaElement = toParentMediaElement(this); if (!mediaElement || !mediaElement->renderer() || !mediaElement->renderer()->isVideo()) return; IntRect videoBox = toRenderVideo(mediaElement->renderer())->videoBox(); if (m_videoDisplaySize == videoBox) return; m_videoDisplaySize = videoBox; float fontSize = m_videoDisplaySize.size().height() * videoHeightFontSizePercentage; if (fontSize != m_fontSize) { m_fontSize = fontSize; setInlineStyleProperty(CSSPropertyFontSize, String::number(fontSize) + "px"); } }
void MediaControls::updateControlVisibility() { if (!m_panel || !m_panel->renderer()) return; // Don't fade for audio controls. HTMLMediaElement* media = m_mediaElement; if (!media->hasVideo()) return; ASSERT(media->renderer()); // Don't fade if the media element is not visible if (media->renderer()->style()->visibility() != VISIBLE) return; bool shouldHideController = !m_mouseOver && !media->canPlay(); // Do fading manually, css animations don't work with shadow trees float animateFrom = m_panel->renderer()->style()->opacity(); float animateTo = shouldHideController ? 0.0f : 1.0f; if (animateFrom == animateTo) return; if (m_opacityAnimationTimer.isActive()) { if (m_opacityAnimationTo == animateTo) return; m_opacityAnimationTimer.stop(); } if (animateFrom < animateTo) m_opacityAnimationDuration = m_panel->renderer()->theme()->mediaControlsFadeInDuration(); else m_opacityAnimationDuration = m_panel->renderer()->theme()->mediaControlsFadeOutDuration(); m_opacityAnimationFrom = animateFrom; m_opacityAnimationTo = animateTo; m_opacityAnimationStartTime = currentTime(); m_opacityAnimationTimer.startRepeating(cOpacityAnimationRepeatDelay); }
void MediaControlTextTrackContainerElement::updateSizes(bool forceUpdate) { HTMLMediaElement* mediaElement = parentMediaElement(this); if (!mediaElement) return; if (!document().page()) return; IntRect videoBox; if (m_textTrackRepresentation) videoBox = m_textTrackRepresentation->bounds(); else { #if ENABLE(PLUGIN_PROXY_FOR_VIDEO) if (!mediaElement->renderer() || !mediaElement->renderer()->isWidget()) return; videoBox = pixelSnappedIntRect(toRenderWidget(mediaElement->renderer())->contentBoxRect()); #else if (!mediaElement->renderer() || !mediaElement->renderer()->isVideo()) return; videoBox = toRenderVideo(*mediaElement->renderer()).videoBox(); #endif } if (!forceUpdate && m_videoDisplaySize == videoBox) return; m_videoDisplaySize = videoBox; // FIXME (121170): This function is called during layout, and should lay out the text tracks immediately. m_updateTimer.startOneShot(0); }
void MediaControlTextTrackContainerElement::updateSizes(bool forceUpdate) { HTMLMediaElement* mediaElement = toParentMediaElement(this); if (!mediaElement) return; if (!document()->page()) return; IntRect videoBox; if (m_textTrackRepresentation) videoBox = m_textTrackRepresentation->bounds(); else { #if ENABLE(PLUGIN_PROXY_FOR_VIDEO) if (!mediaElement->renderer() || !mediaElement->renderer()->isRenderPart()) return; videoBox = pixelSnappedIntRect(toRenderPart(mediaElement->renderer())->contentBoxRect()); #else if (!mediaElement->renderer() || !mediaElement->renderer()->isVideo()) return; videoBox = toRenderVideo(mediaElement->renderer())->videoBox(); #endif } if (!forceUpdate && m_videoDisplaySize == videoBox) return; m_videoDisplaySize = videoBox; m_updateTimer.startOneShot(0); }
bool MediaElementSession::canControlControlsManager(const HTMLMediaElement& element) const { if (!element.hasAudio()) { LOG(Media, "MediaElementSession::canControlControlsManager - returning FALSE: No audio"); return false; } if (element.muted()) { LOG(Media, "MediaElementSession::canControlControlsManager - returning FALSE: Muted"); return false; } if (element.ended()) { LOG(Media, "MediaElementSession::canControlControlsManager - returning FALSE: Ended"); return false; } if (element.document().activeDOMObjectsAreSuspended()) { LOG(Media, "MediaElementSession::canControlControlsManager - returning FALSE: activeDOMObjectsAreSuspended()"); return false; } if (!playbackPermitted(element)) { LOG(Media, "MediaElementSession::canControlControlsManager - returning FALSE: Playback not permitted"); return false; } if (element.isVideo()) { if (!element.renderer()) { LOG(Media, "MediaElementSession::canControlControlsManager - returning FALSE: No renderer"); return false; } if (!element.hasVideo()) { LOG(Media, "MediaElementSession::canControlControlsManager - returning FALSE: No video"); return false; } if (isElementLargeEnoughForMainContent(element)) { LOG(Media, "MediaElementSession::canControlControlsManager - returning TRUE: Is main content"); return true; } } if (m_restrictions & RequireUserGestureToControlControlsManager && !ScriptController::processingUserGestureForMedia()) { LOG(Media, "MediaElementSession::canControlControlsManager - returning FALSE: No user gesture"); return false; } LOG(Media, "MediaElementSession::canControlControlsManager - returning TRUE: All criteria met"); return true; }
void MediaControlTextTrackContainerElement::updateSizes() { HTMLMediaElement* mediaElement = toParentMediaElement(this); if (!mediaElement || !mediaElement->renderer() || !mediaElement->renderer()->isVideo()) return; IntRect videoBox = toRenderVideo(mediaElement->renderer())->videoBox(); if (m_videoDisplaySize == videoBox) return; m_videoDisplaySize = videoBox; float fontSize = m_videoDisplaySize.size().height() * videoHeightFontSizePercentage; if (fontSize != m_fontSize) { m_fontSize = fontSize; setInlineStyleProperty(CSSPropertyFontSize, String::number(fontSize) + "px"); } LayoutUnit bottom = static_cast<LayoutUnit>(m_videoDisplaySize.y() + m_videoDisplaySize.height() - (m_videoDisplaySize.height() * trackBottomMultiplier)); if (bottom != m_bottom) { m_bottom = bottom; setInlineStyleProperty(CSSPropertyBottom, String::number(bottom) + "px"); } }
static bool isMainContent(const HTMLMediaElement& element) { if (!element.hasAudio() || !element.hasVideo()) return false; // Elements which have not yet been laid out, or which are not yet in the DOM, cannot be main content. RenderBox* renderer = downcast<RenderBox>(element.renderer()); if (!renderer) return false; if (!isElementLargeEnoughForMainContent(element)) return false; // Elements which are hidden by style, or have been scrolled out of view, cannot be main content. // But elements which have audio & video and are already playing should not stop playing because // they are scrolled off the page. if (renderer->style().visibility() != VISIBLE || (renderer->visibleInViewportState() != RenderElement::VisibleInViewport && !element.isPlaying()) ) { return false; } // Main content elements must be in the main frame. Document& document = element.document(); if (!document.frame() || !document.frame()->isMainFrame()) return false; MainFrame& mainFrame = document.frame()->mainFrame(); if (!mainFrame.view() || !mainFrame.view()->renderView()) return false; RenderView& mainRenderView = *mainFrame.view()->renderView(); // Hit test the area of the main frame where the element appears, to determine if the element is being obscured. IntRect rectRelativeToView = element.clientRect(); ScrollPosition scrollPosition = mainFrame.view()->documentScrollPositionRelativeToViewOrigin(); IntRect rectRelativeToTopDocument(rectRelativeToView.location() + scrollPosition, rectRelativeToView.size()); HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::AllowChildFrameContent | HitTestRequest::IgnoreClipping | HitTestRequest::DisallowUserAgentShadowContent); HitTestResult result(rectRelativeToTopDocument.center()); // Elements which are obscured by other elements cannot be main content. mainRenderView.hitTest(request, result); result.setToNonUserAgentShadowAncestor(); Element* hitElement = result.innerElement(); if (hitElement != &element) return false; return true; }
void MediaControlTextTrackContainerElement::updateSizes() { HTMLMediaElement* mediaElement = toParentMediaElement(this); if (!mediaElement) return; if (!document()->page()) return; IntRect videoBox; if (m_textTrackRepresentation) videoBox = m_textTrackRepresentation->bounds(); else { if (!mediaElement->renderer() || !mediaElement->renderer()->isVideo()) return; videoBox = toRenderVideo(mediaElement->renderer())->videoBox(); } if (m_videoDisplaySize == videoBox) return; m_videoDisplaySize = videoBox; if (m_textTrackRepresentation) { setInlineStyleProperty(CSSPropertyWidth, String::number(m_videoDisplaySize.size().width()) + "px"); setInlineStyleProperty(CSSPropertyHeight, String::number(m_videoDisplaySize.size().height()) + "px"); } float smallestDimension = std::min(m_videoDisplaySize.size().height(), m_videoDisplaySize.size().width()); float fontSize = smallestDimension * (document()->page()->group().captionFontSizeScale()); if (fontSize != m_fontSize) { m_fontSize = fontSize; setInlineStyleProperty(CSSPropertyFontSize, String::number(fontSize) + "px"); } }
static bool isElementLargeEnoughForMainContent(const HTMLMediaElement& element) { static const double elementMainContentAreaMinimum = 400 * 300; static const double maximumAspectRatio = 1.8; // Slightly larger than 16:9. static const double minimumAspectRatio = .5; // Slightly smaller than 16:9. // Elements which have not yet been laid out, or which are not yet in the DOM, cannot be main content. RenderBox* renderer = downcast<RenderBox>(element.renderer()); if (!renderer) return false; double width = renderer->clientWidth(); double height = renderer->clientHeight(); double area = width * height; double aspectRatio = width / height; return area >= elementMainContentAreaMinimum && aspectRatio >= minimumAspectRatio && aspectRatio <= maximumAspectRatio; }
bool MediaElementSession::canControlControlsManager(const HTMLMediaElement& element) const { if (!element.hasAudio()) return false; if (!playbackPermitted(element)) return false; RenderBox* renderer = downcast<RenderBox>(element.renderer()); if (!renderer) return false; if (isElementLargeEnoughForMainContent(element)) return true; if (ScriptController::processingUserGestureForMedia()) return true; return false; }
static bool isElementLargeRelativeToMainFrame(const HTMLMediaElement& element) { static const double minimumPercentageOfMainFrameAreaForMainContent = 0.9; auto* renderer = element.renderer(); if (!renderer) return false; auto* documentFrame = element.document().frame(); if (!documentFrame) return false; if (!documentFrame->mainFrame().view()) return false; auto& mainFrameView = *documentFrame->mainFrame().view(); auto maxVisibleClientWidth = std::min(renderer->clientWidth().toInt(), mainFrameView.visibleWidth()); auto maxVisibleClientHeight = std::min(renderer->clientHeight().toInt(), mainFrameView.visibleHeight()); return maxVisibleClientWidth * maxVisibleClientHeight > minimumPercentageOfMainFrameAreaForMainContent * mainFrameView.visibleWidth() * mainFrameView.visibleHeight(); }
void MediaPlayerPrivate::resizeSourceDimensions() { if (!m_webCorePlayer) return; HTMLMediaElement* client = static_cast<HTMLMediaElement*>(m_webCorePlayer->mediaPlayerClient()); if (!client || !client->isVideo()) return; RenderObject* o = client->renderer(); if (!o) return; // If we have an HTMLVideoElement but the source has no video, then we need to resize the media element. if (!hasVideo()) { IntRect rect = o->enclosingBox()->contentBoxRect(); static const int playbookMinAudioElementWidth = 300; static const int playbookMinAudioElementHeight = 32; // If the rect dimensions are less than the allowed minimum, use the minimum instead. int newWidth = max(rect.width(), playbookMinAudioElementWidth); int newHeight = max(rect.height(), playbookMinAudioElementHeight); char attrString[12]; sprintf(attrString, "%d", newWidth); client->setAttribute(HTMLNames::widthAttr, attrString); sprintf(attrString, "%d", newHeight); client->setAttribute(HTMLNames::heightAttr, attrString); } // If we don't know what the width and height of the video source is, then we need to set it to something sane. if (m_platformPlayer->sourceWidth() && m_platformPlayer->sourceHeight()) return; IntRect rect = o->enclosingBox()->contentBoxRect(); m_platformPlayer->setSourceDimension(rect.width(), rect.height()); }
PassRefPtr<Widget> SubframeLoader::loadMediaPlayerProxyPlugin(HTMLMediaElement& mediaElement, const URL& url, const Vector<String>& paramNames, const Vector<String>& paramValues) { ASSERT(mediaElement.hasTagName(videoTag) || isHTMLAudioElement(mediaElement)); URL completedURL; if (!url.isEmpty()) completedURL = completeURL(url); if (!m_frame.document()->securityOrigin()->canDisplay(completedURL)) { FrameLoader::reportLocalLoadFailed(&m_frame, completedURL.string()); return nullptr; } if (!m_frame.document()->contentSecurityPolicy()->allowMediaFromSource(completedURL)) return nullptr; RenderWidget* renderer = toRenderWidget(mediaElement.renderer()); IntSize size; if (renderer) size = roundedIntSize(LayoutSize(renderer->contentWidth(), renderer->contentHeight())); else if (mediaElement.isVideo()) size = RenderVideo::defaultSize(); if (!m_frame.loader().mixedContentChecker().canRunInsecureContent(m_frame.document()->securityOrigin(), completedURL)) return nullptr; RefPtr<Widget> widget = m_frame.loader().client().createMediaPlayerProxyPlugin(size, &mediaElement, completedURL, paramNames, paramValues, "application/x-media-element-proxy-plugin"); if (widget && renderer) { renderer->setWidget(widget); renderer->frameOwnerElement().setNeedsStyleRecalc(SyntheticStyleChange); } m_containsPlugins = true; return widget ? widget.release() : nullptr; }
static bool isElementLargeEnoughForMainContent(const HTMLMediaElement& element) { static const double elementMainContentAreaMinimum = 400 * 300; static const double maximumAspectRatio = 1.8; // Slightly larger than 16:9. static const double minimumAspectRatio = .5; // Slightly smaller than 9:16. // Elements which have not yet been laid out, or which are not yet in the DOM, cannot be main content. auto* renderer = element.renderer(); if (!renderer) return false; double width = renderer->clientWidth(); double height = renderer->clientHeight(); double area = width * height; double aspectRatio = width / height; if (area < elementMainContentAreaMinimum) return false; if (aspectRatio >= minimumAspectRatio && aspectRatio <= maximumAspectRatio) return true; return isElementLargeRelativeToMainFrame(element); }