⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 htmlmediaelement.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  */#include "config.h"#if ENABLE(VIDEO)#include "HTMLMediaElement.h"#include "ContentType.h"#include "CSSHelper.h"#include "CSSPropertyNames.h"#include "CSSValueKeywords.h"#include "Event.h"#include "EventNames.h"#include "ExceptionCode.h"#include "Frame.h"#include "FrameLoader.h"#include "HTMLDocument.h"#include "HTMLNames.h"#include "HTMLSourceElement.h"#include "HTMLVideoElement.h"#include <limits>#include "MediaError.h"#include "MediaList.h"#include "MediaQueryEvaluator.h"#include "MIMETypeRegistry.h"#include "MediaPlayer.h"#include "Page.h"#include "RenderVideo.h"#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)#include "RenderPartObject.h"#endif#include "TimeRanges.h"#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)#include "Widget.h"#endif#include <wtf/CurrentTime.h>#include <wtf/MathExtras.h>using namespace std;namespace WebCore {using namespace HTMLNames;HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document* doc)    : HTMLElement(tagName, doc)    , m_loadTimer(this, &HTMLMediaElement::loadTimerFired)    , m_asyncEventTimer(this, &HTMLMediaElement::asyncEventTimerFired)    , m_progressEventTimer(this, &HTMLMediaElement::progressEventTimerFired)    , m_defaultPlaybackRate(1.0f)    , m_networkState(EMPTY)    , m_readyState(DATA_UNAVAILABLE)    , m_begun(false)    , m_loadedFirstFrame(false)    , m_autoplaying(true)    , m_volume(1.0f)    , m_muted(false)    , m_paused(true)    , m_seeking(false)    , m_currentTimeDuringSeek(0)    , m_previousProgress(0)    , m_previousProgressTime(numeric_limits<double>::max())    , m_sentStalledEvent(false)    , m_loadNestingLevel(0)    , m_terminateLoadBelowNestingLevel(0)    , m_pausedInternal(false)    , m_inActiveDocument(true)    , m_player(0)    , m_restrictions(NoRestrictions)    , m_processingMediaPlayerCallback(0)    , m_sendProgressEvents(true)#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)    , m_needWidgetUpdate(false)#endif{    document()->registerForDocumentActivationCallbacks(this);    document()->registerForMediaVolumeCallbacks(this);}HTMLMediaElement::~HTMLMediaElement(){    document()->unregisterForDocumentActivationCallbacks(this);    document()->unregisterForMediaVolumeCallbacks(this);}bool HTMLMediaElement::checkDTD(const Node* newChild){    return newChild->hasTagName(sourceTag) || HTMLElement::checkDTD(newChild);}void HTMLMediaElement::attributeChanged(Attribute* attr, bool preserveDecls){    HTMLElement::attributeChanged(attr, preserveDecls);    const QualifiedName& attrName = attr->name();    if (attrName == srcAttr) {        // 3.14.9.2.        // change to src attribute triggers load()        if (inDocument() && m_networkState == EMPTY)            scheduleLoad();    } #if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)    else if (attrName == controlsAttr) {        if (!isVideo() && attached() && (controls() != (renderer() != 0))) {            detach();            attach();        }        if (renderer())            renderer()->updateFromElement();    }#endif}    bool HTMLMediaElement::rendererIsNeeded(RenderStyle* style){#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)    UNUSED_PARAM(style);    Frame* frame = document()->frame();    if (!frame)        return false;    return true;#else    return controls() ? HTMLElement::rendererIsNeeded(style) : false;#endif}RenderObject* HTMLMediaElement::createRenderer(RenderArena* arena, RenderStyle*){#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)    return new (arena) RenderPartObject(this);#else    return new (arena) RenderMedia(this);#endif} void HTMLMediaElement::insertedIntoDocument(){    HTMLElement::insertedIntoDocument();    if (!src().isEmpty())        scheduleLoad();}void HTMLMediaElement::removedFromDocument(){    if (networkState() != EMPTY) {        ExceptionCode ec;        pause(ec);    }    HTMLElement::removedFromDocument();}void HTMLMediaElement::attach(){    ASSERT(!attached());#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)    m_needWidgetUpdate = true;#endif    HTMLElement::attach();    if (renderer())        renderer()->updateFromElement();}void HTMLMediaElement::recalcStyle(StyleChange change){    HTMLElement::recalcStyle(change);    if (renderer())        renderer()->updateFromElement();}void HTMLMediaElement::scheduleLoad(){    m_loadTimer.startOneShot(0);}void HTMLMediaElement::initAndDispatchProgressEvent(const AtomicString& eventName){    if (!m_sendProgressEvents)        return;    bool totalKnown = m_player && m_player->totalBytesKnown();    unsigned loaded = m_player ? m_player->bytesLoaded() : 0;    unsigned total = m_player ? m_player->totalBytes() : 0;    dispatchProgressEvent(eventName, totalKnown, loaded, total);    if (renderer())        renderer()->updateFromElement();}void HTMLMediaElement::dispatchEventAsync(const AtomicString& eventName){    m_asyncEventsToDispatch.append(eventName);    if (!m_asyncEventTimer.isActive())                                    m_asyncEventTimer.startOneShot(0);}void HTMLMediaElement::loadTimerFired(Timer<HTMLMediaElement>*){    ExceptionCode ec;    loadInternal(ec);}void HTMLMediaElement::asyncEventTimerFired(Timer<HTMLMediaElement>*){    Vector<AtomicString> asyncEventsToDispatch;    m_asyncEventsToDispatch.swap(asyncEventsToDispatch);    unsigned count = asyncEventsToDispatch.size();    for (unsigned n = 0; n < count; ++n)        dispatchEventForType(asyncEventsToDispatch[n], false, true);}static String serializeTimeOffset(float time){    String timeString = String::number(time);    // FIXME serialize time offset values properly (format not specified yet)    timeString.append("s");    return timeString;}static float parseTimeOffset(const String& timeString, bool* ok = 0){    const UChar* characters = timeString.characters();    unsigned length = timeString.length();        if (length && characters[length - 1] == 's')        length--;        // FIXME parse time offset values (format not specified yet)    float val = charactersToFloat(characters, length, ok);    return val;}float HTMLMediaElement::getTimeOffsetAttribute(const QualifiedName& name, float valueOnError) const{    bool ok;    String timeString = getAttribute(name);    float result = parseTimeOffset(timeString, &ok);    if (ok)        return result;    return valueOnError;}void HTMLMediaElement::setTimeOffsetAttribute(const QualifiedName& name, float value){    setAttribute(name, serializeTimeOffset(value));}PassRefPtr<MediaError> HTMLMediaElement::error() const {    return m_error;}KURL HTMLMediaElement::src() const{    return document()->completeURL(getAttribute(srcAttr));}void HTMLMediaElement::setSrc(const String& url){    setAttribute(srcAttr, url);}String HTMLMediaElement::currentSrc() const{    return m_currentSrc;}HTMLMediaElement::NetworkState HTMLMediaElement::networkState() const{    return m_networkState;}String HTMLMediaElement::canPlayType(const String& mimeType) const{    MediaPlayer::SupportsType support = MediaPlayer::supportsType(ContentType(mimeType));    String canPlay;    // 4.8.10.3    switch (support)    {        case MediaPlayer::IsNotSupported:            canPlay = "no";            break;        case MediaPlayer::MayBeSupported:            canPlay = "maybe";            break;        case MediaPlayer::IsSupported:            canPlay = "probably";            break;    }        return canPlay;}void HTMLMediaElement::load(ExceptionCode& ec){    if (m_restrictions & RequireUserGestureForLoadRestriction && !processingUserGesture()) {        ec = INVALID_STATE_ERR;        return;    }    loadInternal(ec);}void HTMLMediaElement::loadInternal(ExceptionCode& ec){    String mediaSrc;    ContentType contentType("");    // 3.14.9.4. Loading the media resource    // 1    // if an event generated during load() ends up re-entering load(), terminate previous instances    m_loadNestingLevel++;    m_terminateLoadBelowNestingLevel = m_loadNestingLevel;        m_progressEventTimer.stop();    m_sentStalledEvent = false;        m_loadTimer.stop();        // 2    if (m_begun) {        m_begun = false;        m_error = MediaError::create(MediaError::MEDIA_ERR_ABORTED);        if (m_sendProgressEvents)            initAndDispatchProgressEvent(eventNames().abortEvent);        if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel)            goto end;    }        // 3    m_error = 0;    m_loadedFirstFrame = false;    m_autoplaying = true;    // 4    setPlaybackRate(defaultPlaybackRate(), ec);        // 5    if (networkState() != EMPTY) {        m_networkState = EMPTY;        m_readyState = DATA_UNAVAILABLE;        m_paused = true;        m_seeking = false;        if (m_player) {            m_player->pause();            m_player->seek(0);        }        dispatchEventForType(eventNames().emptiedEvent, false, true);        if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel)            goto end;    }        // 6    mediaSrc = selectMediaURL(contentType);    if (mediaSrc.isEmpty()) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -