2009-03-23 Eric Carlson <eric.carlson@apple.com>

        Reviewed by Adele Peterson.

        https://bugs.webkit.org/show_bug.cgi?id=24588
        
        Update media element implementation to current HTML5 spec

        New tests: 
               media/media-constants.html
               media/video-seek-no-src-exception.html
               media/video-source-add-src.html
               media/video-src-invalid-remove.html
               media/video-src-plus-source.html
               media/video-timeupdate-during-playback.html

        * dom/EventNames.h: Remove obsolute events, add new ones.
        * html/HTMLMediaElement.cpp:
        (WebCore::HTMLMediaElement::HTMLMediaElement): Initialize new member vars.
        (WebCore::HTMLMediaElement::attributeChanged): Trigger load() only when we don't
        have a source.
        (WebCore::HTMLMediaElement::removedFromDocument): Deal with state name changes.
        (WebCore::HTMLMediaElement::scheduleProgressEvent): New, create a progress event and 
        add it to the event queue to be dispatch when the timer fires.
        (WebCore::HTMLMediaElement::scheduleEvent): New, create a generic event and add
        it to the event queue to be dispatch when the timer fires.
        (WebCore::HTMLMediaElement::enqueueEvent): Add an event to the queue and ticke the 
        asynch event timer.
        (WebCore::HTMLMediaElement::asyncEventTimerFired): Dispatch all pending events.
        (WebCore::HTMLMediaElement::loadTimerFired): Either trigger the initial load or
        try to load the next <source> url.
        (WebCore::HTMLMediaElement::load): Minor style change.
        (WebCore::HTMLMediaElement::loadInternal): The first part of the spec load algorithm, cleanup
        the current load (if any) and set up state for a new load.
        (WebCore::HTMLMediaElement::selectMediaResource): Deal with no 'src' or <source>, post 'loadstart'
        event, and initiate load from 'src' if present.
        (WebCore::HTMLMediaElement::loadNextSourceChild): Initiate load from next <source> url, or trigger
        noneSupported() if no more to consider.
        (WebCore::HTMLMediaElement::loadResource): Instantiate a new MediaPlayer and ask it to load a url.
        (WebCore::HTMLMediaElement::startProgressEventTimer): Start the repeating progress event timer.
        (WebCore::HTMLMediaElement::noneSupported): Post error event and set up state when no valid 
        media url was found.
        (WebCore::HTMLMediaElement::mediaEngineError): Post error event and set up state when no valid 
        media engine failed with a decode error or a network error.
        (WebCore::HTMLMediaElement::mediaPlayerNetworkStateChanged):
        (WebCore::HTMLMediaElement::setNetworkState): Updated for new spec network states.
        (WebCore::HTMLMediaElement::mediaPlayerReadyStateChanged):
        (WebCore::HTMLMediaElement::setReadyState): Updated for new spec ready state.
        (WebCore::HTMLMediaElement::progressEventTimerFired): Bail if the network is not active.
        (WebCore::HTMLMediaElement::seek): Return INVALID_STATE_ERR exception if state is too low or
        if player hasn't been set up yet. This is necessary becase load() is async. Clear the flag
        we use to guard against sending 'ended' more than once.
        (WebCore::HTMLMediaElement::duration): Don't bother calling media engine before it has metadata.
        (WebCore::HTMLMediaElement::setDefaultPlaybackRate): Remove exception param, 0 is no longer an
        invalid rate. 
        (WebCore::HTMLMediaElement::setPlaybackRate): Remove exception param, 0 is no longer an
        invalid rate. Cache rate being set so we can use it later if media engine isn't ready now.
        (WebCore::HTMLMediaElement::play): Remove exception param, play() before load() now just
        starts loading asynchronously.
        (WebCore::HTMLMediaElement::playInternal): Remove exception param. Fire 'waiting' or 'playing'
        event depending on current state.
        (WebCore::HTMLMediaElement::pause): Remove exception param, pause() before load() now just
        starts loading asynchronously.
        (WebCore::HTMLMediaElement::pauseInternal): Remove exception param.
        (WebCore::HTMLMediaElement::setVolume): dispatchEventAsync -> scheduleEvent
        (WebCore::HTMLMediaElement::setMuted): dispatchEventAsync -> scheduleEvent
        (WebCore::HTMLMediaElement::togglePlayState): Remove exception param.
        (WebCore::HTMLMediaElement::beginScrubbing): pause() doesn't take an exception param.
        (WebCore::HTMLMediaElement::startPlaybackProgressTimer): New, starts timer that fires 4 times per
        second when the movie is playing to timeupdate so we can post 'timeupdate' events.
        (WebCore::HTMLMediaElement::playbackProgressTimerFired): Timer proc.
        (WebCore::HTMLMediaElement::scheduleTimeupdateEvent): Bottleneck around scheduling a 'timeupdate'
        event because we both fire them them when the spec says we should and when the media engine
        says that time has jumped, but we don't want to fire more than one at a given movie time. We also
        use this bottleneck to keep track of the last time one was posted so we won't fire too often
        during playback.
        (WebCore::HTMLMediaElement::canPlay): readyState now tracks whether or not we have metadata.
        (WebCore::HTMLMediaElement::havePotentialSourceChild): New, checks to see if there are a <source>
        element with a 'src' attribute that we have not tried to load yet.
        (WebCore::HTMLMediaElement::nextSourceChild): New, returns the url and content type of the next
        <source> element that we haven't tried to load.
        (WebCore::HTMLMediaElement::mediaPlayerTimeChanged): Schedule 'seeked' event when seeking completes.
        Set a flag when we post the 'ended' event, clear it when time changed and we aren't at the end since
        some media engines call this proc more than once when playback reaches the end and stops, but we
        don't want to post 'ended' more than once.
        (WebCore::HTMLMediaElement::mediaPlayerDurationChanged): New, added so media engine can inform
        when the movie duration changes and we can post 'durationchanged' event.
        (WebCore::HTMLMediaElement::mediaPlayerRateChanged): New, added so media engine can inform when
        the rate changed and we can updated our cached rate. This is useful because we only want to know
        post periodic 'timeupdate' events when the movie is actually playing, and because we want to know
        the actual playback rate when it differs from what we tried to set.
        (WebCore::HTMLMediaElement::mediaPlayerSizeChanged): New, added so media engine can inform when
        a movie's intrinsic size changes and we can inform the renderer.
        (WebCore::HTMLMediaElement::potentiallyPlaying): Renamed from activelyPlaying since the spec now
        uses "actively playing" for this concept. Update logic for new state names and un-comment calls
        to stoppedDueToErrors() and pausedForUserInteraction() since the spec says those condiditons
        are part of the answer.
        (WebCore::HTMLMediaElement::endedPlayback): Update logic for new state names. 
        (WebCore::HTMLMediaElement::stoppedDueToErrors): New, spec says this logic should be part of
        the determination of "potentially playing".
        (WebCore::HTMLMediaElement::pausedForUserInteraction): New, placeholder for when (if) user
        agent supports this spec concept.
        (WebCore::HTMLMediaElement::updatePlayState): Stop timer used to fire periodic 'timeupdate' 
        events when we pauses the movie. Set the media engine rate before calling play() in case it
        wasn't set up when the rate was changed.
        (WebCore::HTMLMediaElement::stopPeriodicTimers): New, stop the progress event and 'timeupate'
        event timers.
        (WebCore::HTMLMediaElement::userCancelledLoad): New, logic pulled out of documentWillBecomeInactive
        and updated for the current spec.
        (WebCore::HTMLMediaElement::documentWillBecomeInactive): Moved some logic to userCancelledLoad.
        (WebCore::HTMLMediaElement::documentDidBecomeActive): Update comments.
        (WebCore::HTMLMediaElement::initialURL): Update for refactoring of code that determines the 
        initial url.
        * html/HTMLMediaElement.h: Change ReadyState and NetworkState enums to match names in the spec,
        update for changes in .cpp.
        (WebCore::HTMLMediaElement::):

        * html/HTMLMediaElement.idl: Update ready state and network state constants for spec changes.
        defaultPlaybackRate, playbackRate, play(), and pause() no longer raise exceptions.

        * html/HTMLSourceElement.cpp:
        (WebCore::HTMLSourceElement::insertedIntoDocument): Update for network state name changes.

        * html/HTMLVideoElement.cpp:
        (WebCore::HTMLVideoElement::updatePosterImage): Update for ready state name changes.

        * html/MediaError.h:
        (WebCore::MediaError::): add MEDIA_ERR_NONE_SUPPORTED.

        * html/MediaError.idl: add MEDIA_ERR_NONE_SUPPORTED.

        * loader/MediaDocument.cpp:
        (WebCore::MediaDocument::defaultEventHandler): play() and pause() don't take an exception.

        * platform/graphics/MediaPlayer.cpp:
        (WebCore::NullMediaPlayerPrivate::readyState): Update for newtork state name changes.
        (WebCore::MediaPlayer::sizeChanged): New, so engine can report intrinsic size changes.
        (WebCore::MediaPlayer::rateChanged): New, so engine can report rate changes.
        (WebCore::MediaPlayer::durationChanged): New, so engine can report duration changes.
        * platform/graphics/MediaPlayer.h: Update NetworkState and ReadyState enum names to match spec
        states.
        (WebCore::MediaPlayerClient::mediaPlayerDurationChanged): New.
        (WebCore::MediaPlayerClient::mediaPlayerRateChanged): New.
        (WebCore::MediaPlayerClient::mediaPlayerSizeChanged): New.
        (WebCore::MediaPlayer::):

        * platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp:
        (WebCore::MediaPlayerPrivate::MediaPlayerPrivate): Update for network/ready state name changes.
        (WebCore::MediaPlayerPrivate::load): Ditto.
        (WebCore::MediaPlayerPrivate::updateStates): Ditto.
        (WebCore::MediaPlayerPrivate::loadingFailed): Ditto.

        * platform/graphics/mac/MediaPlayerPrivateQTKit.h: Update for network/ready state name changes.
        Remove endPointTimer, it is no longer necessary. Add m_enabledTrackCount and m_duration.
        (WebCore::MediaPlayerPrivate::metaDataAvailable):
        * platform/graphics/mac/MediaPlayerPrivateQTKit.mm:
        (WebCore::MediaPlayerPrivate::MediaPlayerPrivate): No more m_endPointTimer or m_endTime. Initialize
        m_enabledTrackCount and m_duration. Update for network/ready state name changes.
        (WebCore::MediaPlayerPrivate::load): Update for network/ready state name changes.
        (WebCore::MediaPlayerPrivate::play): No more m_endPointTimer.
        (WebCore::MediaPlayerPrivate::pause): Ditto.
        (WebCore::MediaPlayerPrivate::currentTime): No more m_endTime.
        (WebCore::MediaPlayerPrivate::seek): Ditto.
        (WebCore::MediaPlayerPrivate::doSeek): Ditto, plus don't call setRate(0) when the rate is
        already zero.
        (WebCore::MediaPlayerPrivate::setEndTime): No more m_endTime.
        (WebCore::MediaPlayerPrivate::updateStates): Update for network/ready state name changes. Return
        different errors depending on what causes a failure. Watch for and report duration changes.
        (WebCore::MediaPlayerPrivate::rateChanged): Report rate changes.
        (WebCore::MediaPlayerPrivate::sizeChanged): Report size changes.
        (WebCore::MediaPlayerPrivate::didEnd): No more endpoint timer.
        (WebCore::MediaPlayerPrivate::setVisible): Update for network/ready state name changes.
        (WebCore::MediaPlayerPrivate::disableUnsupportedTracks): Don't return number of unsupported
        tracks, store in m_enabledTrackCount so we can use it to help determine causes of failure.

        * platform/graphics/qt/MediaPlayerPrivatePhonon.cpp:
        (WebCore::MediaPlayerPrivate::MediaPlayerPrivate): Update for network/ready state name changes.
        (WebCore::MediaPlayerPrivate::load): Ditto.
        (WebCore::MediaPlayerPrivate::duration): Ditto.
        (WebCore::MediaPlayerPrivate::updateStates): Ditto.
        (WebCore::MediaPlayerPrivate::naturalSize): Ditto.

        * platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp:
        (WebCore::MediaPlayerPrivate::MediaPlayerPrivate): No more m_endPointTimer. Update for 
        network/ready state name changes.
        (WebCore::MediaPlayerPrivate::load): Update for network/ready state name changes. No more
        m_endPointTimer.
        (WebCore::MediaPlayerPrivate::play): No more m_endPointTimer.
        (WebCore::MediaPlayerPrivate::pause): Ditto. 
        (WebCore::MediaPlayerPrivate::setEndTime): Ditto.
        (WebCore::MediaPlayerPrivate::updateStates): Update for network/ready state name changes.
        (WebCore::MediaPlayerPrivate::didEnd): No more m_endPointTimer.
        * platform/graphics/win/MediaPlayerPrivateQuickTimeWin.h:

        * rendering/MediaControlElements.cpp:
        (WebCore::MediaControlPlayButtonElement::defaultEventHandler): Update for network/ready state 
        name changes.
        (WebCore::MediaControlSeekButtonElement::defaultEventHandler): Ditto.

2009-03-23  Eric Carlson  <eric.carlson@apple.com>

        Reviewed by Adele Peterson.
        
        https://bugs.webkit.org/show_bug.cgi?id=24588
        Bug 24588: Update media element implementation to current spec

        * media/media-constants-expected.txt: Test all media constants.
        * media/media-constants.html: Ditto.
        * media/remove-from-document-expected.txt: Updated for spec changes.
        * media/remove-from-document-no-load.html: Ditto.
        * media/remove-from-document.html: Ditto.
        * media/unsupported-rtsp-expected.txt: Ditto.
        * media/unsupported-rtsp.html: Ditto.
        * media/video-currentTime-set-expected.txt: Ditto.
        * media/video-currentTime-set.html: Ditto.
        * media/video-error-does-not-exist-expected.txt: Ditto.
        * media/video-error-does-not-exist.html: Ditto.
        * media/video-load-networkState-expected.txt: Ditto.
        * media/video-load-networkState.html: Ditto.
        * media/video-load-readyState-expected.txt: Ditto.
        * media/video-load-readyState.html: Ditto.
        * media/video-loop-expected.txt: Ditto.
        * media/video-loop.html: Ditto.
        * media/video-pause-empty-events-expected.txt: Ditto.
        * media/video-pause-empty-events.html: Ditto.
        * media/video-play-empty-events-expected.txt: Ditto.
        * media/video-play-empty-events.html: Ditto.
        * media/video-play-pause-events-expected.txt: Ditto.
        * media/video-play-pause-events.html: Ditto.
        * media/video-play-pause-exception-expected.txt: Ditto.
        * media/video-play-pause-exception.html: Ditto.
        * media/video-seek-no-src-exception-expected.txt: Test that seeking 
        whene there is no 'src' attribute throws an INVALID_STATE_ERR exception.
        * media/video-seek-no-src-exception.html: 
        * media/video-seek-past-end-playing-expected.txt: Ditto.
        * media/video-seek-past-end-playing.html: Ditto.
        * media/video-seeking-expected.txt: Ditto.
        * media/video-seeking.html: Ditto.
        * media/video-source-add-src-expected.txt: Test that adding a 'src' 
        attribute does nothing when a <source> element has already been chosen.
        * media/video-source-add-src.html: 
        * media/video-src-change-expected.txt: Ditto.
        * media/video-src-change.html: Ditto.
        * media/video-src-invalid-remove-expected.txt: Test that removing invalid 
        'src' attribute triggers <source> elements loading.
        * media/video-src-invalid-remove.html: 
        * media/video-src-plus-source-expected.txt: Test that a <source> element 
        is not used when a bogus 'src' attribute is present.
        * media/video-src-plus-source.html: 
        * media/video-src-remove-expected.txt: Ditto.
        * media/video-src-remove.html: Ditto.
        * media/video-test.js: 
        (findMediaElement):
        (testExpected):
        (waitForEvent):
        (failTest):
        * media/video-timeupdate-during-playback-expected.txt: Test that 'timeupdate' events
        are posted while an element is playing but not while paused.
        * media/video-timeupdate-during-playback.html:

        * platform/mac/Skipped: Skip media/video-error-abort.html for now, need to figure out how to 
        test now that the 'loadstart' event is now fired asynchronously.
        * platform/win/Skipped



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@41907 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 69e405c4
2009-03-23 Eric Carlson <eric.carlson@apple.com>
Reviewed by Adele Peterson.
https://bugs.webkit.org/show_bug.cgi?id=24588
Bug 24588: Update media element implementation to current spec
* media/media-constants-expected.txt: Test all media constants.
* media/media-constants.html: Ditto.
* media/remove-from-document-expected.txt: Updated for spec changes.
* media/remove-from-document-no-load.html: Ditto.
* media/remove-from-document.html: Ditto.
* media/unsupported-rtsp-expected.txt: Ditto.
* media/unsupported-rtsp.html: Ditto.
* media/video-currentTime-set-expected.txt: Ditto.
* media/video-currentTime-set.html: Ditto.
* media/video-error-does-not-exist-expected.txt: Ditto.
* media/video-error-does-not-exist.html: Ditto.
* media/video-load-networkState-expected.txt: Ditto.
* media/video-load-networkState.html: Ditto.
* media/video-load-readyState-expected.txt: Ditto.
* media/video-load-readyState.html: Ditto.
* media/video-loop-expected.txt: Ditto.
* media/video-loop.html: Ditto.
* media/video-pause-empty-events-expected.txt: Ditto.
* media/video-pause-empty-events.html: Ditto.
* media/video-play-empty-events-expected.txt: Ditto.
* media/video-play-empty-events.html: Ditto.
* media/video-play-pause-events-expected.txt: Ditto.
* media/video-play-pause-events.html: Ditto.
* media/video-play-pause-exception-expected.txt: Ditto.
* media/video-play-pause-exception.html: Ditto.
* media/video-seek-no-src-exception-expected.txt: Test that seeking
whene there is no 'src' attribute throws an INVALID_STATE_ERR exception.
* media/video-seek-no-src-exception.html:
* media/video-seek-past-end-playing-expected.txt: Ditto.
* media/video-seek-past-end-playing.html: Ditto.
* media/video-seeking-expected.txt: Ditto.
* media/video-seeking.html: Ditto.
* media/video-source-add-src-expected.txt: Test that adding a 'src'
attribute does nothing when a <source> element has already been chosen.
* media/video-source-add-src.html:
* media/video-src-change-expected.txt: Ditto.
* media/video-src-change.html: Ditto.
* media/video-src-invalid-remove-expected.txt: Test that removing invalid
'src' attribute triggers <source> elements loading.
* media/video-src-invalid-remove.html:
* media/video-src-plus-source-expected.txt: Test that a <source> element
is not used when a bogus 'src' attribute is present.
* media/video-src-plus-source.html:
* media/video-src-remove-expected.txt: Ditto.
* media/video-src-remove.html: Ditto.
* media/video-test.js:
(findMediaElement):
(testExpected):
(waitForEvent):
(failTest):
* media/video-timeupdate-during-playback-expected.txt: Test that 'timeupdate' events
are posted while an element is playing but not while paused.
* media/video-timeupdate-during-playback.html:
* platform/mac/Skipped: Skip media/video-error-abort.html for now, need to figure out how to
test now that the 'loadstart' event is now fired asynchronously.
* platform/win/Skipped
2009-03-22 Simon Fraser <simon.fraser@apple.com>
Reviewed by Dan Bernstein
......
Test HTMLMediaElement and MediaError constants.
EXPECTED (HTMLMediaElement.NETWORK_EMPTY == '0') OK
EXPECTED (HTMLMediaElement.NETWORK_IDLE == '1') OK
EXPECTED (HTMLMediaElement.NETWORK_LOADING == '2') OK
EXPECTED (HTMLMediaElement.NETWORK_LOADED == '3') OK
EXPECTED (HTMLMediaElement.NETWORK_NO_SOURCE == '4') OK
EXPECTED (HTMLMediaElement.HAVE_NOTHING == '0') OK
EXPECTED (HTMLMediaElement.HAVE_METADATA == '1') OK
EXPECTED (HTMLMediaElement.HAVE_CURRENT_DATA == '2') OK
EXPECTED (HTMLMediaElement.HAVE_FUTURE_DATA == '3') OK
EXPECTED (HTMLMediaElement.HAVE_ENOUGH_DATA == '4') OK
EXPECTED (MediaError.MEDIA_ERR_ABORTED == '1') OK
EXPECTED (MediaError.MEDIA_ERR_NETWORK == '2') OK
EXPECTED (MediaError.MEDIA_ERR_DECODE == '3') OK
EXPECTED (MediaError.MEDIA_ERR_NONE_SUPPORTED == '4') OK
END OF TEST
<p>Test HTMLMediaElement and MediaError constants.</p>
<script src=video-test.js></script>
<script>
testExpected("HTMLMediaElement.NETWORK_EMPTY", 0);
testExpected("HTMLMediaElement.NETWORK_IDLE", 1);
testExpected("HTMLMediaElement.NETWORK_LOADING", 2);
testExpected("HTMLMediaElement.NETWORK_LOADED", 3);
testExpected("HTMLMediaElement.NETWORK_NO_SOURCE", 4);
consoleWrite("");
testExpected("HTMLMediaElement.HAVE_NOTHING", 0);
testExpected("HTMLMediaElement.HAVE_METADATA", 1);
testExpected("HTMLMediaElement.HAVE_CURRENT_DATA", 2);
testExpected("HTMLMediaElement.HAVE_FUTURE_DATA", 3);
testExpected("HTMLMediaElement.HAVE_ENOUGH_DATA", 4);
consoleWrite("");
testExpected("MediaError.MEDIA_ERR_ABORTED", 1);
testExpected("MediaError.MEDIA_ERR_NETWORK", 2);
testExpected("MediaError.MEDIA_ERR_DECODE", 3);
testExpected("MediaError.MEDIA_ERR_NONE_SUPPORTED", 4);
endTest();
</script>
Test that removing a media element from the tree pauses playback but does not unload the media.
EVENT(load)
EXPECTED (video.networkState == '4') OK
EXPECTED (video.networkState == '3') OK
EXPECTED (video.paused == 'false') OK
RUN(document.body.removeChild(video))
EXPECTED (video.networkState == '4') OK
EXPECTED (video.networkState == '3') OK
EXPECTED (video.paused == 'true') OK
END OF TEST
......@@ -5,7 +5,7 @@
didReceiveLoadStartEvent = false;
video.addEventListener('loadstart', function() { didReceiveLoadStartEvent = true; });
video.src = "content/test.mp4";
testExpected("video.networkState", HTMLMediaElement.EMPTY);
testExpected("video.networkState", HTMLMediaElement.NETWORK_EMPTY);
run("document.body.removeChild(video)");
testExpected("didReceiveLoadStartEvent", false);
endTest();
......
<video controls></video>
<video controls autoplay></video>
<p>Test that removing a media element from the tree pauses playback but does not unload the media.</p>
<script src=video-test.js></script>
<script>
waitForEvent('load', function () {
testExpected("video.networkState", HTMLMediaElement.LOADED);
testExpected("video.networkState", HTMLMediaElement.NETWORK_LOADED);
testExpected("video.paused", false);
run("document.body.removeChild(video)");
testExpected("video.networkState", HTMLMediaElement.LOADED);
testExpected("video.networkState", HTMLMediaElement.NETWORK_LOADED);
testExpected("video.paused", true);
document.body.offsetTop;
......@@ -17,5 +17,4 @@
} );
video.src = "content/test.mp4";
video.play();
</script>
......@@ -2,6 +2,7 @@ Test that QuickTime file with RTSP URL generates a load error.
EVENT(error)
EXPECTED (video.error != 'null') OK
EXPECTED (video.error.code == '2') OK
EXPECTED (video.error.code == '4') OK
EXPECTED (video.networkState == '4') OK
END OF TEST
<video controls></video>
<p>Test that QuickTime file with RTSP URL generates a load error.<p>
<script src=video-test.js></script>
<script>
video.src = "rtsp://a2047.v1411b.c1411.g.vq.akamaistream.net/5/2047/1411/2_h264_650/1a1a1ae454c430950065de4cbb2f94c226950c7ae655b61a48a91475e243acda3dac194879adde0f/wwdc_2006_2_650.mov";
waitForEvent("error", function () {
testExpected("video.error", null, "!=");
testExpected("video.error.code", MediaError.MEDIA_ERR_NETWORK);
endTest();
});
video.src = "rtsp://a2047.v1411b.c1411.g.vq.akamaistream.net/5/2047/1411/2_h264_650/1a1a1ae454c430950065de4cbb2f94c226950c7ae655b61a48a91475e243acda3dac194879adde0f/wwdc_2006_2_650.mov";
waitForEvent("error", function () {
testExpected("video.error", null, "!=");
testExpected("video.error.code", MediaError.MEDIA_ERR_NONE_SUPPORTED);
testExpected("video.networkState", HTMLMediaElement.NETWORK_NO_SOURCE);
endTest();
});
</script>
Test that setting currentTime changes the time, and that 'ended' event is fired in a reasonable amount of time
EVENT(load)
EVENT(timeupdate)
EXPECTED (video.currentTime == '0') OK
RUN(video.currentTime = video.duration - 0.2)
EXPECTED (video.currentTime.toFixed(2) == '8.20') OK
RUN(video.play())
EVENT(ended)
END OF TEST
<video src=content/test.mp4 controls></video>
<script src=video-test.js></script>
<script>
waitForEvent('load',
function () {
video.currentTime = video.duration - 0.2;
video.play();
waitForEvent('timeupdate', function () {
<html>
<body>
<video src=content/test.mp4 controls></video>
<p>Test that setting currentTime changes the time, and that 'ended' event is fired in a reasonable amount of time</p>
<script src=video-test.js></script>
<script>
waitForEvent('load',
function () {
waitForEventAndEnd('ended');
testExpected("video.currentTime", 0);
run("video.currentTime = video.duration - 0.2");
testExpected("video.currentTime.toFixed(2)", (video.duration - 0.2).toFixed(2));
run("video.play()");
consoleWrite("");
var timeout = 800;
setTimeout(function () { logResult("No timeupdate event in " + timeout/1000 + "seconds", false); }, timeout);
setTimeout(function () { logResult("No 'ended' event in " + timeout/1000 + "seconds", false); }, timeout);
});
waitForEventAndEnd('ended');
});
video.src = "content/test.mp4";
</script>
video.src = "content/test.mp4";
</script>
</body>
</html>
Test that the media element is in correct state after load fails.
EXPECTED (video.error == 'null') OK
EVENT(emptied)
EXPECTED (video.error.code == '2') OK
EXPECTED (video.duration == '0') OK
EVENT(error)
EXPECTED (video.error != 'null') OK
EXPECTED (video.error.code == '4') OK
EXPECTED (video.networkState == '4') OK
EXPECTED (isNaN(video.duration) == 'true') OK
EXPECTED (video.currentTime == '0') OK
EXPECTED (video.buffered.length == '0') OK
EXPECTED (video.seekable.length == '0') OK
......
......@@ -2,16 +2,26 @@
<video controls></video>
<script src=video-test.js></script>
<script>
testExpected("video.error", null);
waitForEventAndTest("load", "false");
waitForEvent("emptied", function () {
testExpected("video.error.code", MediaError.MEDIA_ERR_NETWORK);
testExpected("video.duration", 0);
testExpected("video.currentTime", 0);
testExpected("video.buffered.length", 0);
testExpected("video.seekable.length", 0);
testExpected("video.buffered.length", 0);
endTest();
});
video.src = "content/does-not-exist.mpeg";
consoleWrite("");
testExpected("video.error", null);
waitForEventAndTest("load", "false");
waitForEvent("error", function () {
testExpected("video.error", null, "!=");
testExpected("video.error.code", MediaError.MEDIA_ERR_NONE_SUPPORTED);
testExpected("video.networkState", HTMLMediaElement.NETWORK_NO_SOURCE);
testExpected("isNaN(video.duration)", true);
testExpected("video.currentTime", 0);
testExpected("video.buffered.length", 0);
testExpected("video.seekable.length", 0);
testExpected("video.buffered.length", 0);
endTest();
});
video.src = "content/does-not-exist.mpeg";
consoleWrite("");
</script>
Test that setting src to an invalid url triggers load(), which sets networkState to NETWORK_NO_SOURCE. Setting src to a valid url should then trigger the loading events and end up with networkState >= NETWORK_LOADING.
EXPECTED (video.networkState == '0') OK
RUN(video.src = 'bogus/movie.mpg')
EVENT(loadstart)
EXPECTED (video.networkState == '1') OK
EVENT(loadedmetadata)
EXPECTED (video.networkState == '2') OK
EVENT(loadedfirstframe)
EXPECTED (video.networkState == '3') OK
EVENT(load)
EXPECTED (video.networkState == '4') OK
RUN(video.src = 'content/test.mp4')
EVENT(loadstart)
EVENT(loadedmetadata)
EVENT(loadeddata)
EVENT(canplay)
EVENT(canplaythrough)
EXPECTED (video.networkState >= '2') OK
END OF TEST
<video controls></video>
<script src=video-test.js></script>
<script>
function testNetworkState(expected, endIt)
{
testExpected("video.networkState", expected);
if (endIt)
endTest();
}
<html>
<body>
testExpected("video.networkState", HTMLMediaElement.EMPTY);
waitForEvent("loadstart", function () { testNetworkState(HTMLMediaElement.LOADING); } );
waitForEvent("loadedmetadata", function () { testNetworkState(HTMLMediaElement.LOADED_METADATA); } );
waitForEvent("loadedfirstframe", function () { testNetworkState(HTMLMediaElement.LOADED_FIRST_FRAME); } );
waitForEvent("load", function () { testNetworkState(HTMLMediaElement.LOADED, true); } );
video.src = "content/test.mp4";
</script>
<video controls></video>
<p>Test that setting src to an invalid url triggers load(), which sets networkState
to NETWORK_NO_SOURCE. Setting src to a valid url should then trigger the loading
events and end up with networkState >= NETWORK_LOADING.
</p>
<script src=video-test.js></script>
<script>
function testNetworkState(expected, endit, op)
{
testExpected("video.networkState", expected, op);
if (endit)
endTest();
}
waitForEvent("loadstart");
waitForEvent("loadedmetadata");
waitForEvent("loadeddata");
waitForEvent("canplay");
waitForEventAndFail("play");
waitForEventAndFail("playing");
waitForEvent("canplaythrough", function () { testNetworkState(HTMLMediaElement.NETWORK_LOADING, true, '>=' ); } );
function someTimeLater()
{
testNetworkState(HTMLMediaElement.NETWORK_NO_SOURCE );
consoleWrite("");
// now set a valid url
run("video.src = 'content/test.mp4'");
}
// first set the src to a bogus url, it should attempt a load
consoleWrite("");
testNetworkState(HTMLMediaElement.NETWORK_EMPTY);
run("video.src = 'bogus/movie.mpg'");
setTimeout(someTimeLater, 400)
</script>
</body>
</html>
EXPECTED (video.readyState == '0') OK
EVENT(loadstart)
EXPECTED (video.readyState == '0') OK
EVENT(loadedmetadata)
EXPECTED (video.readyState == '0') OK
EVENT(loadedfirstframe)
EXPECTED (video.readyState == '1') OK
EVENT(canshowcurrentframe)
EXPECTED (video.readyState == '1') OK
EVENT(loadeddata)
EVENT(canplay)
EVENT(canplaythrough)
EXPECTED (video.readyState == '3') OK
EXPECTED (video.readyState == '4') OK
END OF TEST
<video controls></video>
<script src=video-test.js></script>
<script>
function testReadyState(expected, endIt)
function testReadyState(expected, endit, op)
{
testExpected("video.readyState", expected);
if (endIt)
testExpected("video.readyState", expected, op);
if (endit)
endTest();
}
testExpected("video.readyState", HTMLMediaElement.DATA_UNAVAILABLE);
waitForEvent("loadstart", function () { testReadyState(HTMLMediaElement.DATA_UNAVAILABLE); } );
waitForEvent("loadedmetadata", function () { testReadyState(HTMLMediaElement.DATA_UNAVAILABLE); } );
waitForEvent("loadedfirstframe", function () { testReadyState(HTMLMediaElement.CAN_SHOW_CURRENT_FRAME); } );
waitForEvent("canshowcurrentframe", function () { testReadyState(HTMLMediaElement.CAN_SHOW_CURRENT_FRAME); } );
waitForEvent("canplaythrough", function () { testReadyState(HTMLMediaElement.CAN_PLAY_THROUGH, true); } );
testExpected("video.readyState", HTMLMediaElement.HAVE_NOTHING);
waitForEvent("loadstart");
waitForEvent("loadedmetadata");
waitForEvent("loadeddata");
waitForEvent("canplay");
waitForEventAndFail("play");
waitForEventAndFail("playing");
waitForEvent("canplaythrough", function () { testReadyState(HTMLMediaElement.HAVE_ENOUGH_DATA, true ); } );
video.src = "content/test.mp4";
</script>
......@@ -13,10 +13,12 @@ EVENT(play)
EXPECTED (video.paused == 'false') OK
RUN(video.currentTime = video.duration - 0.4)
EVENT(playing)
EXPECTED (video.ended == 'false') OK
EXPECTED (media.currentTime > '0') OK
EXPECTED (media.currentTime < '8.00') OK
RUN(video.loop = false)
RUN(video.currentTime = video.duration - 0.4)
RUN(video.currentTime = video.duration - 0.3)
EXPECTED (video.ended == 'true') OK
EXPECTED (media.currentTime == 'media.duration') OK
......
<video controls autoplay ></video>
<script src=video-test.js></script>
<script>
<html>
testExpected("video.getAttribute('loop')", null);
testExpected("video.loop", false);
<video controls autoplay ></video>
run("video.loop = true");
testExpected("video.loop", true);
testExpected("video.getAttribute('loop')", null, "!=");
<script src=video-test.js></script>
run("video.removeAttribute('loop')");
testExpected("video.loop", false);
<script>
testExpected("video.getAttribute('loop')", null);
testExpected("video.loop", false);
run("video.loop = true");
testExpected("video.loop", true);
testExpected("video.getAttribute('loop')", null, "!=");
run("video.removeAttribute('loop')");
testExpected("video.loop", false);
var respondToTimeUpdate = false;
var firstTimeCheck = true;
var respondToTimeUpdate = false;
var firstTimeCheck = true;
waitForEvent('pause');
waitForEvent('playing');
// make sure we are playing, seek to near the end so the test doesn't take too long
waitForEvent('play', function () {
testExpected("video.paused", false);
run("video.currentTime = video.duration - 0.4");
consoleWrite("");
setTimeout(timeCheck, 800);
} );
function timeCheck() {
testExpected("video.ended", !firstTimeCheck);
if (!firstTimeCheck)
{
// don't use "testExpected()" so we won't log the actual duration to the
// results file, as the floating point result may differ with different engines
reportExpected(media.currentTime == media.duration, "media.currentTime", "==", "media.duration", media.currentTime);
endTest();
return;
// make sure we are playing, seek to near the end so the test doesn't take too long
waitForEvent('play', function () {
testExpected("video.paused", false);
run("video.currentTime = video.duration - 0.4");
consoleWrite("");
setTimeout(timeCheck, 800);
} );
function timeCheck() {
testExpected("video.ended", !firstTimeCheck);
if (!firstTimeCheck)
{
// don't use "testExpected()" so we won't log the actual duration to the
// results file, as the floating point result may differ with different engines
reportExpected(media.currentTime == media.duration, "media.currentTime", "==", "media.duration", media.currentTime);
endTest();
return;
}
testExpected("media.currentTime", 0, '>');
testExpected("media.currentTime", (video.duration - 0.4).toFixed(2), '<');
run("video.loop = false");
run("video.currentTime = video.duration - 0.3");
respondToTimeUpdate = true;
firstTimeCheck = false;
consoleWrite("");
setTimeout(timeCheck, 800);
}
testExpected("media.currentTime", 0, '>');
run("video.loop = false");
run("video.currentTime = video.duration - 0.4");
respondToTimeUpdate = true;
firstTimeCheck = false;
consoleWrite("");
run("video.loop = true");
run("video.src = 'content/test.mp4'");
consoleWrite("");
setTimeout(timeCheck, 800);
}
</script>
</head>
consoleWrite("");
run("video.loop = true");
run("video.src = 'content/test.mp4'");
consoleWrite("");
</script>
</html>
\ No newline at end of file
......@@ -2,6 +2,12 @@ Test that pause() from EMPTY network state triggers load()
EXPECTED (video.networkState == '0') OK
RUN(video.pause())
SCRIPT DONE
EVENT(loadstart)
EVENT(durationchange)
EVENT(loadedmetadata)
EVENT(loadeddata)
EVENT(canplay)
EVENT(canplaythrough)
END OF TEST
......@@ -3,8 +3,18 @@
<script src=video-test.js></script>
<script>
video.src = "content/test.mp4";
testExpected("video.networkState", HTMLMediaElement.EMPTY);
waitForEventAndEnd('loadstart');
testExpected("video.networkState", HTMLMediaElement.NETWORK_EMPTY);