зеркало из https://github.com/mozilla/gecko-dev.git
Bug 469255 - Seeking while seek in progress not handled correctly by Wave decoder; r+sr=roc
This commit is contained in:
Родитель
f2e176127e
Коммит
95f82c5d78
|
@ -252,6 +252,13 @@ private:
|
|||
// underlying channel type.
|
||||
nsAutoPtr<nsMediaStream> mStream;
|
||||
|
||||
// The media time of the last requested seek. This has not been validated
|
||||
// against the current media, so may be out of bounds. Set when
|
||||
// Seek(float) is called, and passed to the state machine when the
|
||||
// SeekStarted event fires to tell it to update its time offset. The
|
||||
// state machine will validate the offset against the current media.
|
||||
float mTimeOffset;
|
||||
|
||||
// Copy of the current time and duration when the state machine was
|
||||
// disposed. Used to respond to time and duration queries with sensible
|
||||
// values after playback has ended.
|
||||
|
|
|
@ -151,6 +151,11 @@ public:
|
|||
// Main state machine loop. Runs forever, until shutdown state is reached.
|
||||
NS_IMETHOD Run();
|
||||
|
||||
// Called by the decoder when the SeekStarted event runs. This ensures
|
||||
// the current time offset of the state machine is updated to the new seek
|
||||
// position at the appropriate time.
|
||||
void UpdateTimeOffset(float aTime);
|
||||
|
||||
private:
|
||||
// Change the current state and wake the playback thread if it is waiting
|
||||
// on mMonitor. Used by public member functions called from both threads,
|
||||
|
@ -281,7 +286,7 @@ private:
|
|||
float mInitialVolume;
|
||||
|
||||
// Time position (in seconds) to offset current time from audio stream.
|
||||
// Set by calling Seek(float) when seeking, and when the stream is closed
|
||||
// Set when the seek started event runs and when the stream is closed
|
||||
// during shutdown.
|
||||
float mTimeOffset;
|
||||
|
||||
|
@ -290,6 +295,9 @@ private:
|
|||
// Available() reports).
|
||||
PRPackedBool mExpectMoreData;
|
||||
|
||||
// Time position (in seconds) to seek to. Set by Seek(float).
|
||||
float mSeekTime;
|
||||
|
||||
// True once metadata has been parsed and validated. Users of mSampleRate,
|
||||
// mChannels, mSampleSize, mSampleFormat, mWaveLength, mWavePCMOffset must
|
||||
// check this flag before assuming the values are valid.
|
||||
|
@ -316,6 +324,7 @@ nsWaveStateMachine::nsWaveStateMachine(nsWaveDecoder* aDecoder, nsMediaStream* a
|
|||
mInitialVolume(aInitialVolume),
|
||||
mTimeOffset(0.0),
|
||||
mExpectMoreData(PR_TRUE),
|
||||
mSeekTime(0.0),
|
||||
mMetadataValid(PR_FALSE)
|
||||
{
|
||||
mMonitor = nsAutoMonitor::NewMonitor("nsWaveStateMachine");
|
||||
|
@ -379,9 +388,9 @@ nsWaveStateMachine::Seek(float aTime)
|
|||
{
|
||||
nsAutoMonitor monitor(mMonitor);
|
||||
mNextState = mState;
|
||||
mTimeOffset = NS_MIN(aTime, BytesToTime(mWaveLength));
|
||||
if (mTimeOffset < 0.0) {
|
||||
mTimeOffset = 0.0;
|
||||
mSeekTime = NS_MIN(aTime, BytesToTime(mWaveLength));
|
||||
if (mSeekTime < 0.0) {
|
||||
mSeekTime = 0.0;
|
||||
}
|
||||
ChangeState(STATE_SEEKING);
|
||||
}
|
||||
|
@ -391,7 +400,15 @@ nsWaveStateMachine::GetDuration()
|
|||
{
|
||||
nsAutoMonitor monitor(mMonitor);
|
||||
if (mMetadataValid) {
|
||||
return BytesToTime(mWaveLength);
|
||||
PRUint32 length = mWaveLength;
|
||||
PRInt64 contentLength = mDecoder->GetTotalBytes();
|
||||
// If the decoder has a valid content length, and it's shorter than the
|
||||
// expected length of the PCM data, calculate the playback duration from
|
||||
// the content length rather than the expected PCM data length.
|
||||
if (contentLength >= 0 && contentLength - mWavePCMOffset < length) {
|
||||
length = contentLength - mWavePCMOffset;
|
||||
}
|
||||
return BytesToTime(length);
|
||||
}
|
||||
return std::numeric_limits<float>::quiet_NaN();
|
||||
}
|
||||
|
@ -562,6 +579,9 @@ nsWaveStateMachine::Run()
|
|||
{
|
||||
CloseAudioStream();
|
||||
|
||||
mSeekTime = NS_MIN(mSeekTime, GetDuration());
|
||||
float seekTime = mSeekTime;
|
||||
|
||||
monitor.Exit();
|
||||
nsCOMPtr<nsIRunnable> startEvent =
|
||||
NS_NEW_RUNNABLE_METHOD(nsWaveDecoder, mDecoder, SeekingStarted);
|
||||
|
@ -572,8 +592,12 @@ nsWaveStateMachine::Run()
|
|||
break;
|
||||
}
|
||||
|
||||
PRInt64 position = RoundDownToSample(TimeToBytes(mTimeOffset)) + mWavePCMOffset;
|
||||
NS_ABORT_IF_FALSE(position >= 0 && position <= mWaveLength + mWavePCMOffset, "Invalid seek position");
|
||||
// Calculate relative offset within PCM data.
|
||||
PRInt64 position = RoundDownToSample(TimeToBytes(seekTime));
|
||||
NS_ABORT_IF_FALSE(position >= 0 && position <= mWaveLength, "Invalid seek position");
|
||||
|
||||
// Convert to absolute offset within stream.
|
||||
position += mWavePCMOffset;
|
||||
|
||||
monitor.Exit();
|
||||
nsresult rv = mStream->Seek(nsISeekableStream::NS_SEEK_SET, position);
|
||||
|
@ -592,7 +616,7 @@ nsWaveStateMachine::Run()
|
|||
NS_DispatchToMainThread(stopEvent, NS_DISPATCH_SYNC);
|
||||
monitor.Enter();
|
||||
|
||||
if (mState != STATE_SHUTDOWN) {
|
||||
if (mState == STATE_SEEKING && mSeekTime == seekTime) {
|
||||
ChangeState(mNextState);
|
||||
}
|
||||
}
|
||||
|
@ -649,6 +673,16 @@ nsWaveStateMachine::Run()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsWaveStateMachine::UpdateTimeOffset(float aTime)
|
||||
{
|
||||
nsAutoMonitor monitor(mMonitor);
|
||||
mTimeOffset = NS_MIN(aTime, GetDuration());
|
||||
if (mTimeOffset < 0.0) {
|
||||
mTimeOffset = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsWaveStateMachine::ChangeState(State aState)
|
||||
{
|
||||
|
@ -915,6 +949,7 @@ nsWaveDecoder::nsWaveDecoder()
|
|||
: mBytesDownloaded(0),
|
||||
mInitialVolume(1.0),
|
||||
mStream(nsnull),
|
||||
mTimeOffset(0.0),
|
||||
mEndedCurrentTime(0.0),
|
||||
mEndedDuration(std::numeric_limits<float>::quiet_NaN()),
|
||||
mNotifyOnShutdown(PR_FALSE),
|
||||
|
@ -955,8 +990,10 @@ nsWaveDecoder::GetCurrentTime()
|
|||
nsresult
|
||||
nsWaveDecoder::Seek(float aTime)
|
||||
{
|
||||
mTimeOffset = aTime;
|
||||
|
||||
if (mPlaybackStateMachine) {
|
||||
mPlaybackStateMachine->Seek(aTime);
|
||||
mPlaybackStateMachine->Seek(mTimeOffset);
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
|
@ -1255,6 +1292,10 @@ nsWaveDecoder::SeekingStarted()
|
|||
return;
|
||||
}
|
||||
|
||||
if (mPlaybackStateMachine) {
|
||||
mPlaybackStateMachine->UpdateTimeOffset(mTimeOffset);
|
||||
}
|
||||
|
||||
if (mElement) {
|
||||
mElement->SeekStarted();
|
||||
}
|
||||
|
|
|
@ -71,12 +71,23 @@ _TEST_FILES = test_autoplay.html \
|
|||
test_volume.html \
|
||||
test_wav_8bit.html \
|
||||
test_wav_ended1.html \
|
||||
test_wav_seek3.html \
|
||||
test_wav_seek4.html \
|
||||
test_wav_seek5.html \
|
||||
test_wav_seek6.html \
|
||||
test_wav_seek7.html \
|
||||
test_wav_seek8.html \
|
||||
test_wav_seek_past_end.html \
|
||||
test_wav_seek_then_play.html \
|
||||
test_wav_trailing.html \
|
||||
test_wav_trunc.html \
|
||||
test_wav_trunc_seek.html \
|
||||
320x240.ogg \
|
||||
bug461281.ogg \
|
||||
seek.ogg \
|
||||
r11025_s16_c1.wav \
|
||||
r11025_s16_c1_trailing.wav \
|
||||
r11025_s16_c1_trunc.wav \
|
||||
r11025_u8_c1.wav \
|
||||
# test_bug448534.html \
|
||||
$(NULL)
|
||||
|
|
Двоичный файл не отображается.
Двоичный файл не отображается.
|
@ -22,9 +22,10 @@ var seekFlagEnd = false;
|
|||
var readonly = true;
|
||||
var completed = false;
|
||||
|
||||
ok(!document.getElementById('v').seeking, "seeking should default to false");
|
||||
var v = document.getElementById('v');
|
||||
ok(!v.seeking, "seeking should default to false");
|
||||
try {
|
||||
v1.seeking = 1;
|
||||
v.seeking = 1;
|
||||
readonly = false;
|
||||
}
|
||||
catch(e) {
|
||||
|
|
|
@ -45,7 +45,7 @@ function startTest() {
|
|||
completed = true;
|
||||
ok(thrown1, "Setting currentTime to invalid value of NaN");
|
||||
ok(thrown2, "Setting currentTime to invalid value of -1");
|
||||
ok(thrown2, "Setting currentTime to invalid value of a function");
|
||||
ok(thrown3, "Setting currentTime to invalid value of a function");
|
||||
SimpleTest.finish();
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Wave Media test: seek test 3</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<audio id='v'
|
||||
onloadedmetadata='return startTest();'
|
||||
onended='return playbackEnded();'
|
||||
onseeking='return seekStarted();'
|
||||
onseeked='return seekEnded();'>
|
||||
<source type='audio/x-wav' src='r11025_s16_c1.wav'>
|
||||
</audio>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
// Test seeking works if current time is set before audio is
|
||||
// playing.
|
||||
var startPassed = false;
|
||||
var endPassed = false;
|
||||
var completed = false;
|
||||
|
||||
function startTest() {
|
||||
if (completed)
|
||||
return false;
|
||||
|
||||
var v = document.getElementById('v');
|
||||
v.currentTime=0.5;
|
||||
v.play();
|
||||
return false;
|
||||
}
|
||||
|
||||
function seekStarted() {
|
||||
if (completed)
|
||||
return false;
|
||||
|
||||
startPassed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
function seekEnded() {
|
||||
if (completed)
|
||||
return false;
|
||||
|
||||
var t = document.getElementById('v').currentTime;
|
||||
ok(t >= 0.4 && t <= 0.6, "Video currentTime should be around 0.5: " + t);
|
||||
endPassed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
function playbackEnded() {
|
||||
if (completed)
|
||||
return false
|
||||
|
||||
completed = true;
|
||||
ok(startPassed, "send seeking event");
|
||||
ok(endPassed, "send seeked event");
|
||||
SimpleTest.finish();
|
||||
return false;
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,54 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Wave Media test: seek test 4</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<audio id='v'
|
||||
onloadedmetadata='return startTest();'
|
||||
onseeking='return seekStarted();'
|
||||
onseeked='return seekEnded();'>
|
||||
<source type='audio/x-wav' src='r11025_s16_c1.wav'>
|
||||
</audio>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
// Test seeking works if current time is set but audio is not played.
|
||||
var startPassed = false;
|
||||
var completed = false;
|
||||
|
||||
function startTest() {
|
||||
if (completed)
|
||||
return false;
|
||||
|
||||
var v = document.getElementById('v');
|
||||
v.currentTime=0.5;
|
||||
return false;
|
||||
}
|
||||
|
||||
function seekStarted() {
|
||||
if (completed)
|
||||
return false;
|
||||
|
||||
startPassed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
function seekEnded() {
|
||||
if (completed)
|
||||
return false;
|
||||
|
||||
var t = document.getElementById('v').currentTime;
|
||||
ok(t >= 0.4 && t<= 0.6, "Video currentTime should be around 0.5: " + t);
|
||||
completed = true;
|
||||
SimpleTest.finish();
|
||||
return false;
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,71 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Wave Media test: seek test 5</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<audio id='v'
|
||||
onloadedmetadata='return startTest();'
|
||||
onseeking='return seekStarted();'
|
||||
onseeked='return seekEnded();'>
|
||||
<source type='audio/x-wav' src='r11025_s16_c1.wav'>
|
||||
</audio>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
// Test for a seek, followed by another seek before the first is complete.
|
||||
var startPassed = false;
|
||||
var seek1Passed = false;
|
||||
var seek2Passed = false;
|
||||
var seekCount = 0;
|
||||
var completed = false;
|
||||
|
||||
function startTest() {
|
||||
if (completed)
|
||||
return false;
|
||||
|
||||
var v = document.getElementById('v');
|
||||
v.currentTime=0.8;
|
||||
return false;
|
||||
}
|
||||
|
||||
function seekStarted() {
|
||||
if (completed)
|
||||
return false;
|
||||
|
||||
startPassed = true;
|
||||
var v = document.getElementById('v');
|
||||
v.currentTime=0.5;
|
||||
return false;
|
||||
}
|
||||
|
||||
function seekEnded() {
|
||||
if (completed)
|
||||
return false;
|
||||
var v = document.getElementById('v');
|
||||
seekCount++;
|
||||
if(seekCount == 1) {
|
||||
if (v.currentTime >= 0.7 && v.currentTime <= 0.9)
|
||||
seek1Passed = true;
|
||||
}
|
||||
|
||||
if(seekCount == 2) {
|
||||
if (v.currentTime >= 0.4 && v.currentTime <= 0.6)
|
||||
seek2Passed = true;
|
||||
|
||||
ok(seek1Passed, "First seek");
|
||||
ok(seek2Passed, "Second seek");
|
||||
completed = true;
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,63 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Wave Media test: seek test 6</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<audio id='v'
|
||||
onloadedmetadata='return startTest();'
|
||||
onended='return playbackEnded();'
|
||||
onseeking='return seekStarted();'
|
||||
onseeked='return seekEnded();'>
|
||||
<source type='audio/x-wav' src='r11025_s16_c1.wav'>
|
||||
</audio>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
// Test for a seek, followed by a play before the seek completes, ensure we play at the end of the seek.
|
||||
var startPassed = false;
|
||||
var completed = false;
|
||||
var seekCount = 0;
|
||||
|
||||
function startTest() {
|
||||
if (completed)
|
||||
return false;
|
||||
|
||||
var v = document.getElementById('v');
|
||||
v.currentTime=0.5;
|
||||
return false;
|
||||
}
|
||||
|
||||
function seekStarted() {
|
||||
if (completed)
|
||||
return false;
|
||||
startPassed = true;
|
||||
var v = document.getElementById('v');
|
||||
v.play();
|
||||
return false;
|
||||
}
|
||||
|
||||
function seekEnded() {
|
||||
if (completed)
|
||||
return false;
|
||||
var v = document.getElementById('v');
|
||||
ok(v.currentTime>=0.4 && v.currentTime<=0.6, "First seek");
|
||||
return false;
|
||||
}
|
||||
|
||||
function playbackEnded() {
|
||||
if (completed)
|
||||
return false;
|
||||
ok(true, "Playback ended");
|
||||
completed = true;
|
||||
SimpleTest.finish();
|
||||
return false;
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,60 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Wave Media test: seek test 7</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<audio id='v'
|
||||
onloadedmetadata='return startTest();'
|
||||
onseeked='return seekEnded();'>
|
||||
<source type='audio/x-wav' src='r11025_s16_c1.wav'>
|
||||
</audio>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript;version=1.7">
|
||||
// Test for bug identified by Chris Pearce in comment 40 on
|
||||
// bug 449159.
|
||||
var v = document.getElementById('v');
|
||||
var seekCount = 0;
|
||||
var completed = false;
|
||||
var interval;
|
||||
|
||||
function startTest() {
|
||||
if (completed)
|
||||
return false;
|
||||
|
||||
var seek = function () {
|
||||
var i = 0;
|
||||
for (;;) {
|
||||
i += 0.1;
|
||||
if (i > 1)
|
||||
i = 0;
|
||||
yield i;
|
||||
}
|
||||
}();
|
||||
|
||||
interval = setInterval(function() { v.currentTime=seek.next(); }, 10);
|
||||
return false;
|
||||
}
|
||||
|
||||
function seekEnded() {
|
||||
if (completed)
|
||||
return false;
|
||||
|
||||
seekCount++;
|
||||
ok(true, "Seek " + seekCount);
|
||||
if (seekCount == 3) {
|
||||
clearInterval(interval);
|
||||
completed = true;
|
||||
SimpleTest.finish();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,58 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Wave Media test: seek test 8</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<audio id='v'
|
||||
onloadedmetadata='return startTest();'>
|
||||
<source type='audio/x-wav' src='r11025_s16_c1.wav'>
|
||||
</audio>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
// If a NaN is passed to currentTime, make sure this is caught
|
||||
// otherwise an infinite loop in the Wave backend occurs.
|
||||
var v = document.getElementById('v');
|
||||
var completed = false;
|
||||
var thrown1 = false;
|
||||
var thrown2 = false;
|
||||
var thrown3 = false;
|
||||
|
||||
function startTest() {
|
||||
if (completed)
|
||||
return false;
|
||||
|
||||
try {
|
||||
v.currentTime = NaN;
|
||||
} catch(e) {
|
||||
thrown1 = true;
|
||||
}
|
||||
|
||||
try {
|
||||
v.currentTime = -1;
|
||||
} catch(e) {
|
||||
thrown2 = true;
|
||||
}
|
||||
|
||||
try {
|
||||
v.currentTime = Math.random;
|
||||
} catch(e) {
|
||||
thrown3 = true;
|
||||
}
|
||||
|
||||
completed = true;
|
||||
ok(thrown1, "Setting currentTime to invalid value of NaN");
|
||||
ok(thrown2, "Setting currentTime to invalid value of -1");
|
||||
ok(thrown3, "Setting currentTime to invalid value of a function");
|
||||
SimpleTest.finish();
|
||||
return false;
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,46 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Wave Media test: playback ends when file has trailing non-PCM data</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<audio id='v'
|
||||
onloadedmetadata='return startTest();'
|
||||
onended='return playbackEnded();'>
|
||||
<source type='audio/x-wav' src='r11025_s16_c1_trailing.wav'>
|
||||
</audio>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
// Test if the ended event works correctly.
|
||||
var v = document.getElementById('v');
|
||||
var endPassed = false;
|
||||
var completed = false;
|
||||
|
||||
function startTest() {
|
||||
if (completed)
|
||||
return false;
|
||||
|
||||
v.play();
|
||||
return false;
|
||||
}
|
||||
|
||||
function playbackEnded() {
|
||||
if (completed)
|
||||
return false
|
||||
|
||||
completed = true;
|
||||
ok(v.currentTime >= 0.9 && v.currentTime <= 1.1,
|
||||
"Checking currentTime at end: " + v.currentTime);
|
||||
ok(v.ended, "Checking playback has ended");
|
||||
SimpleTest.finish();
|
||||
return false;
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,48 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Wave Media test: playback ends when file is truncated</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<audio id='v'
|
||||
onloadedmetadata='return startTest();'
|
||||
onended='return playbackEnded();'>
|
||||
<source type='audio/x-wav' src='r11025_s16_c1_trunc.wav'>
|
||||
</audio>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
// Test if the ended event works correctly.
|
||||
var v = document.getElementById('v');
|
||||
var endPassed = false;
|
||||
var completed = false;
|
||||
|
||||
function startTest() {
|
||||
if (completed)
|
||||
return false;
|
||||
|
||||
ok(v.duration > 0.3 && v.duration < 0.5, "Duration should be around 0.4: " + v.duration);
|
||||
|
||||
v.play();
|
||||
return false;
|
||||
}
|
||||
|
||||
function playbackEnded() {
|
||||
if (completed)
|
||||
return false
|
||||
|
||||
completed = true;
|
||||
ok(v.currentTime >= 0.3 && v.currentTime <= 0.5,
|
||||
"Checking currentTime at end: " + v.currentTime);
|
||||
ok(v.ended, "Checking playback has ended");
|
||||
SimpleTest.finish();
|
||||
return false;
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,54 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Wave Media test: seeking in truncated file</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<audio id='v'
|
||||
onloadedmetadata='return startTest();'
|
||||
onseeked='return endSeek();'
|
||||
onended='return endTest();'>
|
||||
<source type='audio/x-wav' src='r11025_s16_c1_trunc.wav'>
|
||||
</audio>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
// Test if the ended event works correctly.
|
||||
var v = document.getElementById('v');
|
||||
var endPassed = false;
|
||||
var completed = false;
|
||||
|
||||
function startTest() {
|
||||
if (completed)
|
||||
return false;
|
||||
|
||||
ok(v.duration > 0.3 && v.duration < 0.5, "Duration should be around 0.4: " + v.duration);
|
||||
|
||||
v.currentTime = 1.0;
|
||||
return false;
|
||||
}
|
||||
|
||||
function endTest() {
|
||||
ok(v.ended, "Checking ended set after seeking to EOF and playing");
|
||||
SimpleTest.finish();
|
||||
return false;
|
||||
}
|
||||
|
||||
function endSeek() {
|
||||
if (completed)
|
||||
return false
|
||||
|
||||
completed = true;
|
||||
ok(v.currentTime >= 0.3 && v.currentTime <= 0.5,
|
||||
"Checking currentTime at end: " + v.currentTime);
|
||||
v.play();
|
||||
return false;
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
Загрузка…
Ссылка в новой задаче