mirror of
https://github.com/shaka-project/shaka-player.git
synced 2026-06-17 16:26:39 +03:00
7cd09c266a
This removed any goog.require from the test code to make it simpler. Now, shaka-player.uncompiled is required to be loaded before any tests. This fixes some dependency problems. This also moves the utility test code to test/util. Change-Id: I8991a61fc59c9c03e0143bb0883fd6d166af86c2
302 lines
9.9 KiB
JavaScript
302 lines
9.9 KiB
JavaScript
/**
|
|
* @license
|
|
* Copyright 2015 Google Inc.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
describe('MediaSourceEngine', function() {
|
|
var metadata = {
|
|
video: {
|
|
initSegmentUri: 'test/assets/sintel-video-init.mp4',
|
|
mvhdOffset: 0x24,
|
|
segmentUri: 'test/assets/sintel-video-segment.mp4',
|
|
tfdtOffset: 0x34,
|
|
segmentDuration: 12,
|
|
presentationTimeOffset: 0,
|
|
mimeType: 'video/mp4; codecs="avc1.42c01e"',
|
|
generator: null
|
|
},
|
|
audio: {
|
|
initSegmentUri: 'test/assets/sintel-audio-init.mp4',
|
|
mvhdOffset: 0x20,
|
|
segmentUri: 'test/assets/sintel-audio-segment.mp4',
|
|
tfdtOffset: 0x38,
|
|
segmentDuration: 10.005333,
|
|
presentationTimeOffset: 0,
|
|
mimeType: 'audio/mp4; codecs="mp4a.40.2"',
|
|
generator: null
|
|
}
|
|
};
|
|
var presentationDuration = 840;
|
|
|
|
var originalTimeout;
|
|
var video;
|
|
var mediaSource;
|
|
var mediaSourceEngine;
|
|
|
|
function createStreamGenerator(type, metadata) {
|
|
var generator = new shaka.test.DashVodStreamGenerator(
|
|
metadata.initSegmentUri, metadata.mvhdOffset,
|
|
metadata.segmentUri, metadata.tfdtOffset, metadata.segmentDuration,
|
|
metadata.presentationTimeOffset, presentationDuration);
|
|
metadata.generator = generator;
|
|
return generator.init();
|
|
}
|
|
|
|
beforeAll(function(done) {
|
|
video = /** @type {HTMLVideoElement} */ (document.createElement('video'));
|
|
video.width = 600;
|
|
video.height = 400;
|
|
document.body.appendChild(video);
|
|
|
|
originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
|
|
jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000; // ms
|
|
|
|
Promise.all([
|
|
createStreamGenerator('video', metadata.video),
|
|
createStreamGenerator('audio', metadata.audio)
|
|
]).catch(fail).then(done);
|
|
});
|
|
|
|
beforeEach(function(done) {
|
|
mediaSource = new MediaSource();
|
|
video.src = window.URL.createObjectURL(mediaSource);
|
|
|
|
var onMediaSourceOpen = function() {
|
|
mediaSource.removeEventListener('sourceopen', onMediaSourceOpen);
|
|
mediaSource.duration = 0;
|
|
mediaSourceEngine = new shaka.media.MediaSourceEngine(mediaSource, null);
|
|
done();
|
|
};
|
|
mediaSource.addEventListener('sourceopen', onMediaSourceOpen);
|
|
});
|
|
|
|
afterEach(function(done) {
|
|
mediaSourceEngine.destroy().then(function() {
|
|
video.src = '';
|
|
done();
|
|
});
|
|
});
|
|
|
|
afterAll(function() {
|
|
document.body.removeChild(video);
|
|
jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout;
|
|
});
|
|
|
|
function appendInit(type) {
|
|
var segment = metadata[type].generator.getInitSegment(Date.now() / 1000);
|
|
return mediaSourceEngine.appendBuffer(type, segment);
|
|
}
|
|
|
|
function append(type, segmentNumber) {
|
|
var segment = metadata[type].generator.
|
|
getSegment(segmentNumber, Date.now() / 1000);
|
|
return mediaSourceEngine.appendBuffer(type, segment);
|
|
}
|
|
|
|
function buffered(type, time) {
|
|
return mediaSourceEngine.bufferedAheadOf(type, time);
|
|
}
|
|
|
|
function remove(type, segmentNumber) {
|
|
var start = (segmentNumber - 1) * metadata[type].segmentDuration;
|
|
var end = segmentNumber * metadata[type].segmentDuration;
|
|
return mediaSourceEngine.remove(type, start, end);
|
|
}
|
|
|
|
it('buffers MP4 video', function(done) {
|
|
mediaSourceEngine.init({'video': metadata.video.mimeType});
|
|
mediaSourceEngine.setDuration(presentationDuration).then(function() {
|
|
return appendInit('video');
|
|
}).then(function() {
|
|
expect(buffered('video', 0)).toBe(0);
|
|
return append('video', 1);
|
|
}).then(function() {
|
|
expect(buffered('video', 0)).toBeCloseTo(12);
|
|
return append('video', 2);
|
|
}).then(function() {
|
|
expect(buffered('video', 0)).toBeCloseTo(24);
|
|
return append('video', 3);
|
|
}).then(function() {
|
|
expect(buffered('video', 0)).toBeCloseTo(36);
|
|
}).catch(fail).then(done);
|
|
});
|
|
|
|
it('removes segments', function(done) {
|
|
mediaSourceEngine.init({'video': metadata.video.mimeType});
|
|
mediaSourceEngine.setDuration(presentationDuration).then(function() {
|
|
return appendInit('video');
|
|
}).then(function() {
|
|
return Promise.all([
|
|
append('video', 1),
|
|
append('video', 2),
|
|
append('video', 3)
|
|
]);
|
|
}).then(function() {
|
|
expect(buffered('video', 0)).toBeCloseTo(36);
|
|
return remove('video', 1);
|
|
}).then(function() {
|
|
expect(buffered('video', 0)).toBe(0);
|
|
expect(buffered('video', 12)).toBeCloseTo(24);
|
|
return remove('video', 2);
|
|
}).then(function() {
|
|
expect(buffered('video', 0)).toBe(0);
|
|
expect(buffered('video', 12)).toBe(0);
|
|
expect(buffered('video', 24)).toBeCloseTo(12);
|
|
return remove('video', 3);
|
|
}).then(function() {
|
|
expect(buffered('video', 24)).toBe(0);
|
|
}).catch(fail).then(done);
|
|
});
|
|
|
|
it('extends the duration', function(done) {
|
|
mediaSourceEngine.init({'video': metadata.video.mimeType});
|
|
appendInit('video').then(function() {
|
|
return mediaSourceEngine.setDuration(20);
|
|
}).then(function() {
|
|
expect(mediaSource.duration).toBeCloseTo(20);
|
|
return append('video', 1);
|
|
}).then(function() {
|
|
expect(mediaSource.duration).toBeCloseTo(20);
|
|
return mediaSourceEngine.setDuration(40);
|
|
}).then(function() {
|
|
expect(mediaSource.duration).toBeCloseTo(40);
|
|
return Promise.all([
|
|
append('video', 2),
|
|
append('video', 3),
|
|
append('video', 4)
|
|
]);
|
|
}).then(function() {
|
|
expect(mediaSource.duration).toBeCloseTo(48);
|
|
return mediaSourceEngine.setDuration(60);
|
|
}).then(function() {
|
|
expect(mediaSource.duration).toBeCloseTo(60);
|
|
}).catch(fail).then(done);
|
|
});
|
|
|
|
it('ends the stream, truncating the duration', function(done) {
|
|
mediaSourceEngine.init({'video': metadata.video.mimeType});
|
|
mediaSourceEngine.setDuration(presentationDuration).then(function() {
|
|
return appendInit('video');
|
|
}).then(function() {
|
|
return append('video', 1);
|
|
}).then(function() {
|
|
return append('video', 2);
|
|
}).then(function() {
|
|
return append('video', 3);
|
|
}).then(function() {
|
|
return mediaSourceEngine.endOfStream();
|
|
}).then(function() {
|
|
expect(mediaSource.duration).toBeCloseTo(36);
|
|
}).catch(fail).then(done);
|
|
});
|
|
|
|
it('queues operations', function(done) {
|
|
var resolutionOrder = [];
|
|
var requests = [];
|
|
|
|
function checkOrder(p) {
|
|
var nextIndex = requests.length;
|
|
requests.push(p);
|
|
p.then(function() { resolutionOrder.push(nextIndex); });
|
|
}
|
|
|
|
mediaSourceEngine.init({'video': metadata.video.mimeType});
|
|
checkOrder(mediaSourceEngine.setDuration(presentationDuration));
|
|
checkOrder(appendInit('video'));
|
|
checkOrder(append('video', 1));
|
|
checkOrder(append('video', 2));
|
|
checkOrder(append('video', 3));
|
|
checkOrder(mediaSourceEngine.endOfStream());
|
|
|
|
Promise.all(requests).then(function() {
|
|
expect(resolutionOrder).toEqual([0, 1, 2, 3, 4, 5]);
|
|
}).catch(fail).then(done);
|
|
});
|
|
|
|
it('buffers MP4 audio', function(done) {
|
|
mediaSourceEngine.init({'audio': metadata.audio.mimeType});
|
|
mediaSourceEngine.setDuration(presentationDuration).then(function() {
|
|
// NOTE: For some reason, this appendInit never resolves on my Windows VM.
|
|
// The test operates correctly on real hardware.
|
|
return appendInit('audio');
|
|
}).then(function() {
|
|
expect(buffered('audio', 0)).toBe(0);
|
|
return append('audio', 1);
|
|
}).then(function() {
|
|
expect(buffered('audio', 0)).toBeCloseTo(10.005333);
|
|
return append('audio', 2);
|
|
}).then(function() {
|
|
expect(buffered('audio', 0)).toBeCloseTo(20.010666);
|
|
return append('audio', 3);
|
|
}).then(function() {
|
|
expect(buffered('audio', 0)).toBeCloseTo(30.015999);
|
|
}).catch(fail).then(done);
|
|
});
|
|
|
|
it('buffers MP4 video and audio', function(done) {
|
|
mediaSourceEngine.init({
|
|
'video': metadata.video.mimeType,
|
|
'audio': metadata.audio.mimeType
|
|
});
|
|
|
|
mediaSourceEngine.setDuration(presentationDuration).catch(fail);
|
|
|
|
var audioStreaming = appendInit('audio').then(function() {
|
|
return append('audio', 1);
|
|
}).then(function() {
|
|
expect(buffered('audio', 0)).toBeCloseTo(10.005333);
|
|
return append('audio', 2);
|
|
}).then(function() {
|
|
expect(buffered('audio', 0)).toBeCloseTo(20.010666);
|
|
return append('audio', 3);
|
|
}).then(function() {
|
|
expect(buffered('audio', 0)).toBeCloseTo(30.015999);
|
|
return append('audio', 4);
|
|
}).then(function() {
|
|
expect(buffered('audio', 0)).toBeCloseTo(40.021333);
|
|
return append('audio', 5);
|
|
}).then(function() {
|
|
expect(buffered('audio', 0)).toBeCloseTo(50.026666);
|
|
return append('audio', 6);
|
|
}).then(function() {
|
|
expect(buffered('audio', 0)).toBeCloseTo(60.031999);
|
|
}).catch(fail);
|
|
|
|
var videoStreaming = appendInit('video').then(function() {
|
|
return append('video', 1);
|
|
}).then(function() {
|
|
expect(buffered('video', 0)).toBeCloseTo(12);
|
|
return append('video', 2);
|
|
}).then(function() {
|
|
expect(buffered('video', 0)).toBeCloseTo(24);
|
|
return append('video', 3);
|
|
}).then(function() {
|
|
expect(buffered('video', 0)).toBeCloseTo(36);
|
|
return append('video', 4);
|
|
}).then(function() {
|
|
expect(buffered('video', 0)).toBeCloseTo(48);
|
|
return append('video', 5);
|
|
}).then(function() {
|
|
expect(buffered('video', 0)).toBeCloseTo(60);
|
|
}).catch(fail);
|
|
|
|
Promise.all([audioStreaming, videoStreaming]).then(function() {
|
|
return mediaSourceEngine.endOfStream();
|
|
}).then(function() {
|
|
expect(mediaSource.duration).toBeCloseTo(60.031999);
|
|
}).catch(fail).then(done);
|
|
});
|
|
});
|