npaw-plugin-adapters
Version:
NPAW's Plugin Adapters
505 lines (445 loc) • 15.4 kB
JavaScript
/* global mkplayer */
export default class MediaKindMkplayerAdapter {
getVersion() {
return '7.0.2-mediakind-mkplayer-jsclass';
}
getPlayerName() {
return 'mediakind-ott';
}
checkExistsPlayer() {
try {
const videoElement = this._getVideoElement();
if (videoElement) {
return this.checkExistsObjectOnPage(videoElement);
}
return this.player != null;
} catch (err) {
return true;
}
}
registerListeners() {
if (!this.player || typeof this.player.on !== 'function') {
this._registerRetryCount = (this._registerRetryCount || 0) + 1;
if (this._registerRetryCount < 50) {
setTimeout(() => this.registerListeners(), 100);
} else if (this.log && typeof this.log.warn === 'function') {
this.log.warn('MediaKindMkplayerAdapter', 'Player not ready after maximum retries. Skipping listener registration.');
}
return;
}
this.monitorPlayhead(false, false);
this.references = {};
this.lastPlayhead = 0;
this.lastDuration = 0;
this.lastResource = null;
this.seekStartPosition = null;
const events = this._getEventNames();
this._addListener(events.play, this.playListener);
this._addListener(events.playing, this.playingListener);
this._addListener(events.paused, this.pauseListener);
this._addListener(events.timeChanged, this.timeChangedListener);
this._addListener(events.seek, this.seekListener);
this._addListener(events.seeked, this.seekedListener);
this._addListener(events.timeShift, this.seekListener);
this._addListener(events.timeShifted, this.seekedListener);
this._addListener(events.stallStarted, this.stallStartedListener);
this._addListener(events.stallEnded, this.stallEndedListener);
this._addListener(events.playbackFinished, this.playbackFinishedListener);
this._addListener(events.sourceLoaded, this.sourceLoadedListener);
this._addListener(events.sourceUnloaded, this.sourceUnloadedListener);
this._addListener(events.error, this.errorListener);
this._addListener(events.destroy, this.destroyListener);
this._addListener(events.qualityChanged, this.qualityChangedListener);
}
unregisterListeners() {
if (this.monitor) {
this.monitor.stop();
}
try {
if (this.player && typeof this.player.off === 'function' && this.references) {
for (const key in this.references) {
this.player.off(key, this.references[key]);
}
delete this.references;
}
} catch (err) { }
}
playListener() {
this.firePlayerLog('playListener', {});
this.lastPlayhead = 0;
this.fireStart({}, 'playListener');
this.failedView = false;
}
playingListener() {
this.firePlayerLog('playingListener', {});
this.fireStart({}, 'playingListener');
this.failedView = false;
this.fireJoin({}, 'playingListener');
if (this.flags && this.flags.isSeeking) {
this.fireSeekEnd({}, 'playingListener');
this.seekStartPosition = null;
}
if (this.flags.isPaused) {
this.fireResume({}, 'playingListener');
}
if (this.flags.isBuffering) {
this.fireBufferEnd({}, 'playingListener');
}
}
pauseListener() {
this.firePlayerLog('pauseListener', {});
this.firePause({}, 'pauseListener');
}
timeChangedListener() {
const currentPlayhead = this.getPlayhead();
if (typeof currentPlayhead === 'number') {
this.lastPlayhead = currentPlayhead;
}
const duration = this.getDuration();
if (typeof duration === 'number' && !Number.isNaN(duration)) {
this.lastDuration = duration;
}
if ((currentPlayhead > 0 || this.getIsLive()) && !this.player?.error) {
this.fireStart({}, 'timeChangedListener');
this.fireJoin({}, 'timeChangedListener');
}
if (this.flags && this.flags.isSeeking && this.player && typeof this.player.isPaused === 'function' && !this.player.isPaused()) {
this.fireSeekEnd({}, 'timeChangedListener');
this.seekStartPosition = null;
}
}
stallStartedListener() {
this.firePlayerLog('stallStartedListener', {});
if (!this.flags.isSeeking) {
this.fireBufferBegin({}, false, 'stallStartedListener');
}
}
stallEndedListener() {
this.firePlayerLog('stallEndedListener', {});
if (!this.flags.isSeeking) {
this.fireBufferEnd({}, 'stallEndedListener');
}
}
seekListener() {
this.firePlayerLog('seekListener', {});
this.seekStartPosition = this.getPlayhead();
this.fireSeekBegin({}, false, 'seekListener');
}
seekedListener() {
this.firePlayerLog('seekedListener', {});
}
playbackFinishedListener() {
this.firePlayerLog('playbackFinishedListener', {});
this.fireStop({}, 'playbackFinishedListener');
}
sourceLoadedListener() {
this.firePlayerLog('sourceLoadedListener', {});
const resource = this.getResource();
const normalized = resource ? resource.split('?')[0] : null;
const isLive = this.getIsLive();
const isSeeking = this.flags && this.flags.isSeeking;
if (this.flags.isJoined && !isSeeking && isLive) {
this.seekStartPosition = this.lastPlayhead;
this.fireSeekBegin({}, false, 'sourceLoadedListener');
} else if (!isLive && !isSeeking && this.flags.isJoined && normalized && this.lastResource && this.lastResource !== normalized) {
this.fireStop({}, 'sourceLoadedListener');
}
this.lastResource = normalized;
}
sourceUnloadedListener() {
this.firePlayerLog('sourceUnloadedListener', {});
this.fireStop({}, 'sourceUnloadedListener');
}
destroyListener() {
this.firePlayerLog('destroyListener', {});
this.fireStop({}, 'destroyListener');
}
errorListener(e) {
this.firePlayerLog('errorListener', {});
let code = null;
let msg = null;
try {
code = e?.code || e?.error?.code;
msg = e?.message || e?.error?.message;
} catch (err) { }
this.fireError(code, msg, undefined, undefined, 'errorListener');
}
qualityChangedListener() {
const rendition = this.getRendition();
if (rendition && typeof this.storeNewRendition === 'function') {
this.storeNewRendition(rendition);
}
}
getPlayhead() {
if (!this.player || typeof this.player.getCurrentTime !== 'function') {
return null;
}
if (this.getIsLive()) {
const mode = this._getEnumValue(this._getEnum('MKTimeMode'), 'RelativeTime', 'relative');
try {
return this.player.getCurrentTime(mode);
} catch (err) { }
}
return this.player.getCurrentTime();
}
getDuration() {
if (!this.player || typeof this.player.getDuration !== 'function') {
return this.lastDuration || null;
}
const duration = this.player.getDuration();
if (typeof duration === 'number') {
this.lastDuration = duration;
}
return duration ?? this.lastDuration ?? null;
}
getPlayrate() {
return this.player && typeof this.player.getPlaybackSpeed === 'function'
? this.player.getPlaybackSpeed()
: null;
}
getResource() {
let resource = null;
const sourceConfig = this._getSourceConfig();
if (sourceConfig) {
if (sourceConfig.hls) {
return sourceConfig.hls;
}
if (sourceConfig.dash) {
return sourceConfig.dash;
}
if (sourceConfig.smooth) {
return sourceConfig.smooth;
}
if (sourceConfig.progressive) {
resource = this._extractProgressiveSource(sourceConfig.progressive);
}
if (!resource && sourceConfig.source) {
resource = this._extractMediaSource(sourceConfig.source);
}
}
if (!resource) {
const videoElement = this._getVideoElement();
resource = videoElement?.currentSrc || videoElement?.src || null;
}
return resource;
}
getTitle() {
const sourceConfig = this._getSourceConfig();
return sourceConfig && sourceConfig.title ? sourceConfig.title : null;
}
getBitrate() {
const playback = this._getPlaybackVideoData();
if (playback && typeof playback.bitrate === 'number') {
return playback.bitrate;
}
const quality = this._getVideoQuality();
return quality && typeof quality.bitrate === 'number' ? quality.bitrate : null;
}
getRendition() {
const playback = this._getPlaybackVideoData();
if (playback && playback.width && playback.height) {
return this.getNpawUtils().buildRenditionString(playback.width, playback.height, playback.bitrate);
}
const quality = this._getVideoQuality();
if (quality && quality.width && quality.height) {
return this.getNpawUtils().buildRenditionString(quality.width, quality.height, quality.bitrate);
}
return null;
}
getDroppedFrames() {
return this.player && typeof this.player.getDroppedVideoFrames === 'function'
? this.player.getDroppedVideoFrames()
: null;
}
getFramesPerSecond() {
const playback = this._getPlaybackVideoData();
if (playback && typeof playback.frameRate === 'number') {
return playback.frameRate;
}
const quality = this._getVideoQuality();
return quality && typeof quality.frameRate === 'number' ? quality.frameRate : null;
}
getVideoCodec() {
const playback = this._getPlaybackVideoData();
if (playback && playback.codec) {
return playback.codec;
}
const quality = this._getVideoQuality();
return quality && quality.codec ? quality.codec : null;
}
getAudioCodec() {
const playback = this._getPlaybackAudioData();
if (playback && playback.codec) {
return playback.codec;
}
const quality = this._getAudioQuality();
return quality && quality.codec ? quality.codec : null;
}
getAudioEnabled() {
if (!this.player) {
return null;
}
const isMuted = typeof this.player.isMuted === 'function' ? this.player.isMuted() : null;
const volume = typeof this.player.getVolume === 'function' ? this.player.getVolume() : null;
if (isMuted === null && volume === null) {
return null;
}
if (isMuted === true) {
return false;
}
if (typeof volume === 'number') {
return volume > 0;
}
return true;
}
getIsLive() {
return this.player && typeof this.player.isLive === 'function' ? this.player.isLive() : null;
}
getPlayerVersion() {
return this.player && typeof this.player.getVersion === 'function' ? this.player.getVersion() : null;
}
getIsFullscreen() {
if (!this.player || typeof this.player.getViewMode !== 'function') {
return null;
}
const mode = this.player.getViewMode();
const fullscreen = this._getEnumValue(this._getEnum('MKViewMode'), 'Fullscreen', 'fullscreen');
return mode === fullscreen;
}
getIsVisible() {
const videoElement = this._getVideoElement();
return videoElement ? this.getNpawUtils().calculateAdViewability(videoElement) : null;
}
_addListener(eventName, handler) {
if (!eventName || !handler || !this.player || typeof this.player.on !== 'function') {
return;
}
const bound = handler.bind(this);
this.references[eventName] = bound;
this.player.on(eventName, bound);
}
_getEventNames() {
const events = this._getEnum('MKPlayerEvent');
return {
play: this._getEnumValue(events, 'Play', 'play'),
playing: this._getEnumValue(events, 'Playing', 'playing'),
paused: this._getEnumValue(events, 'Paused', 'paused'),
timeChanged: this._getEnumValue(events, 'TimeChanged', 'timechanged'),
seek: this._getEnumValue(events, 'Seek', 'seek'),
seeked: this._getEnumValue(events, 'Seeked', 'seeked'),
timeShift: this._getEnumValue(events, 'TimeShift', 'timeshift'),
timeShifted: this._getEnumValue(events, 'TimeShifted', 'timeshifted'),
stallStarted: this._getEnumValue(events, 'StallStarted', 'stallstarted'),
stallEnded: this._getEnumValue(events, 'StallEnded', 'stallended'),
playbackFinished: this._getEnumValue(events, 'PlaybackFinished', 'playbackfinished'),
sourceLoaded: this._getEnumValue(events, 'SourceLoaded', 'sourceloaded'),
sourceUnloaded: this._getEnumValue(events, 'SourceUnloaded', 'sourceunloaded'),
error: this._getEnumValue(events, 'Error', 'mkerror'),
destroy: this._getEnumValue(events, 'Destroy', 'destroy'),
qualityChanged: this._getEnumValue(events, 'VideoPlaybackQualityChanged', 'videoplaybackqualitychanged')
};
}
_getEnum(enumName) {
if (this.player && this.player.exports && this.player.exports[enumName]) {
return this.player.exports[enumName];
}
if (typeof mkplayer !== 'undefined' && mkplayer[enumName]) {
return mkplayer[enumName];
}
if (typeof window !== 'undefined' && window.mkplayer && window.mkplayer[enumName]) {
return window.mkplayer[enumName];
}
return null;
}
_getEnumValue(enumObject, key, fallback) {
return enumObject && enumObject[key] ? enumObject[key] : fallback;
}
_getSourceConfig() {
if (!this.player || typeof this.player.getSourceConfig !== 'function') {
return null;
}
try {
return this.player.getSourceConfig();
} catch (err) {
return null;
}
}
_getVideoElement() {
if (this.player && typeof this.player.getVideoElement === 'function') {
return this.player.getVideoElement();
}
return this.tag || null;
}
_getPlaybackVideoData() {
if (!this.player || typeof this.player.getPlaybackVideoData !== 'function') {
return null;
}
try {
return this.player.getPlaybackVideoData();
} catch (err) {
return null;
}
}
_getVideoQuality() {
if (!this.player || typeof this.player.getVideoQuality !== 'function') {
return null;
}
try {
return this.player.getVideoQuality();
} catch (err) {
return null;
}
}
_getPlaybackAudioData() {
if (!this.player || typeof this.player.getPlaybackAudioData !== 'function') {
return null;
}
try {
return this.player.getPlaybackAudioData();
} catch (err) {
return null;
}
}
_getAudioQuality() {
if (!this.player || typeof this.player.getAudioQuality !== 'function') {
return null;
}
try {
return this.player.getAudioQuality();
} catch (err) {
return null;
}
}
_extractProgressiveSource(progressive) {
if (typeof progressive === 'string') {
return progressive;
}
if (Array.isArray(progressive)) {
const match = progressive.find((item) => item && (item.src || item.url));
return match ? match.src || match.url : null;
}
if (progressive && (progressive.src || progressive.url)) {
return progressive.src || progressive.url;
}
return null;
}
_extractMediaSource(source) {
if (!source) {
return null;
}
if (source.hls || source.dash || source.smooth) {
return source.hls || source.dash || source.smooth;
}
if (source.progressive) {
const progressive = this._extractProgressiveSource(source.progressive);
if (progressive) {
return progressive;
}
}
if (Array.isArray(source.sources)) {
const match = source.sources.find((item) => item && (item.src || item.url));
return match ? match.src || match.url : null;
}
return null;
}
}