63537 - Heartbeat and metrics WiP
This commit is contained in:
+6
-2
@@ -2,14 +2,18 @@
|
||||
FROM arm64v8/node:23.6.1-alpine3.21 AS arm
|
||||
#FROM node:23.6.1-alpine3.21 AS intel
|
||||
|
||||
# Global npm dependencies for correct caching docker layers
|
||||
RUN <<EOF
|
||||
npm install -g nodemon;
|
||||
npm install -g lite-server;
|
||||
EOF
|
||||
|
||||
WORKDIR /usr/voka
|
||||
|
||||
COPY package*.json .
|
||||
COPY develop.sh .
|
||||
|
||||
RUN <<EOF
|
||||
npm install -g nodemon;
|
||||
npm install -g lite-server;
|
||||
npm install;
|
||||
chmod +x develop.sh;
|
||||
EOF
|
||||
|
||||
+1
-1
@@ -4,6 +4,6 @@
|
||||
"VokaStatisticsPlugin": false,
|
||||
"VokaQualityPlugin": false,
|
||||
"VokaCaptionsPlugin": false,
|
||||
"VokaKeyboard": true
|
||||
"VokaKeyboardPlugin": true
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ import '@/internal/player/native/mp4/tech/VokaMp4Tech'
|
||||
import '@/internal/player/native/apple/tech/VokaAppleTech'
|
||||
import '@/internal/player/native/hls/tech/VokaHlsTech'
|
||||
import '@/internal/player/native/dash/tech/VokaDashTech'
|
||||
import '@/plugins/VokaKeyboard'
|
||||
import '@/plugins/VokaKeyboardPlugin'
|
||||
|
||||
import '@/components/Skin'
|
||||
|
||||
@@ -95,7 +95,9 @@ export class VokaPlayerImpl implements IVokaPlayer {
|
||||
//plugins.vokaStatisticsPlugin = {}
|
||||
//plugins.vokaAdvertisementPlugin = {}
|
||||
//plugins.vokaCaptionsPlugin = {}
|
||||
plugins.vokaKeyboard = {}
|
||||
plugins.vokaKeyboardPlugin = {}
|
||||
plugins.vokaHeartbeatPlugin = {} // Хартбит Player.Heartbeat
|
||||
plugins.vokaMetricsPlugin = {} // Метрики Player.Metrics
|
||||
|
||||
const childrenComponents = [
|
||||
// Non-visual component, not in UI layer list.
|
||||
|
||||
@@ -0,0 +1,336 @@
|
||||
import videojs, { VideoJsPlayer, VideoJsPlayerOptions } from 'video.js'
|
||||
import VokaEvent from "@/constants/VokaEvent"
|
||||
const Plugin = videojs.getPlugin('plugin')
|
||||
|
||||
export class VokaHeartbeatPlugin extends Plugin {
|
||||
private player!: VideoJsPlayer
|
||||
|
||||
constructor(player: VideoJsPlayer, options: VideoJsPlayerOptions) {
|
||||
super(player, options)
|
||||
this.player = player
|
||||
// this.setupListeners()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
videojs.registerPlugin('vokaHeartbeatPlugin', VokaHeartbeatPlugin)
|
||||
|
||||
/*
|
||||
Player.Heartbeat = function (_global, _options, _player) {
|
||||
|
||||
'use strict';
|
||||
|
||||
var global = _global;
|
||||
var options = _options;
|
||||
var player = _player;
|
||||
|
||||
var playerListenerInitialized = false;
|
||||
var streamOptions = null;
|
||||
var playbackStarted = false;
|
||||
|
||||
var progressRequest = null;
|
||||
var startRequest = null;
|
||||
var endRequest = null;
|
||||
var scheduledProgress = undefined;
|
||||
|
||||
function abortProgressRequest() {
|
||||
if (!progressRequest) {
|
||||
return;
|
||||
}
|
||||
progressRequest.abort();
|
||||
progressRequest = null;
|
||||
}
|
||||
|
||||
function abortStartRequest() {
|
||||
if (!startRequest) {
|
||||
return;
|
||||
}
|
||||
startRequest.abort();
|
||||
startRequest = null;
|
||||
}
|
||||
|
||||
function detachEndRequest() {
|
||||
|
||||
if (!endRequest) {
|
||||
return;
|
||||
}
|
||||
|
||||
endRequest.onload = null;
|
||||
endRequest.onerror = null;
|
||||
endRequest.ontimeout = null;
|
||||
|
||||
endRequest = null;
|
||||
}
|
||||
|
||||
function createRequest(reqType) {
|
||||
|
||||
var action;
|
||||
var needTime, needDuration;
|
||||
var time, duration;
|
||||
var url;
|
||||
var firstParam;
|
||||
var request;
|
||||
|
||||
function addParam(name, value) {
|
||||
|
||||
if (firstParam && url.indexOf('?') >= 0) {
|
||||
firstParam = false;
|
||||
}
|
||||
|
||||
if (firstParam) {
|
||||
url += '?';
|
||||
firstParam = false;
|
||||
} else {
|
||||
url += '&';
|
||||
}
|
||||
|
||||
url += encodeURIComponent(name);
|
||||
url += '=';
|
||||
url += encodeURIComponent(value);
|
||||
}
|
||||
|
||||
needTime = false;
|
||||
needDuration = false;
|
||||
|
||||
switch (reqType) {
|
||||
case 'start':
|
||||
action = 'start';
|
||||
needTime = true;
|
||||
needDuration = true;
|
||||
break;
|
||||
case 'end':
|
||||
action = 'end';
|
||||
needTime = true;
|
||||
needDuration = true;
|
||||
break;
|
||||
case 'progress':
|
||||
action = 'watch';
|
||||
needTime = true;
|
||||
needDuration = true;
|
||||
break;
|
||||
default:
|
||||
action = null;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!action) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (needTime) {
|
||||
time = player.getCurrentTime();
|
||||
} else {
|
||||
time = NaN;
|
||||
}
|
||||
|
||||
if (needDuration && !player.getIsLive()) {
|
||||
duration = player.getDuration();
|
||||
} else {
|
||||
duration = NaN;
|
||||
}
|
||||
|
||||
request = new XMLHttpRequest();
|
||||
|
||||
switch (reqType) {
|
||||
case 'start':
|
||||
startRequest = request;
|
||||
break;
|
||||
case 'end':
|
||||
endRequest = request;
|
||||
break;
|
||||
case 'progress':
|
||||
default:
|
||||
progressRequest = request;
|
||||
break;
|
||||
}
|
||||
|
||||
request.onload = onRequestLoad;
|
||||
request.onerror = onRequestError;
|
||||
request.ontimeout = onRequestTimeout;
|
||||
|
||||
url = streamOptions.heartbeat.url;
|
||||
firstParam = true;
|
||||
|
||||
if (!isNaN(streamOptions.heartbeat.version)) {
|
||||
addParam('v', streamOptions.heartbeat.version.toString());
|
||||
}
|
||||
|
||||
addParam('action', action);
|
||||
|
||||
if (!isNaN(time)) {
|
||||
addParam('timestamp', Math.round(time * 1000).toString());
|
||||
}
|
||||
|
||||
if (!isNaN(duration)) {
|
||||
addParam('duration', Math.round(duration * 1000).toString());
|
||||
}
|
||||
|
||||
request.open('GET', url, true);
|
||||
|
||||
//request.withCredentials = true;
|
||||
request.timeout = 60000;
|
||||
|
||||
request.send();
|
||||
}
|
||||
|
||||
function createProgressRequest() {
|
||||
abortProgressRequest();
|
||||
progressRequest = createRequest('progress');
|
||||
}
|
||||
|
||||
function scheduleProgressRequest() {
|
||||
unscheduleProgressRequest();
|
||||
scheduledProgress = Utils.setInterval(createProgressRequest, streamOptions.heartbeat.interval * 1000);
|
||||
}
|
||||
|
||||
function unscheduleProgressRequest() {
|
||||
if (scheduledProgress === undefined) {
|
||||
return;
|
||||
}
|
||||
clearInterval(scheduledProgress);
|
||||
scheduledProgress = undefined;
|
||||
}
|
||||
|
||||
function removeRequest(e) {
|
||||
|
||||
var request;
|
||||
|
||||
if (!e) {
|
||||
return;
|
||||
}
|
||||
|
||||
request = e.target;
|
||||
if (!request) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (request === progressRequest) {
|
||||
progressRequest = null;
|
||||
} else if (request === startRequest) {
|
||||
startRequest = null;
|
||||
} else if (request === endRequest) {
|
||||
endRequest = null;
|
||||
}
|
||||
}
|
||||
|
||||
function onRequestLoad(e) {
|
||||
removeRequest(e);
|
||||
}
|
||||
|
||||
function onRequestError(e) {
|
||||
removeRequest(e);
|
||||
}
|
||||
|
||||
function onRequestTimeout(e) {
|
||||
removeRequest(e);
|
||||
}
|
||||
|
||||
function onSourceAttached(e) {
|
||||
|
||||
onPlaybackEnded(null);
|
||||
|
||||
streamOptions = e.streamOptions;
|
||||
playbackStarted = false;
|
||||
}
|
||||
|
||||
function onPlaybackStarted(e) {
|
||||
|
||||
if (!streamOptions || !streamOptions.heartbeat.url) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (playbackStarted) {
|
||||
return;
|
||||
}
|
||||
playbackStarted = true;
|
||||
|
||||
createRequest('start');
|
||||
scheduleProgressRequest();
|
||||
}
|
||||
|
||||
function onPlaybackEnded(e) {
|
||||
|
||||
if (!streamOptions || !streamOptions.heartbeat.url) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!playbackStarted) {
|
||||
return;
|
||||
}
|
||||
playbackStarted = false;
|
||||
|
||||
createRequest('end');
|
||||
unscheduleProgressRequest();
|
||||
}
|
||||
|
||||
function onBeforeUnload(e) {
|
||||
onPlaybackEnded(null);
|
||||
}
|
||||
|
||||
function registerEventListeners() {
|
||||
|
||||
if (playerListenerInitialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!player) {
|
||||
return;
|
||||
}
|
||||
|
||||
playerListenerInitialized = true;
|
||||
|
||||
player.addEventListener('sourceAttached', onSourceAttached);
|
||||
player.addEventListener('play', onPlaybackStarted);
|
||||
player.addEventListener('ended', onPlaybackEnded);
|
||||
|
||||
window.addEventListener('unload', onBeforeUnload, false);
|
||||
}
|
||||
|
||||
function unregisterEventListeners() {
|
||||
|
||||
if (!playerListenerInitialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
playerListenerInitialized = false;
|
||||
|
||||
if (!player) {
|
||||
return;
|
||||
}
|
||||
|
||||
player.removeEventListener('sourceAttached', onSourceAttached);
|
||||
player.removeEventListener('play', onPlaybackStarted);
|
||||
player.removeEventListener('ended', onPlaybackEnded);
|
||||
|
||||
window.removeEventListener('unload', onBeforeUnload, false);
|
||||
}
|
||||
|
||||
function initialize() {
|
||||
registerEventListeners();
|
||||
}
|
||||
|
||||
function destroy() {
|
||||
|
||||
unregisterEventListeners();
|
||||
|
||||
unscheduleProgressRequest();
|
||||
abortProgressRequest();
|
||||
abortStartRequest();
|
||||
detachEndRequest();
|
||||
|
||||
streamOptions = null;
|
||||
playbackStarted = false;
|
||||
|
||||
global = null;
|
||||
options = null;
|
||||
player = null;
|
||||
}
|
||||
|
||||
return {
|
||||
initialize: initialize,
|
||||
destroy: destroy
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
* */
|
||||
@@ -3,7 +3,7 @@ import keycode from 'keycode'
|
||||
import VokaEvent from "@/constants/VokaEvent"
|
||||
const Plugin = videojs.getPlugin('plugin')
|
||||
|
||||
export class VokaKeyboard extends Plugin {
|
||||
export class VokaKeyboardPlugin extends Plugin {
|
||||
|
||||
private player!: VideoJsPlayer
|
||||
|
||||
@@ -64,4 +64,4 @@ export class VokaKeyboard extends Plugin {
|
||||
}
|
||||
}
|
||||
|
||||
videojs.registerPlugin('vokaKeyboard', VokaKeyboard)
|
||||
videojs.registerPlugin('vokaKeyboardPlugin', VokaKeyboardPlugin)
|
||||
@@ -0,0 +1,436 @@
|
||||
import videojs, { VideoJsPlayer, VideoJsPlayerOptions } from 'video.js'
|
||||
import VokaEvent from "@/constants/VokaEvent"
|
||||
const Plugin = videojs.getPlugin('plugin')
|
||||
|
||||
export class VokaMetricsPlugin extends Plugin {
|
||||
private player!: VideoJsPlayer
|
||||
|
||||
constructor(player: VideoJsPlayer, options: VideoJsPlayerOptions) {
|
||||
super(player, options)
|
||||
this.player = player
|
||||
// this.setupListeners()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
videojs.registerPlugin('vokaMetricsPlugin', VokaMetricsPlugin)
|
||||
|
||||
/*
|
||||
Player.Metrics = function (_global, _options, _player) {
|
||||
|
||||
'use strict';
|
||||
|
||||
var defaultApiHost = '127.0.0.1';
|
||||
|
||||
var global = _global;
|
||||
var options = _options;
|
||||
var player = _player;
|
||||
|
||||
var playerListenerInitialized = false;
|
||||
var streamOptions = null;
|
||||
var playbackInitialized = false;
|
||||
var playbackStarted = false;
|
||||
|
||||
var prevPlayerState = '';
|
||||
var prevStateTime = 0;
|
||||
var timeSpent = null;
|
||||
|
||||
var scheduledRequest = undefined;
|
||||
var defaultWatchSessionId = null;
|
||||
|
||||
function getApiUrl() {
|
||||
|
||||
var result;
|
||||
|
||||
if (!streamOptions) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// if (streamOptions.metrics.apiUrl) {
|
||||
// return streamOptions.metrics.apiUrl;
|
||||
// }
|
||||
//
|
||||
// result = streamOptions.metrics.apiHost;
|
||||
// if (!result) {
|
||||
result = defaultApiHost;
|
||||
// }
|
||||
|
||||
if (result.indexOf('//') < 0) {
|
||||
result = 'https://' + result;
|
||||
}
|
||||
result = result + '/v2/player';
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function getWatchSessionId() {
|
||||
if (streamOptions && streamOptions.metrics.params.watch_session_id) {
|
||||
return streamOptions.metrics.params.watch_session_id;
|
||||
}
|
||||
return defaultWatchSessionId;
|
||||
}
|
||||
|
||||
function getPlayerState() {
|
||||
|
||||
if (!player) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (!playbackInitialized) {
|
||||
return 'initial_buffering';
|
||||
}
|
||||
|
||||
if (!playbackStarted) {
|
||||
return 'paused';
|
||||
}
|
||||
|
||||
if (player.getPaused()) {
|
||||
return 'paused';
|
||||
}
|
||||
|
||||
if (player.getBufferingState()) {
|
||||
return 'freezed';
|
||||
}
|
||||
|
||||
return 'playing';
|
||||
}
|
||||
|
||||
function updateTimeSpent() {
|
||||
|
||||
var currTime;
|
||||
var diffTime;
|
||||
var propName;
|
||||
|
||||
if (!timeSpent) {
|
||||
timeSpent = {
|
||||
initializing_player: 0,
|
||||
initializing_buffer: 0,
|
||||
playing: 0,
|
||||
paused: 0,
|
||||
buffering: 0
|
||||
};
|
||||
}
|
||||
|
||||
currTime = Utils.getCurrTimeMS();
|
||||
|
||||
if (!prevStateTime) {
|
||||
prevStateTime = currTime;
|
||||
}
|
||||
|
||||
diffTime = currTime - prevStateTime;
|
||||
prevStateTime = currTime;
|
||||
|
||||
switch (prevPlayerState)
|
||||
{
|
||||
case 'initialization':
|
||||
propName = 'initializing_player';
|
||||
break;
|
||||
case 'initial_buffering':
|
||||
propName = 'initializing_buffer';
|
||||
break;
|
||||
case 'paused':
|
||||
propName = 'paused';
|
||||
break;
|
||||
case 'freezed':
|
||||
propName = 'buffering';
|
||||
break;
|
||||
case 'playing':
|
||||
propName = 'playing';
|
||||
break;
|
||||
default:
|
||||
propName = null;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!propName) {
|
||||
return;
|
||||
}
|
||||
|
||||
timeSpent[propName] += diffTime;
|
||||
}
|
||||
|
||||
function createRequest(state) {
|
||||
|
||||
var url;
|
||||
var request;
|
||||
var data;
|
||||
var timeout;
|
||||
var playerState;
|
||||
var osVersion;
|
||||
var deviceOS;
|
||||
var bandwidth;
|
||||
|
||||
if (!global || !options || !player || !streamOptions) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case 'init':
|
||||
playerState = 'initialization';
|
||||
break;
|
||||
case 'buffering':
|
||||
playerState = 'initial_buffering';
|
||||
break;
|
||||
case 'play':
|
||||
playerState = 'playing';
|
||||
break;
|
||||
case 'pause':
|
||||
playerState = 'paused';
|
||||
break;
|
||||
case 'periodic':
|
||||
case 'update':
|
||||
default:
|
||||
playerState = getPlayerState();
|
||||
break;
|
||||
}
|
||||
|
||||
if (state === 'update' && playerState === prevPlayerState) {
|
||||
return;
|
||||
}
|
||||
|
||||
updateTimeSpent();
|
||||
prevPlayerState = playerState;
|
||||
|
||||
if (state !== 'periodic') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (state === 'periodic') {
|
||||
timeout = streamOptions.metrics.interval * 2 * 1000;
|
||||
} else {
|
||||
timeout = 20000;
|
||||
}
|
||||
|
||||
osVersion = Utils.getOSVersion();
|
||||
deviceOS = osVersion.name.toLowerCase();
|
||||
|
||||
switch (deviceOS) {
|
||||
|
||||
case 'ios':
|
||||
case 'android':
|
||||
case 'windows':
|
||||
case 'macos':
|
||||
case 'linux':
|
||||
break;
|
||||
|
||||
default:
|
||||
deviceOS = 'other';
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
bandwidth = player.getNetworkBandwidth();
|
||||
if (isNaN(bandwidth)) {
|
||||
bandwidth = 0;
|
||||
} else {
|
||||
bandwidth *= 1000;
|
||||
}
|
||||
|
||||
data = {
|
||||
application_id: streamOptions.metrics.params.application_id,
|
||||
application_version: streamOptions.metrics.params.application_version,
|
||||
user_type: streamOptions.metrics.params.user_type,
|
||||
user_id: streamOptions.metrics.params.user_id,
|
||||
device_id: global.getDeviceId(),
|
||||
device_os: deviceOS,
|
||||
device_type: 'browser',
|
||||
device_player_type: 'native',
|
||||
application_session_id: player.getAppSessionId(),
|
||||
watch_session_id: getWatchSessionId(),
|
||||
resource_uid: streamOptions.metrics.params.resource_uid,
|
||||
resource_type: streamOptions.metrics.params.resource_type,
|
||||
buffered_duration: Math.floor(player.getBufferLength() * 1000),
|
||||
bandwidth: Math.floor(bandwidth),
|
||||
//player_state: playerState,
|
||||
time_spent: timeSpent,
|
||||
network_type: 'unknown'
|
||||
};
|
||||
|
||||
data = JSON.stringify(data);
|
||||
|
||||
url = getApiUrl();
|
||||
|
||||
// request = new XMLHttpRequest();
|
||||
// request.open('POST', url, true);
|
||||
//request.withCredentials = true;
|
||||
// request.timeout = timeout;
|
||||
// request.send(data);
|
||||
|
||||
timeSpent = null;
|
||||
}
|
||||
|
||||
function periodicRequest() {
|
||||
createRequest('periodic');
|
||||
}
|
||||
|
||||
function scheduleRequest() {
|
||||
|
||||
unscheduleRequest();
|
||||
|
||||
if (!streamOptions) {
|
||||
return;
|
||||
}
|
||||
|
||||
scheduledRequest = Utils.setInterval(periodicRequest, streamOptions.metrics.interval * 1000);
|
||||
}
|
||||
|
||||
function unscheduleRequest() {
|
||||
if (scheduledRequest === undefined) {
|
||||
return;
|
||||
}
|
||||
clearInterval(scheduledRequest);
|
||||
scheduledRequest = undefined;
|
||||
}
|
||||
|
||||
function scheduleRequestIfNeeded() {
|
||||
if (scheduledRequest !== undefined) {
|
||||
return;
|
||||
}
|
||||
scheduleRequest();
|
||||
}
|
||||
|
||||
function onSourceAttached(e) {
|
||||
|
||||
onPlaybackEnded(null);
|
||||
|
||||
streamOptions = e.streamOptions;
|
||||
playbackInitialized = false;
|
||||
playbackStarted = false;
|
||||
|
||||
prevPlayerState = '';
|
||||
prevStateTime = 0;
|
||||
timeSpent = null;
|
||||
|
||||
defaultWatchSessionId = Utils.generateGuid();
|
||||
scheduleRequestIfNeeded();
|
||||
|
||||
createRequest('init');
|
||||
createRequest('buffering');
|
||||
}
|
||||
|
||||
function onPlayerCanplay(e) {
|
||||
|
||||
if (!streamOptions) {
|
||||
return;
|
||||
}
|
||||
|
||||
playbackInitialized = true;
|
||||
|
||||
createRequest('update');
|
||||
scheduleRequestIfNeeded();
|
||||
}
|
||||
|
||||
function onPlaybackStarted(e) {
|
||||
|
||||
if (!streamOptions) {
|
||||
return;
|
||||
}
|
||||
|
||||
playbackInitialized = true;
|
||||
playbackStarted = true;
|
||||
|
||||
scheduleRequestIfNeeded();
|
||||
|
||||
createRequest('play');
|
||||
}
|
||||
|
||||
function onPlaybackPaused(e) {
|
||||
|
||||
if (!streamOptions) {
|
||||
return;
|
||||
}
|
||||
|
||||
scheduleRequestIfNeeded();
|
||||
|
||||
createRequest('pause');
|
||||
}
|
||||
|
||||
function onPlaybackEnded(e) {
|
||||
|
||||
unscheduleRequest();
|
||||
|
||||
playbackStarted = false;
|
||||
}
|
||||
|
||||
function onPlayerBufferingUpdate(e) {
|
||||
|
||||
if (!streamOptions) {
|
||||
return;
|
||||
}
|
||||
|
||||
createRequest('update');
|
||||
}
|
||||
|
||||
function registerEventListeners() {
|
||||
|
||||
if (playerListenerInitialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!player) {
|
||||
return;
|
||||
}
|
||||
|
||||
playerListenerInitialized = true;
|
||||
|
||||
player.addEventListener('sourceAttached', onSourceAttached);
|
||||
player.addEventListener('canplay', onPlayerCanplay);
|
||||
player.addEventListener('play', onPlaybackStarted);
|
||||
player.addEventListener('pause', onPlaybackPaused);
|
||||
player.addEventListener('ended', onPlaybackEnded);
|
||||
player.addEventListener('bufferingUpdate', onPlayerBufferingUpdate);
|
||||
}
|
||||
|
||||
function unregisterEventListeners() {
|
||||
|
||||
if (!playerListenerInitialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
playerListenerInitialized = false;
|
||||
|
||||
if (!player) {
|
||||
return;
|
||||
}
|
||||
|
||||
player.removeEventListener('sourceAttached', onSourceAttached);
|
||||
player.removeEventListener('canplay', onPlayerCanplay);
|
||||
player.removeEventListener('play', onPlaybackStarted);
|
||||
player.removeEventListener('pause', onPlaybackPaused);
|
||||
player.removeEventListener('ended', onPlaybackEnded);
|
||||
player.removeEventListener('bufferingUpdate', onPlayerBufferingUpdate);
|
||||
}
|
||||
|
||||
function initialize() {
|
||||
registerEventListeners();
|
||||
}
|
||||
|
||||
function destroy() {
|
||||
|
||||
unregisterEventListeners();
|
||||
|
||||
unscheduleRequest();
|
||||
defaultWatchSessionId = null;
|
||||
|
||||
streamOptions = null;
|
||||
playbackInitialized = false;
|
||||
playbackStarted = false;
|
||||
|
||||
prevPlayerState = '';
|
||||
prevStateTime = 0;
|
||||
timeSpent = null;
|
||||
|
||||
global = null;
|
||||
options = null;
|
||||
player = null;
|
||||
}
|
||||
|
||||
return {
|
||||
initialize: initialize,
|
||||
destroy: destroy
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
**/
|
||||
Reference in New Issue
Block a user