mirror of
https://github.com/shaka-project/shaka-player.git
synced 2026-06-15 16:06:41 +03:00
2a34eff924
This is a SourceBuffer-work-alike for text, based on registered parsers. Actual parsers are needed now. b/25323462 Change-Id: If2a3ce3d8a769e53d783304fe24519b8d98e093c
306 lines
9.7 KiB
JavaScript
306 lines
9.7 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.
|
|
*/
|
|
|
|
goog.require('shaka.media.TextSourceBuffer');
|
|
goog.require('shaka.util.EventManager');
|
|
|
|
describe('TextSourceBuffer', function() {
|
|
var TextSourceBuffer;
|
|
var dummyData = new ArrayBuffer();
|
|
var dummyMimeType = 'text/fake';
|
|
|
|
beforeAll(function() {
|
|
// Can't set this alias at load-time because the sources may not be loaded
|
|
// yet.
|
|
TextSourceBuffer = shaka.media.TextSourceBuffer;
|
|
});
|
|
|
|
describe('isTypeSupported', function() {
|
|
it('reports support only when a parser is installed', function() {
|
|
expect(TextSourceBuffer.isTypeSupported(dummyMimeType)).toBe(false);
|
|
TextSourceBuffer.registerParser(dummyMimeType, function() {});
|
|
expect(TextSourceBuffer.isTypeSupported(dummyMimeType)).toBe(true);
|
|
TextSourceBuffer.unregisterParser(dummyMimeType);
|
|
expect(TextSourceBuffer.isTypeSupported(dummyMimeType)).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe('appendBuffer', function() {
|
|
var mockParser;
|
|
var mockTrack;
|
|
var sourceBuffer;
|
|
var eventManager;
|
|
var onUpdateEnd;
|
|
|
|
beforeEach(function() {
|
|
mockParser = jasmine.createSpy('mockParser');
|
|
mockTrack = createMockTrack();
|
|
TextSourceBuffer.registerParser(dummyMimeType, mockParser);
|
|
sourceBuffer = new TextSourceBuffer(mockTrack, dummyMimeType);
|
|
onUpdateEnd = jasmine.createSpy('onUpdateEnd');
|
|
eventManager = new shaka.util.EventManager();
|
|
eventManager.listen(sourceBuffer, 'updateend', onUpdateEnd);
|
|
});
|
|
|
|
afterEach(function() {
|
|
sourceBuffer = null;
|
|
TextSourceBuffer.unregisterParser(dummyMimeType);
|
|
mockTrack = null;
|
|
mockParser = null;
|
|
eventManager.destroy();
|
|
eventManager = null;
|
|
});
|
|
|
|
it('works asynchronously', function() {
|
|
mockParser.and.returnValue([1, 2, 3]);
|
|
sourceBuffer.appendBuffer(dummyData);
|
|
expect(mockTrack.addCue).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('dispatches an "updateend" event', function(done) {
|
|
mockParser.and.returnValue([]);
|
|
|
|
expect(sourceBuffer.updating).toBe(false);
|
|
sourceBuffer.appendBuffer(dummyData);
|
|
expect(sourceBuffer.updating).toBe(true);
|
|
|
|
eventToPromise(onUpdateEnd).then(function() {
|
|
expect(sourceBuffer.updating).toBe(false);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('adds cues to the track', function() {
|
|
expect(mockParser).not.toHaveBeenCalled();
|
|
expect(mockTrack.addCue).not.toHaveBeenCalled();
|
|
expect(mockTrack.removeCue).not.toHaveBeenCalled();
|
|
|
|
mockParser.and.returnValue([1, 2, 3]);
|
|
sourceBuffer.appendBuffer(dummyData);
|
|
|
|
eventToPromise(onUpdateEnd).then(function() {
|
|
expect(mockParser).toHaveBeenCalledWith(dummyData);
|
|
expect(mockTrack.addCue).toHaveBeenCalledWith(1);
|
|
expect(mockTrack.addCue).toHaveBeenCalledWith(2);
|
|
expect(mockTrack.addCue).toHaveBeenCalledWith(3);
|
|
expect(mockTrack.removeCue).not.toHaveBeenCalled();
|
|
|
|
mockTrack.addCue.calls.reset();
|
|
mockParser.calls.reset();
|
|
|
|
mockParser.and.returnValue([4, 5]);
|
|
sourceBuffer.appendBuffer(dummyData);
|
|
|
|
return eventToPromise(onUpdateEnd);
|
|
}).then(function() {
|
|
expect(mockParser).toHaveBeenCalledWith(dummyData);
|
|
expect(mockTrack.addCue).toHaveBeenCalledWith(4);
|
|
expect(mockTrack.addCue).toHaveBeenCalledWith(5);
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('remove', function() {
|
|
var mockTrack;
|
|
var sourceBuffer;
|
|
var eventManager;
|
|
var onUpdateEnd;
|
|
|
|
beforeEach(function() {
|
|
mockTrack = createMockTrack();
|
|
TextSourceBuffer.registerParser(dummyMimeType, function() {});
|
|
sourceBuffer = new TextSourceBuffer(mockTrack, dummyMimeType);
|
|
onUpdateEnd = jasmine.createSpy('onUpdateEnd');
|
|
eventManager = new shaka.util.EventManager();
|
|
eventManager.listen(sourceBuffer, 'updateend', onUpdateEnd);
|
|
});
|
|
|
|
afterEach(function() {
|
|
sourceBuffer = null;
|
|
TextSourceBuffer.unregisterParser(dummyMimeType);
|
|
mockTrack = null;
|
|
mockParser = null;
|
|
eventManager.destroy();
|
|
eventManager = null;
|
|
});
|
|
|
|
it('works asynchronously', function() {
|
|
var cue1 = createFakeCue(0, 1);
|
|
var cue2 = createFakeCue(1, 2);
|
|
var cue3 = createFakeCue(2, 3);
|
|
mockTrack.cues = [cue1, cue2, cue3];
|
|
|
|
sourceBuffer.remove(0, 1);
|
|
expect(mockTrack.removeCue).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('dispatches an "updateend" event', function(done) {
|
|
expect(sourceBuffer.updating).toBe(false);
|
|
sourceBuffer.remove(0, 1);
|
|
expect(sourceBuffer.updating).toBe(true);
|
|
|
|
eventToPromise(onUpdateEnd).then(function() {
|
|
expect(sourceBuffer.updating).toBe(false);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('removes cues which overlap the range', function(done) {
|
|
var cue1 = createFakeCue(0, 1);
|
|
var cue2 = createFakeCue(1, 2);
|
|
var cue3 = createFakeCue(2, 3);
|
|
mockTrack.cues = [cue1, cue2, cue3];
|
|
|
|
sourceBuffer.remove(0, 1);
|
|
|
|
eventToPromise(onUpdateEnd).then(function() {
|
|
expect(mockTrack.removeCue.calls.allArgs()).toEqual([[cue1], [cue2]]);
|
|
|
|
mockTrack.removeCue.calls.reset();
|
|
sourceBuffer.remove(0.5, 0.9);
|
|
return eventToPromise(onUpdateEnd);
|
|
}).then(function() {
|
|
expect(mockTrack.removeCue.calls.allArgs()).toEqual([[cue1]]);
|
|
|
|
mockTrack.removeCue.calls.reset();
|
|
sourceBuffer.remove(3.00001, 5);
|
|
return eventToPromise(onUpdateEnd);
|
|
}).then(function() {
|
|
expect(mockTrack.removeCue).not.toHaveBeenCalled();
|
|
|
|
mockTrack.removeCue.calls.reset();
|
|
sourceBuffer.remove(0.5, 1.5);
|
|
return eventToPromise(onUpdateEnd);
|
|
}).then(function() {
|
|
expect(mockTrack.removeCue.calls.allArgs()).toEqual([[cue1], [cue2]]);
|
|
|
|
mockTrack.removeCue.calls.reset();
|
|
sourceBuffer.remove(3, Number.POSITIVE_INFINITY);
|
|
return eventToPromise(onUpdateEnd);
|
|
}).then(function() {
|
|
expect(mockTrack.removeCue.calls.allArgs()).toEqual([[cue3]]);
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('buffered', function() {
|
|
var mockTrack;
|
|
var sourceBuffer;
|
|
var eventManager;
|
|
var onUpdateEnd;
|
|
|
|
beforeEach(function() {
|
|
var fakeParser = function() { return []; };
|
|
mockTrack = createMockTrack();
|
|
TextSourceBuffer.registerParser(dummyMimeType, fakeParser);
|
|
sourceBuffer = new TextSourceBuffer(mockTrack, dummyMimeType);
|
|
onUpdateEnd = jasmine.createSpy('onUpdateEnd');
|
|
eventManager = new shaka.util.EventManager();
|
|
eventManager.listen(sourceBuffer, 'updateend', onUpdateEnd);
|
|
});
|
|
|
|
afterEach(function() {
|
|
sourceBuffer = null;
|
|
TextSourceBuffer.unregisterParser(dummyMimeType);
|
|
mockTrack = null;
|
|
eventManager.destroy();
|
|
eventManager = null;
|
|
});
|
|
|
|
it('reflects newly-added cues', function(done) {
|
|
expect(sourceBuffer.buffered.length).toBe(0);
|
|
|
|
var cue1 = createFakeCue(0, 1);
|
|
var cue2 = createFakeCue(1, 2);
|
|
mockTrack.cues = [cue1, cue2];
|
|
// call appendBuffer to trigger the update of buffered.
|
|
sourceBuffer.appendBuffer(dummyData);
|
|
|
|
eventToPromise(onUpdateEnd).then(function() {
|
|
expect(sourceBuffer.buffered.length).toBe(1);
|
|
expect(sourceBuffer.buffered.start(0)).toBe(0);
|
|
expect(sourceBuffer.buffered.end(0)).toBe(2);
|
|
|
|
var cue3 = createFakeCue(2, 3);
|
|
mockTrack.cues = [cue1, cue2, cue3];
|
|
sourceBuffer.appendBuffer(dummyData);
|
|
|
|
return eventToPromise(onUpdateEnd);
|
|
}).then(function() {
|
|
expect(sourceBuffer.buffered.length).toBe(1);
|
|
expect(sourceBuffer.buffered.start(0)).toBe(0);
|
|
expect(sourceBuffer.buffered.end(0)).toBe(3);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('reflects newly-removed cues', function(done) {
|
|
var cue1 = createFakeCue(0, 1);
|
|
var cue2 = createFakeCue(1, 2);
|
|
var cue3 = createFakeCue(2, 3);
|
|
mockTrack.cues = [cue1, cue2, cue3];
|
|
// call appendBuffer to trigger the update of buffered.
|
|
sourceBuffer.appendBuffer(dummyData);
|
|
|
|
eventToPromise(onUpdateEnd).then(function() {
|
|
expect(sourceBuffer.buffered.length).toBe(1);
|
|
expect(sourceBuffer.buffered.start(0)).toBe(0);
|
|
expect(sourceBuffer.buffered.end(0)).toBe(3);
|
|
|
|
mockTrack.cues = [cue1, cue2];
|
|
// call remove to trigger the update of buffered.
|
|
sourceBuffer.remove(-1, -1);
|
|
|
|
return eventToPromise(onUpdateEnd);
|
|
}).then(function() {
|
|
expect(sourceBuffer.buffered.length).toBe(1);
|
|
expect(sourceBuffer.buffered.start(0)).toBe(0);
|
|
expect(sourceBuffer.buffered.end(0)).toBe(2);
|
|
|
|
mockTrack.cues = [];
|
|
// call remove to trigger the update of buffered.
|
|
sourceBuffer.remove(-1, -1);
|
|
|
|
return eventToPromise(onUpdateEnd);
|
|
}).then(function() {
|
|
expect(sourceBuffer.buffered.length).toBe(0);
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
function eventToPromise(eventSpy) {
|
|
return new Promise(function(resolve) {
|
|
eventSpy.and.callFake(resolve);
|
|
});
|
|
}
|
|
|
|
function createMockTrack() {
|
|
return {
|
|
addCue: jasmine.createSpy('addCue'),
|
|
removeCue: jasmine.createSpy('removeCue'),
|
|
cues: []
|
|
};
|
|
}
|
|
|
|
function createFakeCue(startTime, endTime) {
|
|
return { startTime: startTime, endTime: endTime };
|
|
}
|
|
});
|