Skip to content

Commit

Permalink
Filters out single-stream variants.
Browse files Browse the repository at this point in the history
In situations where there are variants with video and audio, and variants
with only one of the two, this filters out the less-complete variants.
This removes the possibility of the player switching to an audio-only
variant and breaking MediaSource. It also solves the regression where
audio-only variants have the lowest bandwidth and thus are chosen
preferentially on weak connections.

Closes #824
Closes #861

Change-Id: Ic37543d98962ddd83a85224e26e5225d142b844e
  • Loading branch information
theodab authored and joeyparrish committed Jul 17, 2017
1 parent d05a6b7 commit e256dc3
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 0 deletions.
19 changes: 19 additions & 0 deletions lib/player.js
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,25 @@ shaka.Player.prototype.load = function(manifestUri, opt_startTime,
return this.parser_.start(manifestUri, playerInterface);
}.bind(this)).then(function(manifest) {

// When there is a variant with video and audio, filter out all
// variants which lack one or the other.
// This is to avoid problems where we choose audio-only variants because
// they have lower bandwidth, when there are variants with video available.
var hasAVVariant = manifest.periods.some(function(period) {
return period.variants.some(function(variant) {
return variant.video && variant.audio;
});
});
if (hasAVVariant) {
shaka.log.debug('Found variant with audio and video content, ' +
'so filtering all periods.');
manifest.periods.forEach(function(period) {
period.variants = period.variants.filter(function(variant) {
return variant.video && variant.audio;
});
});
}

if (manifest.periods.length == 0) {
throw new shaka.util.Error(
shaka.util.Error.Severity.CRITICAL,
Expand Down
99 changes: 99 additions & 0 deletions test/player_unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,105 @@ describe('Player', function() {
});
});

describe('filterTracks', function() {
it('retains only video+audio variants if they exist', function(done) {
var manifest = new shaka.test.ManifestGenerator()
.addPeriod(0)
.addVariant(1)
.bandwidth(200)
.language('fr')
.addAudio(2).bandwidth(100)
.addVariant(2)
.bandwidth(400)
.language('en')
.addAudio(1).bandwidth(100)
.addVideo(4).bandwidth(100).size(100, 200)
.frameRate(1000000 / 42000)
.addVariant(3)
.bandwidth(200)
.addVideo(5).bandwidth(100).size(300, 400)
.frameRate(1000000 / 42000)
.addPeriod(1)
.addVariant(1)
.bandwidth(200)
.language('fr')
.addAudio(2).bandwidth(100)
.addVariant(2)
.bandwidth(200)
.addVideo(5).bandwidth(100).size(300, 400)
.frameRate(1000000 / 42000)
.addVariant(3)
.bandwidth(450)
.language('en')
.addAudio(1).bandwidth(100)
.addVideo(4).bandwidth(100).size(100, 200)
.frameRate(1000000 / 42000)
.build();

var variantTracks1 = [
{
id: 2,
active: false,
type: 'variant',
bandwidth: 400,
language: 'en',
label: null,
kind: null,
width: 100,
height: 200,
frameRate: 1000000 / 42000,
mimeType: 'video/mp4',
codecs: 'avc1.4d401f, mp4a.40.2',
audioCodec: 'mp4a.40.2',
videoCodec: 'avc1.4d401f',
primary: false,
roles: [],
videoId: 4,
audioId: 1,
channelsCount: null
}
];
var variantTracks2 = [
{
id: 3,
active: false,
type: 'variant',
bandwidth: 450,
language: 'en',
label: null,
kind: null,
width: 100,
height: 200,
frameRate: 1000000 / 42000,
mimeType: 'video/mp4',
codecs: 'avc1.4d401f, mp4a.40.2',
audioCodec: 'mp4a.40.2',
videoCodec: 'avc1.4d401f',
primary: false,
roles: [],
videoId: 4,
audioId: 1,
channelsCount: null
}
];

var parser = new shaka.test.FakeManifestParser(manifest);
var parserFactory = function() { return parser; };
player.load('', 0, parserFactory).catch(fail).then(function() {
// Check the first period's variant tracks.
var actualVariantTracks1 = player.getVariantTracks();
expect(actualVariantTracks1).toEqual(variantTracks1);

// Check the second period's variant tracks.
playhead.getTime.and.callFake(function() {
return 100;
});
var actualVariantTracks2 = player.getVariantTracks();
expect(actualVariantTracks2).toEqual(variantTracks2);
}).then(done);
});
});

describe('tracks', function() {
var variantTracks;
var textTracks;
Expand Down

0 comments on commit e256dc3

Please sign in to comment.