/** * @license * Copyright 2016 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('DashParser SegmentBase', function() { /** @const */ var Dash = shaka.test.Dash; /** @type {!shaka.test.FakeNetworkingEngine} */ var fakeNetEngine; /** @type {!shaka.dash.DashParser} */ var parser; /** @type {shakaExtern.ManifestParser.PlayerInterface} */ var playerInterface; /** @const {string} */ var indexSegmentUri = '/base/test/test/assets/index-segment.mp4'; /** @type {ArrayBuffer} */ var indexSegment; beforeAll(function(done) { shaka.test.Util.fetch(indexSegmentUri).then(function(data) { indexSegment = data; }).catch(fail).then(done); }); beforeEach(function() { fakeNetEngine = new shaka.test.FakeNetworkingEngine(); parser = shaka.test.Dash.makeDashParser(); playerInterface = { networkingEngine: fakeNetEngine, filterNewPeriod: function() {}, filterAllPeriods: function() {}, onTimelineRegionAdded: fail, // Should not have any EventStream elements. onEvent: fail, onError: fail }; }); it('requests init data for WebM', function(done) { var source = [ '', ' ', ' ', ' ', ' http://example.com', ' ', ' ', ' ', ' ', ' ', ' ', ''].join('\n'); fakeNetEngine.setResponseMapAsText({ 'dummy://foo': source, 'http://example.com': '', 'http://example.com/init.webm': '' }); parser.start('dummy://foo', playerInterface) .then(function(manifest) { expect(manifest).toEqual( Dash.makeManifestFromInit('init.webm', 201, 300)); return Dash.callCreateSegmentIndex(manifest); }) .then(function() { expect(fakeNetEngine.request.calls.count()).toBe(3); fakeNetEngine.expectRangeRequest('http://example.com', 100, 200); fakeNetEngine.expectRangeRequest( 'http://example.com/init.webm', 201, 300); }) .catch(fail) .then(done); }); it('inherits from Period', function(done) { var source = [ '', ' ', ' http://example.com', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ''].join('\n'); fakeNetEngine.setResponseMapAsText({ 'dummy://foo': source, 'http://example.com': '' }); parser.start('dummy://foo', playerInterface) .then(function(manifest) { expect(manifest).toEqual( Dash.makeManifestFromInit('init.mp4', 201, 300)); return Dash.callCreateSegmentIndex(manifest); }) .then(function() { expect(fakeNetEngine.request.calls.count()).toBe(2); fakeNetEngine.expectRangeRequest('http://example.com', 100, 200); }) .catch(fail) .then(done); }); it('inherits from AdaptationSet', function(done) { var source = [ '', ' ', ' ', ' http://example.com', ' ', ' ', ' ', ' ', ' ', ' ', ''].join('\n'); fakeNetEngine.setResponseMapAsText({ 'dummy://foo': source, 'http://example.com': '' }); parser.start('dummy://foo', playerInterface) .then(function(manifest) { expect(manifest).toEqual( Dash.makeManifestFromInit('init.mp4', 201, 300)); return Dash.callCreateSegmentIndex(manifest); }) .then(function() { expect(fakeNetEngine.request.calls.count()).toBe(2); fakeNetEngine.expectRangeRequest('http://example.com', 100, 200); }) .catch(fail) .then(done); }); it('does not require sourceURL in Initialization', function(done) { var source = [ '', ' ', ' ', ' ', ' http://example.com/stream.mp4', ' ', ' ', ' ', ' ', ' ', ' ', ''].join('\n'); fakeNetEngine.setResponseMapAsText({ 'dummy://foo': source, 'http://example.com/stream.mp4': '' }); parser.start('dummy://foo', playerInterface) .then(function(manifest) { expect(manifest).toEqual( Dash.makeManifestFromInit('stream.mp4', 201, 300)); return Dash.callCreateSegmentIndex(manifest); }) .then(function() { expect(fakeNetEngine.request.calls.count()).toBe(2); fakeNetEngine.expectRangeRequest( 'http://example.com/stream.mp4', 100, 200); }) .catch(fail) .then(done); }); it('merges across levels', function(done) { var source = [ '', ' ', ' http://example.com', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ''].join('\n'); fakeNetEngine.setResponseMapAsText({ 'dummy://foo': source, 'http://example.com/index.mp4': '' }); parser.start('dummy://foo', playerInterface) .then(function(manifest) { expect(manifest).toEqual( Dash.makeManifestFromInit('init.mp4', 201, 300, 10)); return Dash.callCreateSegmentIndex(manifest); }) .then(function() { expect(fakeNetEngine.request.calls.count()).toBe(2); fakeNetEngine.expectRangeRequest( 'http://example.com/index.mp4', 5, 2000); }) .catch(fail) .then(done); }); it('merges and overrides across levels', function(done) { var source = [ '', ' ', ' http://example.com', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ''].join('\n'); fakeNetEngine.setResponseMapAsText({ 'dummy://foo': source, 'http://example.com': '' }); parser.start('dummy://foo', playerInterface) .then(function(manifest) { expect(manifest).toEqual( Dash.makeManifestFromInit('special.mp4', 0, null, 20)); return Dash.callCreateSegmentIndex(manifest); }) .then(function() { expect(fakeNetEngine.request.calls.count()).toBe(2); fakeNetEngine.expectRangeRequest('http://example.com', 30, 900); }) .catch(fail) .then(done); }); it('does not assume the same timescale as media', function(done) { var source = [ '', ' ', ' ', ' ', ' http://example.com/index.mp4', ' ', ' ', ' ', ' ', ''].join('\n'); fakeNetEngine.setResponseMap({ 'dummy://foo': shaka.util.StringUtils.toUTF8(source), 'http://example.com/index.mp4': indexSegment }); var video; parser.start('dummy://foo', playerInterface) .then(function(manifest) { video = manifest.periods[0].variants[0].video; return video.createSegmentIndex(); // real data, should succeed }) .then(function() { var reference = video.getSegmentReference(0); expect(reference.startTime).toEqual(0); // clamped to 0 by fit() expect(reference.endTime).toEqual(10); // would be 12 without PTO }) .catch(fail) .then(done); }); describe('fails for', function() { it('unsupported container', function(done) { var source = [ '', ' ', ' http://example.com', ' ', ' ', ' ', ' ', ' ', ' ', '' ].join('\n'); var error = new shaka.util.Error( shaka.util.Error.Severity.CRITICAL, shaka.util.Error.Category.MANIFEST, shaka.util.Error.Code.DASH_UNSUPPORTED_CONTAINER); Dash.testFails(done, source, error); }); it('missing init segment for WebM', function(done) { var source = [ '', ' ', ' http://example.com', ' ', ' ', ' ', ' ', ' ', ' ', '' ].join('\n'); var error = new shaka.util.Error( shaka.util.Error.Severity.CRITICAL, shaka.util.Error.Category.MANIFEST, shaka.util.Error.Code.DASH_WEBM_MISSING_INIT); Dash.testFails(done, source, error); }); it('no @indexRange nor RepresentationIndex', function(done) { var source = [ '', ' ', ' http://example.com', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '' ].join('\n'); var error = new shaka.util.Error( shaka.util.Error.Severity.CRITICAL, shaka.util.Error.Category.MANIFEST, shaka.util.Error.Code.DASH_NO_SEGMENT_INFO); Dash.testFails(done, source, error); }); }); });