in web/reactplayer/src/sdk/QoSSDK.js [3:414]
export var SDK = function(playerComponent) {
var player = playerComponent;
// console.log(player);
//----- common functions & variables-----
var sdk = this,
connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
var getConnectionType = function() {
return {
type: connection ? connection.type || connection.effectiveType : "not available",
rtt: connection ? connection.rtt : -1
};
},
resetVideo = function(videoId) {
return {
videoId: videoId,
previousTime: 0,
currentTime: 0,
seekStart: null,
seekStartTime: 0,
seekEndTime: 0,
loadStarted: 0,
dataLoaded: null,
percentSeen: 0,
packageType: null,
avgBitrate: 0,
duration: 0,
resolution: null,
frameRate: 0,
bufferStarted:0,
};
},
resetUser = function(userId) {
return {
cognitoId: userId,
firstNAme: '',
lastName: ''
};
},
getUser = function() {
// console.log("In getUser");
var userId = aws.getUserId();
// console.log("User id ",userId);
if(userId){
displayMetrics("User Id : ", userId);
}
return userId;
},
initialize = function(videoId) {
console.log("In initialize :",videoId);
currentVideo = resetVideo(videoId);
currentUser = resetUser(getUser());
// console.log("Current user :",currentUser);
commonAttr = {
user_id: currentUser.cognitoId,
video_id: currentVideo.videoId
};
},
//----- Push metrics to Firehose -----
sendToAWS = function(calculatedMetrics) {
// console.log("Sending Data To AWS ...");
console.log(calculatedMetrics);
aws.push(calculatedMetrics, function(error, data) {
if (error) {
console.log("error");
}
});
},
currentUser = resetUser(),
currentVideo = resetVideo(),
commonAttr = {},
// cdnTrackingId = '',
connectionType = getConnectionType();
//-----Defining the Metrics -----
var Metric = function(MetricType, MetricValue) {
//structure of the metric object
var metric = {
MetricType,
...MetricValue,
...commonAttr,
TimeStamp: Date.now()
// isotimestamp: (new Date()).toISOString()
};
return metric;
},
MetricType = ["PLAY","FIRSTFRAME", "SEEK", "BUFFER", "STREAM", "STEP", "PAUSE", "ERROR", "STOP"],
PLAY = {
at: '',//playback position
duration: '',
},
FIRSTFRAME = {
rtt: '',//round trip time
connection_type: '',//3g or 4g
package: '', //HLS or DASH
resolution: '',
fps: '',
avg_bitrate: '',
time_millisecond: '',
cdn_tracking_id: '',
},
SEEK = {
seek_from: '',
seek_to: '',
rtt: '',
connection_type: '',
time_millisecond: '',
cdn_tracking_id: ''
},
BUFFER = {
buffer_type: '',
at: '',//playback position
rtt: '',
connection_type: '',
time_millisecond: '',
cdn_tracking_id: ''
},
STREAM = {
at: '',
rtt: '',
connection_type: '',
package: '',
// aspect_ratio: '',
resolution: '',
fps: '',
avg_bitrate: '',
duration: '',
cdn_tracking_id:''
},
STEP = {
at: '',//playback position
bitrate_from: '',
bitrate_to: '',
direction: '',//quality UP or DOWN
package: '',
resolution: '',
fps: '',
connection_type: '',
},
STOP = {
at: '',
duration: '',
connection_type: '',
package: '',
// aspect_ratio: '',
resolution: '',
fps: '',
avg_bitrate: '',
},
PAUSE = {
at: '',
duration: '',
},
ERROR = {
at: '',
message: '',
cdn_tracking_id: ''
},
MetricValue = {
FIRSTFRAME,
SEEK,
PLAY,
BUFFER,
PAUSE,
ERROR,
STOP,
STREAM,
STEP
},
setMetricValue = function(metericName, args) {
var metricObj = MetricValue[metericName];
var index = 0;
for (var key in metricObj) {
metricObj[key] = args[index++];
}
return metricObj;
};
//-----Defining the player event function handlers ------
var play = function(playlistType) {
console.log("In play with playlistType ",playlistType);
displayMetrics("Video Start at ", new Date().toLocaleTimeString());
var metericName = "PLAY";
//set whether the video being played is VOD or Live
commonAttr.playlist_type = playlistType;
var metricValue = setMetricValue(metericName, [currentVideo.currentTime, currentVideo.duration]);
var calculatedMetric = Metric(metericName, metricValue);
return sendToAWS(calculatedMetric);
},
loadStarted = function() {
currentVideo.loadStarted = Date.now();
},
loadeddata = function(duration, packageType, playbackAttr, cdn_request_id, rtt) {
currentVideo.packageType = packageType.toUpperCase();
if(playbackAttr["AVERAGE-BANDWIDTH"]){
currentVideo.avgBitrate = parseInt(playbackAttr["AVERAGE-BANDWIDTH"]);
}
else{
currentVideo.avgBitrate = 0;
}
currentVideo.duration = duration;
currentVideo.resolution = parseResolution(playbackAttr);
currentVideo.frameRate = playbackAttr["FRAME-RATE"];
var dataloadedTime = Date.now();
if (!currentVideo.dataLoaded) {
timeToFirstFrame(playbackAttr, dataloadedTime - currentVideo.loadStarted, cdn_request_id, rtt);
}
currentVideo.dataLoaded = dataloadedTime;
},
timeToFirstFrame = function(playbackAttr, time, cdn_request_id, rtt) {
displayMetrics("Time to First Frame ", time + ' ms');
var metericName = "FIRSTFRAME";
connectionType = getConnectionType();
var metricValue = setMetricValue(metericName, [rtt, connectionType.type, currentVideo.packageType, currentVideo.resolution,
playbackAttr["FRAME-RATE"], playbackAttr["AVERAGE-BANDWIDTH"], time, cdn_request_id
]);
var calculatedMetric = Metric(metericName, metricValue);
return sendToAWS(calculatedMetric);
},
buffering = function(time) {
if(time === 0){
displayMetrics("Initial buffering..", '');
}
else{
displayMetrics("Buffering at :", time);
}
currentVideo.isBuffering = true;
currentVideo.bufferStarted = Date.now();
},
bufferCompleted = function(cdn_request_id, rtt) {
var time = currentVideo.currentTime;
if (currentVideo.isBuffering) {
var bufferingTime = Date.now() - currentVideo.bufferStarted;
updateBufferStatus("ScreenFreezedBuffer", bufferingTime, time, cdn_request_id, rtt);
} else {
firstBufferCompleted(time, cdn_request_id, rtt );
}
if (currentVideo.seekStart) {
seeked(currentVideo.previousTime);
}
return currentVideo.isBuffering = false;
},
updateBufferStatus = function(bufferType, timeTakenToBuffer, time, cdn_request_id, rtt) {
var metericName = "BUFFER";
connectionType = getConnectionType();
var metricValue = setMetricValue(metericName, [bufferType, time, rtt, connectionType.type, timeTakenToBuffer, cdn_request_id]);
var calculatedMetric = Metric(metericName, metricValue);
// displayMetrics("Completed " + bufferType + " at :", new Date().toLocaleTimeString());
displayMetrics(bufferType + " ready in :", timeTakenToBuffer + " ms");
return sendToAWS(calculatedMetric);
},
firstBufferCompleted = function(time, cdn_request_id, rtt) {
var timeTakenToBuffer = Date.now() - currentVideo.loadStarted;
return updateBufferStatus("FirstBuffer", timeTakenToBuffer, currentVideo.currentTime, cdn_request_id, rtt);
},
step = function(playbackAttr, packageType, time) {
var metericName = "STEP";
let newAvgBitrate = 0;
if(playbackAttr["AVERAGE-BANDWIDTH"]){
newAvgBitrate = parseInt(playbackAttr["AVERAGE-BANDWIDTH"])
}
else{
newAvgBitrate = 0;
}
// let newAvgBitrate = parseInt(playbackAttr["AVERAGE-BANDWIDTH"]);
let direction;
currentVideo.packageType = packageType.toUpperCase();
//if current bitrate is 0, then its the step down operation
//at the start of play
if(currentVideo.avgBitrate === 0){
direction = 'DOWN';
}
else{
direction = (currentVideo.avgBitrate > newAvgBitrate) ? 'DOWN' : 'UP';
}
connectionType = getConnectionType();
var metricValue = setMetricValue(metericName, [currentVideo.currentTime, currentVideo.avgBitrate, newAvgBitrate, direction, currentVideo.packageType, currentVideo.resolution, currentVideo.frameRate, connectionType.type]);
// playbackAttr["FRAME-RATE"]
var calculatedMetric = Metric(metericName, metricValue);
//set the new Avg Bitrate being streamed
currentVideo.avgBitrate = parseInt(newAvgBitrate);
displayMetrics("Bitrate Step " + direction + " at :", currentVideo.currentTime);
return sendToAWS(calculatedMetric);
},
timeUpdate = function(time, duration, cdn_request_id,rtt) {
currentVideo.previousTime = currentVideo.currentTime;
currentVideo.currentTime = time;
var intPlayedTime = parseInt(time, 10);
if (currentVideo.percentSeen !== intPlayedTime) {
currentVideo.percentSeen = intPlayedTime;
captureStreamingLogs(currentVideo.packageType, currentVideo.resolution, currentVideo.frameRate, currentVideo.avgBitrate, currentVideo.duration,cdn_request_id,rtt);
}
},
captureStreamingLogs = function(stream_package, resolution, fps, bitrate, duration,cdn_request_id,rtt) {
var metericName = "STREAM";
connectionType = getConnectionType();
var metricValue = setMetricValue(metericName, [currentVideo.currentTime, rtt, connectionType.type, stream_package, resolution, fps, bitrate, duration, cdn_request_id]);
displayMetrics("Streaming at :", currentVideo.currentTime);
var calculatedMetric = Metric(metericName, metricValue);
return sendToAWS(calculatedMetric);
},
seeking = function() {
if (currentVideo.seekStart === null) {
currentVideo.seekStart = currentVideo.previousTime;
currentVideo.seekStartTime = Date.now();
}
currentVideo.isBuffering = true;
},
seeked = function(currentTime,cdn_request_id,rtt) {
var timeTakenToSeek = Date.now() - currentVideo.seekStartTime;
displayMetrics('Seeked from ', currentVideo.seekStart + ' to ' + currentTime + ' in ' + timeTakenToSeek + ' ms');
updateSeekStatus(currentTime, timeTakenToSeek,cdn_request_id,rtt);
return currentVideo.seekStart = null;
},
updateSeekStatus = function(currentTime, timeTakenToSeek,cdn_request_id,rtt) {
var metericName = "SEEK";
connectionType = getConnectionType();
var metricValue = setMetricValue(metericName, [currentVideo.seekStart, currentTime, rtt, connectionType.type, timeTakenToSeek, cdn_request_id]);
var calculatedMetric = Metric(metericName, metricValue);
return sendToAWS(calculatedMetric);
},
pause = function() {
//to avoid firing pause metric which is also called when video playback is //finished
if (currentVideo.currentTime === currentVideo.duration) return;
displayMetrics("Video Paused at ", currentVideo.currentTime);
var metericName = "PAUSE";
var metricValue = setMetricValue(metericName, [currentVideo.currentTime, currentVideo.duration]);
var calculatedMetric = Metric(metericName, metricValue);
return sendToAWS(calculatedMetric);
},
ended = function(currentTime, duration) {
var text = '';
if (currentTime === duration) {
text = "Finished playing at";
stop(currentTime);
} else {
text = "Video Ended with some error at "
errorOccured(currentTime, text + new Date().toUTCString());
}
displayMetrics(text, new Date().toLocaleTimeString());
// return stop();
},
stop = function(time) {
displayMetrics("Video Stopped at ", time);
var metericName = "STOP";
connectionType = getConnectionType();
var metricValue = setMetricValue(metericName, [time, currentVideo.duration, connectionType.type, currentVideo.packageType, currentVideo.resolution, currentVideo.frameRate, currentVideo.avgBitrate]);
var calculatedMetric = Metric(metericName, metricValue);
return sendToAWS(calculatedMetric);
},
parseResolution = function(playbackAttr) {
return playbackAttr.RESOLUTION.width + "x" + playbackAttr.RESOLUTION.height;
},
errorOccured = function(time, cdn_request_id, error) {
var text = "Some thing went wrong at ";
displayMetrics(text, new Date().toLocaleTimeString());
error = error || text + new Date().toUTCString();
var metericName = "ERROR";
var metricValue = setMetricValue(metericName, [time, "Error", cdn_request_id]);
var calculatedMetric = Metric(metericName, metricValue);
return sendToAWS(calculatedMetric);
};
//-------------------------------All Functions exposed by SDK when you create an object -------------------------------------------------------------------------------------------
sdk.play = play;
sdk.pause = pause;
sdk.stop = stop;
sdk.errorOccured = errorOccured;
sdk.ended = ended;
sdk.bufferCompleted = bufferCompleted;
sdk.loadeddata = loadeddata;
sdk.loadStarted = loadStarted;
sdk.seeked = seeked;
sdk.seeking = seeking;
sdk.timeUpdate = timeUpdate;
sdk.buffering = buffering;
sdk.initialize = initialize;
sdk.step = step;
sdk.getUser = getUser;
//-----Extendable Functions to create push custom metrics-----
// var publishCustomMetric = function(MetricType, MetricValue) {
// MetricType = MetricType.toLocaleUpperCase();
// var calculatedMetric = Metric(MetricType, MetricValue);
// displayMetrics("Custom metric " + MetricType + " published at", new Date().toLocaleTimeString());
// return sendToAWS(calculatedMetric);
// }
//
// sdk.publishCustomMetric = publishCustomMetric;
//-----This is used to show activities on screen-----
var displayMetrics = function(data, value) {
player.addTrail(data, value);
}
sdk.displayMetrics = displayMetrics;
return sdk;
};