4 <script src=
"/w3c/resources/testharness.js"></script>
5 <script src=
"/w3c/resources/testharnessreport.js"></script>
6 <script src=
"mediasource-util.js"></script>
7 <link rel=
"stylesheet" href=
"/w3c/resources/testharness.css">
12 var subType
= MediaSourceUtil
.getSubType(MediaSourceUtil
.AUDIO_ONLY_TYPE
);
14 var manifestFilenameA
= subType
+ '/test-a-128k-44100Hz-1ch-manifest.json';
15 var manifestFilenameB
= subType
+ '/test-v-128k-320x240-30fps-10kfr-manifest.json';
18 webm
: '{ [0.000, 2.022) }',
19 mp4
: '{ [0.000, 2.043) }',
23 webm
: '{ [0.000, 2.000) }',
24 mp4
: '{ [0.000, 2.000) }',
27 function mediaSourceDemuxedTest(callback
, description
)
29 mediasource_test(function(test
, mediaElement
, mediaSource
)
32 test
.failOnEvent(mediaElement
, 'error');
33 test
.endOnEvent(mediaElement
, 'ended');
35 MediaSourceUtil
.fetchManifestAndData(test
, manifestFilenameA
, function(typeA
, dataA
)
37 MediaSourceUtil
.fetchManifestAndData(test
, manifestFilenameB
, function(typeB
, dataB
)
39 mediaSource
.addSourceBuffer(typeA
);
40 mediaSource
.addSourceBuffer(typeB
);
41 assert_equals(mediaSource
.sourceBuffers
.length
, 2);
43 callback(test
, mediaElement
, mediaSource
, dataA
, dataB
);
49 function appendDataAndVerifyAddedToActiveSourceBuffers(test
, mediaSource
, dataA
, dataB
, swapAppendBufferOrder
, forceParsingOrder
, callback
)
51 // Verification here assumes no prior initialization segment received for any of mediaSource's sourceBuffers.
52 assert_equals(mediaSource
.sourceBuffers
.length
, 2, 'mediaSource sourceBuffers length before appends');
53 assert_equals(mediaSource
.activeSourceBuffers
.length
, 0, 'mediaSource activeSourceBuffers length before appends');
54 var sourceBufferA
= mediaSource
.sourceBuffers
[0];
55 var sourceBufferB
= mediaSource
.sourceBuffers
[1];
57 var firstBuffer
= swapAppendBufferOrder
? sourceBufferB
: sourceBufferA
;
58 var firstData
= swapAppendBufferOrder
? dataB
: dataA
;
59 var secondBuffer
= swapAppendBufferOrder
? sourceBufferA
: sourceBufferB
;
60 var secondData
= swapAppendBufferOrder
? dataA
: dataB
;
62 test
.expectEvent(firstBuffer
, 'update');
63 test
.expectEvent(firstBuffer
, 'updateend');
64 firstBuffer
.appendBuffer(firstData
);
66 var doSecondAppend = function()
68 test
.expectEvent(secondBuffer
, 'update');
69 test
.expectEvent(secondBuffer
, 'updateend');
70 secondBuffer
.appendBuffer(secondData
);
73 if (forceParsingOrder
) {
74 test
.waitForExpectedEvents(function()
76 assert_equals(mediaSource
.sourceBuffers
.length
, 2, 'mediaSource sourceBuffers length between completed appends');
77 assert_equals(mediaSource
.activeSourceBuffers
.length
, 1, 'mediaSource activeSourceBuffers length between completed appends');
78 assert_equals(mediaSource
.activeSourceBuffers
[0], firstBuffer
);
85 test
.waitForExpectedEvents(function()
87 assert_equals(mediaSource
.sourceBuffers
.length
, 2, 'mediaSource sourceBuffers length after appends completed');
88 assert_equals(mediaSource
.activeSourceBuffers
.length
, 2, 'mediaSource activeSourceBuffers length after appends completed');
89 assert_equals(mediaSource
.activeSourceBuffers
[0], sourceBufferA
);
90 assert_equals(mediaSource
.activeSourceBuffers
[1], sourceBufferB
);
95 mediaSourceDemuxedTest(function(test
, mediaElement
, mediaSource
, dataA
, dataB
) {
96 appendDataAndVerifyAddedToActiveSourceBuffers(test
, mediaSource
, dataA
, dataB
, false, false, function()
98 assertBufferedEquals(mediaSource
.activeSourceBuffers
[0], expectationsA
[subType
], 'mediaSource.activeSourceBuffers[0]');
99 assertBufferedEquals(mediaSource
.activeSourceBuffers
[1], expectationsB
[subType
], 'mediaSource.activeSourceBuffers[1]');
100 assertBufferedEquals(mediaElement
, expectationsB
[subType
], 'mediaElement.buffered');
102 mediaSource
.endOfStream();
104 assertBufferedEquals(mediaSource
.activeSourceBuffers
[0], expectationsA
[subType
], 'mediaSource.activeSourceBuffers[0]');
105 assertBufferedEquals(mediaSource
.activeSourceBuffers
[1], expectationsB
[subType
], 'mediaSource.activeSourceBuffers[1]');
106 assertBufferedEquals(mediaElement
, expectationsA
[subType
], 'mediaElement.buffered');
110 }, 'Demuxed content with different lengths');
112 mediaSourceDemuxedTest(function(test
, mediaElement
, mediaSource
, dataA
, dataB
) {
113 appendDataAndVerifyAddedToActiveSourceBuffers(test
, mediaSource
, dataA
, dataB
, false, true, function()
115 assertBufferedEquals(mediaSource
.activeSourceBuffers
[0], expectationsA
[subType
], 'mediaSource.activeSourceBuffers[0]');
116 assertBufferedEquals(mediaSource
.activeSourceBuffers
[1], expectationsB
[subType
], 'mediaSource.activeSourceBuffers[1]');
117 assertBufferedEquals(mediaElement
, expectationsB
[subType
], 'mediaElement.buffered');
120 }, 'Process first init segment for sourceBuffer[0] first');
122 mediaSourceDemuxedTest(function(test
, mediaElement
, mediaSource
, dataA
, dataB
) {
123 appendDataAndVerifyAddedToActiveSourceBuffers(test
, mediaSource
, dataA
, dataB
, true, true, function()
125 assertBufferedEquals(mediaSource
.activeSourceBuffers
[0], expectationsA
[subType
], 'mediaSource.activeSourceBuffers[0]');
126 assertBufferedEquals(mediaSource
.activeSourceBuffers
[1], expectationsB
[subType
], 'mediaSource.activeSourceBuffers[1]');
127 assertBufferedEquals(mediaElement
, expectationsB
[subType
], 'mediaElement.buffered');
130 }, 'Process first init segment for sourceBuffer[1] first');
132 mediasource_test(function(test
, mediaElement
, mediaSource
)
134 mediaElement
.pause();
135 test
.failOnEvent(mediaElement
, 'error');
136 test
.endOnEvent(mediaElement
, 'ended');
138 MediaSourceUtil
.fetchManifestAndData(test
, subType
+ '/test-av-384k-44100Hz-1ch-320x240-30fps-10kfr-manifest.json', function(type
, data
)
140 var sourceBuffer
= mediaSource
.addSourceBuffer(type
);
141 test
.expectEvent(sourceBuffer
, 'update');
142 test
.expectEvent(sourceBuffer
, 'updateend');
143 sourceBuffer
.appendBuffer(data
);
145 test
.waitForExpectedEvents(function()
147 var expectationsAV
= {
148 webm
: ['{ [0.000, 2.003) }', '{ [0.000, 2.022) }'],
149 mp4
: ['{ [0.000, 2.000) }', '{ [0.000, 2.043) }'],
152 var expectedBeforeEndOfStream
= expectationsAV
[subType
][0];
153 var expectedAfterEndOfStream
= expectationsAV
[subType
][1];
155 assertBufferedEquals(mediaSource
.activeSourceBuffers
[0], expectedBeforeEndOfStream
, 'mediaSource.activeSourceBuffers[0]');
156 assertBufferedEquals(mediaElement
, expectedBeforeEndOfStream
, 'mediaElement.buffered');
158 mediaSource
.endOfStream();
160 assertBufferedEquals(mediaSource
.activeSourceBuffers
[0], expectedAfterEndOfStream
, 'mediaSource.activeSourceBuffers[0]');
161 assertBufferedEquals(mediaElement
, expectedAfterEndOfStream
, 'mediaElement.buffered');
166 }, 'Muxed tracks with different lengths');
168 mediaSourceDemuxedTest(function(test
, mediaElement
, mediaSource
, dataA
, dataB
) {
169 appendDataAndVerifyAddedToActiveSourceBuffers(test
, mediaSource
, dataA
, dataB
.subarray(0, 318), false, false, function()
171 assertBufferedEquals(mediaSource
.activeSourceBuffers
[0], expectationsA
[subType
], 'mediaSource.activeSourceBuffers[0]');
172 assertBufferedEquals(mediaSource
.activeSourceBuffers
[1], '{ }', 'mediaSource.activeSourceBuffers[1]');
173 assertBufferedEquals(mediaElement
, '{ }', 'mediaElement.buffered');
175 mediaSource
.endOfStream();
177 assertBufferedEquals(mediaSource
.activeSourceBuffers
[0], expectationsA
[subType
], 'mediaSource.activeSourceBuffers[0]');
178 assertBufferedEquals(mediaSource
.activeSourceBuffers
[1], '{ }', 'mediaSource.activeSourceBuffers[1]');
179 assertBufferedEquals(mediaElement
, '{ }', 'mediaElement.buffered');
183 }, 'Demuxed content with an empty buffered range on one SourceBuffer');
185 mediasource_test(function(test
, mediaElement
, mediaSource
)
187 mediaElement
.pause();
188 test
.failOnEvent(mediaElement
, 'error');
189 test
.endOnEvent(mediaElement
, 'ended');
191 MediaSourceUtil
.fetchManifestAndData(test
, subType
+ '/test-av-384k-44100Hz-1ch-320x240-30fps-10kfr-manifest.json', function(type
, data
)
193 var sourceBuffer
= mediaSource
.addSourceBuffer(type
);
194 test
.expectEvent(sourceBuffer
, 'update');
195 test
.expectEvent(sourceBuffer
, 'updateend');
196 sourceBuffer
.appendBuffer(data
.subarray(0, 4052));
198 test
.waitForExpectedEvents(function()
200 assertBufferedEquals(mediaSource
.activeSourceBuffers
[0], '{ }', 'mediaSource.activeSourceBuffers[0]');
201 assertBufferedEquals(mediaElement
, '{ }', 'mediaElement.buffered');
203 mediaSource
.endOfStream();
205 assertBufferedEquals(mediaSource
.activeSourceBuffers
[0], '{ }', 'mediaSource.activeSourceBuffers[0]');
206 assertBufferedEquals(mediaElement
, '{ }', 'mediaElement.buffered');
211 }, 'Muxed content empty buffered ranges.');
213 mediasource_test(function(test
, mediaElement
, mediaSource
)
215 mediaElement
.pause();
216 test
.failOnEvent(mediaElement
, 'error');
217 test
.endOnEvent(mediaElement
, 'ended');
219 var sourceBuffer
= mediaSource
.addSourceBuffer(MediaSourceUtil
.AUDIO_ONLY_TYPE
);
221 assertBufferedEquals(mediaSource
.sourceBuffers
[0], '{ }', 'mediaSource.sourceBuffers[0]');
222 assertBufferedEquals(mediaElement
, '{ }', 'mediaElement.buffered');
225 }, 'Get buffered range when sourcebuffer is empty.');
227 mediasource_testafterdataloaded(function(test
, mediaElement
, mediaSource
, segmentInfo
, sourceBuffer
, mediaData
)
229 var initSegment
= MediaSourceUtil
.extractSegmentData(mediaData
, segmentInfo
.init
);
231 test
.expectEvent(sourceBuffer
, 'updateend', 'initSegment append ended.');
232 sourceBuffer
.appendBuffer(initSegment
);
233 test
.waitForExpectedEvents(function()
235 assertBufferedEquals(mediaSource
.sourceBuffers
[0], '{ }', 'mediaSource.sourceBuffers[0]');
236 assertBufferedEquals(mediaSource
.activeSourceBuffers
[0], '{ }', 'mediaSource.activeSourceBuffers[0]');
237 assertBufferedEquals(mediaElement
, '{ }', 'mediaElement.buffered');
241 }, 'Get buffered range when only initsegment is appended.');
243 mediasource_testafterdataloaded(function(test
, mediaElement
, mediaSource
, segmentInfo
, sourceBuffer
, mediaData
)
245 test
.expectEvent(mediaSource
.sourceBuffers
, 'removesourcebuffer', 'SourceBuffer removed.');
246 mediaSource
.removeSourceBuffer(sourceBuffer
);
248 test
.waitForExpectedEvents(function()
250 assert_throws('InvalidStateError',
251 function() { sourceBuffer
.buffered
; },
252 'get sourceBuffer.buffered throws an exception for InvalidStateError.');
255 }, 'Get buffered range after removing sourcebuffer.');