📄 htmlmediaelement.cpp
字号:
ec = INVALID_STATE_ERR; goto end; } // 7 m_networkState = LOADING; // 8 m_currentSrc = mediaSrc; // 9 m_begun = true; if (m_sendProgressEvents) dispatchProgressEvent(eventNames().loadstartEvent, false, 0, 0); if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel) goto end; // 10, 11, 12, 13#if !ENABLE(PLUGIN_PROXY_FOR_VIDEO) m_player.clear(); m_player.set(new MediaPlayer(this));#else if (!m_player) m_player.set(new MediaPlayer(this));#endif updateVolume(); m_player->load(m_currentSrc, contentType); if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel) goto end; if (renderer()) renderer()->updateFromElement(); // 14 if (m_sendProgressEvents) { m_previousProgressTime = WTF::currentTime(); m_previousProgress = 0; if (m_begun) // 350ms is not magic, it is in the spec! m_progressEventTimer.startRepeating(0.350); }end: ASSERT(m_loadNestingLevel); m_loadNestingLevel--;}void HTMLMediaElement::mediaPlayerNetworkStateChanged(MediaPlayer*){ if (!m_begun) return; beginProcessingMediaPlayerCallback(); setNetworkState(m_player->networkState()); endProcessingMediaPlayerCallback();}void HTMLMediaElement::setNetworkState(MediaPlayer::NetworkState state){ if (state == MediaPlayer::Empty) { // just update the cached state and leave, we can't do anything m_networkState = EMPTY; return; } m_terminateLoadBelowNestingLevel = m_loadNestingLevel; // 3.14.9.4. Loading the media resource // 14 if (state == MediaPlayer::LoadFailed) { //delete m_player; //m_player = 0; // FIXME better error handling m_error = MediaError::create(MediaError::MEDIA_ERR_NETWORK); m_begun = false; m_progressEventTimer.stop(); initAndDispatchProgressEvent(eventNames().errorEvent); if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel) return; m_networkState = EMPTY; if (isVideo()) static_cast<HTMLVideoElement*>(this)->updatePosterImage(); dispatchEventForType(eventNames().emptiedEvent, false, true); return; } if (state >= MediaPlayer::Loading && m_networkState < LOADING) m_networkState = LOADING; if (state >= MediaPlayer::LoadedMetaData && m_networkState < LOADED_METADATA) { m_networkState = LOADED_METADATA; dispatchEventForType(eventNames().durationchangeEvent, false, true); if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel) return; dispatchEventForType(eventNames().loadedmetadataEvent, false, true); if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel) return; } if (state >= MediaPlayer::LoadedFirstFrame && m_networkState < LOADED_FIRST_FRAME) { m_networkState = LOADED_FIRST_FRAME; setReadyState(CAN_SHOW_CURRENT_FRAME); if (isVideo()) static_cast<HTMLVideoElement*>(this)->updatePosterImage(); if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel) return; m_loadedFirstFrame = true;#if !ENABLE(PLUGIN_PROXY_FOR_VIDEO) if (renderer()) { ASSERT(!renderer()->isImage()); static_cast<RenderVideo*>(renderer())->videoSizeChanged(); }#endif dispatchEventForType(eventNames().loadedfirstframeEvent, false, true); if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel) return; dispatchEventForType(eventNames().canshowcurrentframeEvent, false, true); if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel) return; } // 15 if (state == MediaPlayer::Loaded && m_networkState < LOADED) { m_begun = false; m_networkState = LOADED; m_progressEventTimer.stop(); initAndDispatchProgressEvent(eventNames().loadEvent); }}void HTMLMediaElement::mediaPlayerReadyStateChanged(MediaPlayer*){ beginProcessingMediaPlayerCallback(); MediaPlayer::ReadyState state = m_player->readyState(); setReadyState((ReadyState)state); endProcessingMediaPlayerCallback();}void HTMLMediaElement::setReadyState(ReadyState state){ // 3.14.9.6. The ready states if (m_readyState == state) return; bool wasActivelyPlaying = activelyPlaying(); m_readyState = state; if (state >= CAN_PLAY) m_seeking = false; if (networkState() == EMPTY) return; if (state == DATA_UNAVAILABLE) { dispatchEventForType(eventNames().dataunavailableEvent, false, true); if (wasActivelyPlaying) { dispatchEventForType(eventNames().timeupdateEvent, false, true); dispatchEventForType(eventNames().waitingEvent, false, true); } } else if (state == CAN_SHOW_CURRENT_FRAME) { if (m_loadedFirstFrame) dispatchEventForType(eventNames().canshowcurrentframeEvent, false, true); if (wasActivelyPlaying) { dispatchEventForType(eventNames().timeupdateEvent, false, true); dispatchEventForType(eventNames().waitingEvent, false, true); } } else if (state == CAN_PLAY) { dispatchEventForType(eventNames().canplayEvent, false, true); } else if (state == CAN_PLAY_THROUGH) { dispatchEventForType(eventNames().canplaythroughEvent, false, true); if (m_autoplaying && m_paused && autoplay()) { m_paused = false; dispatchEventForType(eventNames().playEvent, false, true); } } updatePlayState();}void HTMLMediaElement::progressEventTimerFired(Timer<HTMLMediaElement>*){ ASSERT(m_player); unsigned progress = m_player->bytesLoaded(); double time = WTF::currentTime(); double timedelta = time - m_previousProgressTime; if (progress == m_previousProgress) { if (timedelta > 3.0 && !m_sentStalledEvent) { initAndDispatchProgressEvent(eventNames().stalledEvent); m_sentStalledEvent = true; } } else { initAndDispatchProgressEvent(eventNames().progressEvent); m_previousProgress = progress; m_previousProgressTime = time; m_sentStalledEvent = false; }}void HTMLMediaElement::seek(float time, ExceptionCode& ec){ // 3.14.9.8. Seeking // 1 if (networkState() < LOADED_METADATA) { ec = INVALID_STATE_ERR; return; } time = min(time, duration()); time = max(time, 0.0f); // 6 RefPtr<TimeRanges> seekableRanges = seekable(); if (!seekableRanges->contain(time)) { ec = INDEX_SIZE_ERR; return; } // 7 m_currentTimeDuringSeek = time; // 8 m_seeking = true; // 9 dispatchEventForType(eventNames().timeupdateEvent, false, true); // 10 // As soon as the user agent has established whether or not the media data for the new playback position is available, // and, if it is, decoded enough data to play back that position, the seeking DOM attribute must be set to false. if (m_player) m_player->seek(time);}HTMLMediaElement::ReadyState HTMLMediaElement::readyState() const{ return m_readyState;}bool HTMLMediaElement::seeking() const{ return m_seeking;}// playback statefloat HTMLMediaElement::currentTime() const{ if (!m_player) return 0; if (m_seeking) return m_currentTimeDuringSeek; return m_player->currentTime();}void HTMLMediaElement::setCurrentTime(float time, ExceptionCode& ec){ seek(time, ec);}float HTMLMediaElement::duration() const{ return m_player ? m_player->duration() : 0;}bool HTMLMediaElement::paused() const{ return m_paused;}float HTMLMediaElement::defaultPlaybackRate() const{ return m_defaultPlaybackRate;}void HTMLMediaElement::setDefaultPlaybackRate(float rate, ExceptionCode& ec){ if (rate == 0.0f) { ec = NOT_SUPPORTED_ERR; return; } if (m_defaultPlaybackRate != rate) { m_defaultPlaybackRate = rate; dispatchEventAsync(eventNames().ratechangeEvent); }}float HTMLMediaElement::playbackRate() const{ return m_player ? m_player->rate() : 0;}void HTMLMediaElement::setPlaybackRate(float rate, ExceptionCode& ec){ if (rate == 0.0f) { ec = NOT_SUPPORTED_ERR; return; } if (m_player && m_player->rate() != rate) { m_player->setRate(rate); dispatchEventAsync(eventNames().ratechangeEvent); }}bool HTMLMediaElement::ended() const{ return endedPlayback();}bool HTMLMediaElement::autoplay() const{ return hasAttribute(autoplayAttr);}void HTMLMediaElement::setAutoplay(bool b){ setBooleanAttribute(autoplayAttr, b);}void HTMLMediaElement::play(ExceptionCode& ec){ if (m_restrictions & RequireUserGestureForRateChangeRestriction && !processingUserGesture()) { ec = INVALID_STATE_ERR; return; } playInternal(ec);}void HTMLMediaElement::playInternal(ExceptionCode& ec){ // 3.14.9.7. Playing the media resource if (!m_player || networkState() == EMPTY) { ec = 0; load(ec); if (ec) return; } ExceptionCode unused; if (endedPlayback()) { seek(0, unused); } setPlaybackRate(defaultPlaybackRate(), unused); if (m_paused) { m_paused = false; dispatchEventAsync(eventNames().playEvent); } m_autoplaying = false; updatePlayState();}void HTMLMediaElement::pause(ExceptionCode& ec){ if (m_restrictions & RequireUserGestureForRateChangeRestriction && !processingUserGesture()) { ec = INVALID_STATE_ERR; return; } pauseInternal(ec);}void HTMLMediaElement::pauseInternal(ExceptionCode& ec){ // 3.14.9.7. Playing the media resource if (!m_player || networkState() == EMPTY) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -