Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,7 @@ This option defaults to `false`.
##### useNetworkInformationApi
* Type: `boolean`,
* Default: `true`
* Use [window.networkInformation.downlink](https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation/downlink) to estimate the network's bandwidth. Per mdn, _The value is never greater than 10 Mbps, as a non-standard anti-fingerprinting measure_. Given this, if bandwidth estimates from both the player and networkInfo are >= 10 Mbps, the player will use the larger of the two values as its bandwidth estimate.
* Use [window.networkInformation.downlink](https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation/downlink) to estimate the network's bandwidth. Per mdn, _The value is never greater than 10 Mbps, as a non-standard anti-fingerprinting measure_. Given this, before media segment stats are available, if bandwidth estimates from both the player and networkInfo are >= 10 Mbps, the player will use the larger of the two values as its bandwidth estimate. Once media segment stats are available, the player uses the larger of the player estimate and the networkInfo estimate so networkInfo does not lower a player-specific bandwidth estimate.

##### useDtsForTimestampOffset
* Type: `boolean`,
Expand Down
8 changes: 7 additions & 1 deletion src/videojs-http-streaming.js
Original file line number Diff line number Diff line change
Expand Up @@ -873,16 +873,22 @@ class VhsHandler extends Component {
},
bandwidth: {
get() {
let playerBandwidthEst = this.playlistController_.mainSegmentLoader_.bandwidth;
const mainSegmentLoader = this.playlistController_.mainSegmentLoader_;
let playerBandwidthEst = mainSegmentLoader.bandwidth;

const networkInformation = window.navigator.connection || window.navigator.mozConnection || window.navigator.webkitConnection;
const tenMbpsAsBitsPerSecond = 10e6;
const hasSegmentBandwidthEstimate = !isNaN(mainSegmentLoader.roundTrip);

if (this.options_.useNetworkInformationApi && networkInformation) {
// downlink returns Mbps
// https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation/downlink
const networkInfoBandwidthEstBitsPerSec = networkInformation.downlink * 1000 * 1000;

if (hasSegmentBandwidthEstimate) {
return Math.max(playerBandwidthEst, networkInfoBandwidthEstBitsPerSec);
}

// downlink maxes out at 10 Mbps. In the event that both networkInformationApi and the player
// estimate a bandwidth greater than 10 Mbps, use the larger of the two estimates to ensure that
// high quality streams are not filtered out.
Expand Down
54 changes: 54 additions & 0 deletions test/videojs-http-streaming.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1095,6 +1095,60 @@ QUnit.module('NetworkInformationApi', hooks => {
}
);

QUnit.test(
'bandwidth does not use network-information-api to lower bandwidth after media segment stats are available',
function(assert) {
this.resetNavigatorConnection({
downlink: 1.5
});
this.player = createPlayer({ html5: { vhs: { useNetworkInformationApi: true } } });
this.player.src({
src: 'manifest/main.m3u8',
type: 'application/vnd.apple.mpegurl'
});

this.clock.tick(1);

const mainSegmentLoader = this.player.tech_.vhs.playlistController_.mainSegmentLoader_;

mainSegmentLoader.bandwidth = 20e6;
mainSegmentLoader.roundTrip = 100;

assert.strictEqual(
this.player.tech_.vhs.bandwidth,
20e6,
'bandwidth getter returned the higher player-estimated bandwidth value after media segment stats'
);
}
);

QUnit.test(
'bandwidth can use network-information-api to raise bandwidth after media segment stats are available',
function(assert) {
this.resetNavigatorConnection({
downlink: 9
});
this.player = createPlayer({ html5: { vhs: { useNetworkInformationApi: true } } });
this.player.src({
src: 'manifest/main.m3u8',
type: 'application/vnd.apple.mpegurl'
});

this.clock.tick(1);

const mainSegmentLoader = this.player.tech_.vhs.playlistController_.mainSegmentLoader_;

mainSegmentLoader.bandwidth = 2e6;
mainSegmentLoader.roundTrip = 100;

assert.strictEqual(
this.player.tech_.vhs.bandwidth,
9e6,
'bandwidth getter returned the higher network-information-api bandwidth value after media segment stats'
);
}
);

QUnit.test(
'bandwidth uses player-estimated bandwidth when networkInformation is not supported',
function(assert) {
Expand Down