npaw-plugin-adapters
Version:
NPAW's Plugin Adapters
320 lines (287 loc) • 9.56 kB
JavaScript
export default class DashJSAdapter {
checkExistsPlayer() {
try {
return this.checkExistsObjectOnPage(this.player.getVideoElement());
} catch (err) {
return true;
}
}
getVersion() {
return '7.0.16-dashjs-jsclass';
}
getPlayhead() {
var ret = null;
if (this.player) {
ret = this.isLive ? this.player.timeAsUTC() : this.player.time();
}
return ret;
}
getDroppedFrames() {
var ret = 0;
if (this.player) {
var metrics = this.player.getDashMetrics();
ret = metrics.getCurrentDroppedFrames().droppedFrames;
}
return ret;
}
getDuration() {
var ret = null;
if (this.player) {
ret = this.player.duration();
}
return ret;
}
getBitrate() {
var rendition = this._getRenditionInfo();
return rendition ? rendition.bitrate : null;
}
getRendition() {
var rendition = this._getRenditionInfo();
return rendition
? this.getNpawUtils().buildRenditionString(rendition.width, rendition.height, rendition.bitrate)
: null;
}
_getRenditionInfo() {
var ret = null;
if (this.player) {
if (typeof this.player.getQualityFor === 'function' && typeof this.player.getBitrateInfoListFor === 'function') {
// DashJS < 5.0
var level = this.player.getQualityFor('video');
if (level !== undefined && level !== null) {
ret = this.player.getBitrateInfoListFor('video')[level];
}
} else if (typeof this.player.getCurrentRepresentationForType === 'function') {
// DashJS >= 5.0
var representation = this.player.getCurrentRepresentationForType('video');
if (representation && representation.bandwidth !== undefined) {
ret = {
bitrate: representation.bitrateInKbit * 1000,
height: representation.height,
width: representation.width
};
}
}
}
return ret;
}
getThroughput() {
if (this.getCdnTraffic() && this.getCdnTraffic() !== 0 && this.plugin && this.plugin.getPingTime()) {
if (!this.lastDataValue) {
this.lastDataValue = 0;
}
var prevDataValue = this.lastDataValue;
this.lastDataValue = this.getCdnTraffic() + this.getP2PTraffic();
return Math.round((this.lastDataValue - prevDataValue) / this.plugin.getPingTime());
}
if (!this.throughput && this.player && this.player.getMetricsFor) {
var metrics = this.player.getMetricsFor('video');
var dashMetrics = this.player.getDashMetrics();
var requests = dashMetrics.getHttpRequests(metrics);
if (!requests) return null;
var bps = 0;
var bpsCount = 0;
for (var i = 0; i < requests.length; i++) {
var req = requests[i];
if (
req.type === 'MediaSegment' &&
req.responsecode >= 200 &&
req.responsecode < 400 &&
req._stream === 'video'
) {
var match = req._responseHeaders.match(/Content-Length: (.+)/i);
if (match) {
var time = (req.interval - (req.tresponse - req.trequest)) / 1000;
bps += (match[1] / time) * 8;
bpsCount++;
}
}
}
if (!bps) return null;
this.throughput = bps / bpsCount;
}
if (!this.throughput && this.player && this.player.getAverageThroughput) {
var videoThroughput = this.player.getAverageThroughput('video');
var audioThroughput = this.player.getAverageThroughput('audio');
this.throughput = (videoThroughput + audioThroughput) * 1000;
}
return this.throughput;
}
getIsLive() {
if (!this.isLive) {
this.isLive = false;
}
return this.isLive;
}
getResource() {
var ret = null;
if (this.player) {
try {
var src = this.player.getSource();
if (typeof src === 'string') {
ret = src;
}
} catch (err) {}
}
return ret;
}
getPlayrate() {
if (this.player) {
return this.player.getPlaybackRate();
}
return 1;
}
getPlayerName() {
return 'dashJS';
}
getPlayerVersion() {
var ret = null;
if (this.player) {
ret = this.player.getVersion();
}
return ret;
}
getLatency() {
var ret = null;
if (this.getIsLive() && this.player && this.player.getCurrentLiveLatency) {
ret = this.player.getCurrentLiveLatency() * 1000;
}
return ret;
}
registerListeners() {
this.emptyVideoBuffer = false;
this.emptyAudioBuffer = false;
this.emptyTextBuffer = false;
var Events = dashjs.MediaPlayer.events;
this.references = {};
this.references[Events.MANIFEST_LOADED] = this.manifestLoaded.bind(this);
this.references[Events.PLAYBACK_STARTED] = this.playbackStarted.bind(this);
this.references[Events.PLAYBACK_WAITING] = this.playbackWaiting.bind(this);
this.references[Events.PLAYBACK_PLAYING] = this.playbackPlaying.bind(this);
this.references[Events.PLAYBACK_SEEKED] = this.playbackPlaying.bind(this);
this.references[Events.PLAYBACK_PAUSED] = this.playbackPaused.bind(this);
this.references[Events.PLAYBACK_ENDED] = this.playbackEnded.bind(this);
this.references[Events.ERROR] = this.errorListener.bind(this);
this.references[Events.PLAYBACK_ERROR] = this.playbackError.bind(this);
this.references[Events.PLAYBACK_SEEKING] = this.playbackSeeking.bind(this);
this.references[Events.BUFFER_LOADED] = this.processBufferLoaded.bind(this);
this.references[Events.BUFFER_EMPTY] = this.processBufferEmpty.bind(this);
if (this.player) {
for (var key in this.references) {
this.player.on(key, this.references[key]);
}
}
}
unregisterListeners() {
this.emptyVideoBuffer = false;
this.emptyAudioBuffer = false;
this.emptyTextBuffer = false;
if (this.player && this.references) {
for (var key in this.references) {
this.player.off(key, this.references[key]);
}
delete this.references;
}
}
processBufferEmpty(e) {
if (e.mediaType === 'video') {
this.emptyVideoBuffer = true;
} else if (e.mediaType === 'audio') {
this.emptyAudioBuffer = true;
} else if (e.mediaType === 'text') {
this.emptyTextBuffer = true;
}
}
processBufferLoaded(e) {
if (e.mediaType === 'video') {
this.emptyVideoBuffer = false;
} else if (e.mediaType === 'audio') {
this.emptyAudioBuffer = false;
} else if (e.mediaType === 'text') {
this.emptyTextBuffer = false;
}
}
manifestLoaded(e) {
this.firePlayerLog('manifestLoaded', {});
this.isLive = e.data && e.data.type === 'dynamic';
}
playbackStarted(e) {
this.firePlayerLog('playbackStarted', {});
this.fireStart({}, 'playbackStarted');
}
playbackPaused(e) {
this.firePlayerLog('playbackPaused', {});
this.firePause({}, 'playbackPaused');
}
playbackPlaying(e) {
this.firePlayerLog('playbackPlaying', {});
if (this.flags.isSeeking) {
this.fireSeekEnd({}, 'playbackPlaying');
} else if (this.flags.isPaused) {
this.fireResume({}, 'playbackPlaying');
}
this.fireBufferEnd({}, 'playbackPlaying');
this.fireJoin({}, 'playbackPlaying');
}
playbackWaiting(e) {
var legacyBufferBehaviour = this.isLegacyBufferBehaviourEnabled();
this.firePlayerLog('playbackWaiting', {});
if (!legacyBufferBehaviour || this.emptyVideoBuffer) {
this.fireBufferBegin({}, false, 'playbackWaiting');
}
}
errorListener(e) {
this.firePlayerLog('errorListener', {});
if (e.error.code) {
this.fireError(e.error.code, e.error.message, undefined, undefined, 'errorListener');
} else {
this.fireError(e.error, 'Error', undefined, undefined, 'errorListener');
}
}
playbackError(e) {
this.firePlayerLog('playbackError', {});
if (e.error.code) {
this.fireError(e.error.code, e.error.message, undefined, undefined, 'playbackError');
} else {
this.fireError(e.error, 'Playback error', undefined, undefined, 'playbackError');
}
}
playbackSeeking(e) {
this.firePlayerLog('playbackSeeking', {});
if (this.isLive) {
this.fireStart({}, 'playbackSeeking');
}
this.fireSeekBegin({}, false, 'playbackSeeking');
}
playbackEnded(e) {
var adsAdapter = this.getVideo().getAdsAdapter();
var willShowCSAIAds = false;
if (adsAdapter && typeof adsAdapter.isDAI !== 'undefined') {
if (!adsAdapter.isDAI) {
// This means we are using Google IMA with CSAI
willShowCSAIAds = adsAdapter.player.getCuePoints().indexOf(-1) !== -1;
}
}
if (e.isLast && !willShowCSAIAds) {
this.firePlayerLog('playbackEnded', {});
this.fireStop({}, 'playbackEnded');
}
}
getCdnTraffic() {
if (this.player.getMetricsFor) {
var allMetrics = this.player.getMetricsFor('p2pweb');
if (!allMetrics) return this.getNpawReference().Adapter.prototype.getCdnTraffic();
var metrics = allMetrics.metricsP2PWeb;
return metrics.videoAvgLength * metrics.chunksFromCDN + metrics.audioAvgLength * metrics.chunksFromCDN;
}
return null;
}
getP2PTraffic() {
if (this.player.getMetricsFor) {
var allMetrics = this.player.getMetricsFor('p2pweb');
if (!allMetrics) return this.getNpawReference().Adapter.prototype.getP2PTraffic();
var metrics = allMetrics.metricsP2PWeb;
return metrics.videoAvgLength * metrics.chunksFromP2P + metrics.audioAvgLength * metrics.chunksFromP2P;
}
return null;
}
}