Skip to content

Commit

Permalink
Regression test for language/MediaSource failure
Browse files Browse the repository at this point in the history
This is fairly tricky to reproduce.

First, we must trigger the auto-display of subtitles.  We didn't have
any tests that covered this before, so we needed this anyway.  This is
triggered by careful choice of content language and language
preferences, which required us to add language information to our
simulated test content.  I also added tests for the cases where we
should *not* trigger auto-display of subtitles.

Second, the setup phase for text must complete more quickly than the
setup for audio & video.  In real life, this happens when text is
non-segmented VTT and audio & video use DASH's SegmentBase.  In the
test, this is accomplished by delaying createSegmentIndex() of
audio and video in our simulated content.

This will cause auto-display of subtitles to trigger a setup race in
StreamingEngine.  When text wins the race, MediaSource errors follow
for audio and video.

Issue #1696

Change-Id: I1c22089925486da642368bec269a55d8556900d1
  • Loading branch information
joeyparrish committed Dec 8, 2018
1 parent 2b004f9 commit 41305dc
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 0 deletions.
82 changes: 82 additions & 0 deletions test/player_integration.js
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,88 @@ describe('Player', function() {
expect(textTrack.cues).not.toBe(null);
}
});

it('is called automatically if language prefs match', async () => {
// If the text is a match for the user's preferences, and audio differs
// from text, we enable text display automatically.

// NOTE: This is also a regression test for #1696, in which a change
// to this feature broke StreamingEngine initialization.

const preferredTextLanguage = 'fa'; // The same as in the content itself
player.configure({preferredTextLanguage: preferredTextLanguage});

// Now load a version of Sintel with delayed setup of video & audio
// streams and wait for completion.
await player.load('test:sintel_realistic_compiled');
// By this point, a MediaSource error would be thrown in a repro of bug
// #1696.

// Make sure the automatic setting took effect.
expect(player.isTextTrackVisible()).toBe(true);

// Make sure the content we tested with has text tracks, that the config
// we used matches the text language, and that the audio language differs.
// These will catch any changes to the underlying content that would
// invalidate the test setup.
expect(player.getTextTracks().length).not.toBe(0);
const textTrack = player.getTextTracks()[0];
expect(textTrack.language).toEqual(preferredTextLanguage);

const variantTrack = player.getVariantTracks()[0];
expect(variantTrack.language).not.toEqual(textTrack.language);
});

it('is not called automatically without language pref match', async () => {
// If the text preference doesn't match the content, we do not enable text
// display automatically.

const preferredTextLanguage = 'xx'; // Differs from the content itself
player.configure({preferredTextLanguage: preferredTextLanguage});

// Now load the content and wait for completion.
await player.load('test:sintel_realistic_compiled');

// Make sure the automatic setting did not happen.
expect(player.isTextTrackVisible()).toBe(false);

// Make sure the content we tested with has text tracks, that the config
// we used does not match the text language, and that the text and audio
// languages do not match each other (to keep this distinct from the next
// test case). This will catch any changes to the underlying content that
// would invalidate the test setup.
expect(player.getTextTracks().length).not.toBe(0);
const textTrack = player.getTextTracks()[0];
expect(textTrack.language).not.toEqual(preferredTextLanguage);

const variantTrack = player.getVariantTracks()[0];
expect(variantTrack.language).not.toEqual(textTrack.language);
});

it('is not called automatically with audio and text match', async () => {
// If the audio and text tracks use the same language, we do not enable
// text display automatically, no matter the text preference.

const preferredTextLanguage = 'und'; // The same as in the content itself
player.configure({preferredTextLanguage: preferredTextLanguage});

// Now load the content and wait for completion.
await player.load('test:sintel_compiled');

// Make sure the automatic setting did not happen.
expect(player.isTextTrackVisible()).toBe(false);

// Make sure the content we tested with has text tracks, that the
// config we used matches the content, and that the text and audio
// languages match each other. This will catch any changes to the
// underlying content that would invalidate the test setup.
expect(player.getTextTracks().length).not.toBe(0);
const textTrack = player.getTextTracks()[0];
expect(textTrack.language).toEqual(preferredTextLanguage);

const variantTrack = player.getVariantTracks()[0];
expect(variantTrack.language).toEqual(textTrack.language);
});
});

describe('plays', function() {
Expand Down
12 changes: 12 additions & 0 deletions test/test/util/manifest_generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,18 @@ shaka.test.ManifestGenerator.prototype.textStream = function(uri) {
};


/**
* Force a delay in createSegmentIndex to delay setup. This can be useful in
* certain tests.
*
* @return {!shaka.test.ManifestGenerator}
*/
shaka.test.ManifestGenerator.prototype.delayCreateSegmentIndex = function() {
this.currentStream_().createSegmentIndex = () => shaka.test.Util.delay(1);
return this;
};


/**
* Converts the init segment of the current stream into jasmine.any.
*
Expand Down
55 changes: 55 additions & 0 deletions test/test/util/test_scheme.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,43 @@ shaka.test.TestScheme.DATA = {
},
duration: 30,
},

// Like 'sintel' above, but with languages and delayed setup.
// These extra features help expose some edge cases.
'sintel_realistic': {
video: {
initSegmentUri: '/base/test/test/assets/sintel-video-init.mp4',
mvhdOffset: 0x24,
segmentUri: '/base/test/test/assets/sintel-video-segment.mp4',
tfdtOffset: 0x38,
segmentDuration: 10,
presentationTimeOffset: 0,
mimeType: 'video/mp4',
codecs: 'avc1.42c01e',
delaySetup: true, // Necessary to repro #1696
},
audio: {
initSegmentUri: '/base/test/test/assets/sintel-audio-init.mp4',
mvhdOffset: 0x20,
segmentUri: '/base/test/test/assets/sintel-audio-segment.mp4',
tfdtOffset: 0x3c,
segmentDuration: 10.005,
presentationTimeOffset: 0,
mimeType: 'audio/mp4',
codecs: 'mp4a.40.2',
language: 'uk', // Necessary to repro #1696
delaySetup: true, // Necessary to repro #1696
},
text: {
uri: '/base/test/test/assets/text-clip.vtt',
mimeType: 'text/vtt',
language: 'fa', // Necessary to repro #1696
},
duration: 30,
},

// 'sintel_short_periods' : Generated by createManifests().

'sintel_no_text': {
video: {
initSegmentUri: '/base/test/test/assets/sintel-video-init.mp4',
Expand All @@ -142,6 +178,7 @@ shaka.test.TestScheme.DATA = {
},
duration: 30,
},

'sintel-enc': {
video: {
initSegmentUri: '/base/test/test/assets/encrypted-sintel-video-init.mp4',
Expand Down Expand Up @@ -180,6 +217,7 @@ shaka.test.TestScheme.DATA = {
},
duration: 30,
},

'multidrm': {
video: {
initSegmentUri: '/base/test/test/assets/multidrm-video-init.mp4',
Expand Down Expand Up @@ -227,6 +265,7 @@ shaka.test.TestScheme.DATA = {
},
duration: 30,
},

'multidrm_no_init_data': {
video: {
initSegmentUri: '/base/test/test/assets/multidrm-video-init.mp4',
Expand Down Expand Up @@ -264,6 +303,7 @@ shaka.test.TestScheme.DATA = {
},
duration: 30,
},

'cea-708_ts': {
video: {
segmentUri: '/base/test/test/assets/captions-test.ts',
Expand All @@ -275,6 +315,7 @@ shaka.test.TestScheme.DATA = {
},
duration: 30,
},

'cea-708_mp4': {
video: {
initSegmentUri: '/base/test/test/assets/cea-init.mp4',
Expand Down Expand Up @@ -346,6 +387,8 @@ shaka.test.TestScheme.createManifests = function(shaka, suffix) {
}

/**
* Not for simulating non-segmented text streams.
*
* @param {shaka.test.ManifestGenerator} manifestGenerator
* @param {Object} data
* @param {shaka.util.ManifestParserUtils.ContentType} contentType
Expand All @@ -361,6 +404,14 @@ shaka.test.TestScheme.createManifests = function(shaka, suffix) {
data[contentType].segmentDuration)
.closedCaptions(data[contentType].closedCaptions);

if (data[contentType].language) {
manifestGenerator.language(data[contentType].language);
}

if (data[contentType].delaySetup) {
manifestGenerator.delayCreateSegmentIndex();
}

if (data.licenseServers) {
for (let keySystem in data.licenseServers) {
manifestGenerator.addDrmInfo(keySystem)
Expand Down Expand Up @@ -411,6 +462,10 @@ shaka.test.TestScheme.createManifests = function(shaka, suffix) {
gen.addTextStream(3)
.mime(data.text.mimeType, data.text.codecs)
.textStream(absoluteUri.toString());

if (data.text.language) {
gen.language(data.text.language);
}
}

MANIFESTS[name + suffix] = gen.build();
Expand Down

0 comments on commit 41305dc

Please sign in to comment.