Anthony watchman integration #6799
3 changed files with 38 additions and 30 deletions
|
@ -17,6 +17,9 @@ const devInternalApis = process.env.LBRY_API_URL && process.env.LBRY_API_URL.inc
|
|||
export const SHARE_INTERNAL = 'shareInternal';
|
||||
const SHARE_THIRD_PARTY = 'shareThirdParty';
|
||||
|
||||
const WATCHMAN_BACKEND_ENDPOINT = 'https://watchman.na-backend.odysee.com/reports/playback';
|
||||
const SEND_DATA_TO_WATCHMAN_INTERVAL = 30; // in seconds
|
||||
|
||||
// @if TARGET='app'
|
||||
if (isProduction) {
|
||||
ElectronCookies.enable({
|
||||
|
@ -97,63 +100,77 @@ function getDeviceType() {
|
|||
// default as web, this can be optimized
|
||||
return 'web';
|
||||
}
|
||||
|
||||
let durationInSeconds = 10;
|
||||
// variables initialized for watchman
|
||||
let amountOfBufferEvents = 0;
|
||||
let amountOfBufferTimeInMS = 0;
|
||||
let videoType, userId, claimUrl, playerPoweredBy, timeAtBuffer, videoPlayer;
|
||||
let videoType, userId, claimUrl, playerPoweredBy, videoPlayer;
|
||||
let lastSentTime;
|
||||
|
||||
// calculate data for backend, send them, and reset buffer data for next interval
|
||||
async function sendAndResetWatchmanData() {
|
||||
var protocol;
|
||||
if (!userId) {
|
||||
return 'Can only be used with a user id'
|
||||
}
|
||||
|
||||
let timeSinceLastIntervalSend = new Date() - lastSentTime;
|
||||
console.log(timeSinceLastIntervalSend);
|
||||
lastSentTime = new Date();
|
||||
|
||||
let protocol;
|
||||
if (videoType === 'application/x-mpegURL') {
|
||||
protocol = 'hls';
|
||||
} else {
|
||||
protocol = 'stb';
|
||||
}
|
||||
|
||||
console.log(claimUrl);
|
||||
// current position in video in MS
|
||||
const positionInVideo = Math.round(videoPlayer.currentTime()) * 1000;
|
||||
|
||||
|
||||
timeAtBuffer = Math.round(videoPlayer.currentTime()) * 1000;
|
||||
|
||||
var totalDurationInSeconds = Math.round(videoPlayer.duration());
|
||||
// get the duration marking the time in the video for relative position calculation
|
||||
const totalDurationInSeconds = Math.round(videoPlayer.duration());
|
||||
|
||||
// build object for watchman backend
|
||||
const objectToSend = {
|
||||
rebuf_count: amountOfBufferEvents,
|
||||
rebuf_duration: amountOfBufferTimeInMS,
|
||||
url: claimUrl.replace('lbry://', ''),
|
||||
device: getDeviceType(),
|
||||
duration: Math.round(durationInSeconds) * 1000,
|
||||
duration: timeSinceLastIntervalSend,
|
||||
protocol,
|
||||
player: playerPoweredBy,
|
||||
user_id: userId.toString(),
|
||||
position: Math.round(timeAtBuffer),
|
||||
rel_position: Math.round((timeAtBuffer / (totalDurationInSeconds * 1000)) * 100),
|
||||
position: Math.round(positionInVideo),
|
||||
rel_position: Math.round((positionInVideo / (totalDurationInSeconds * 1000)) * 100),
|
||||
};
|
||||
|
||||
// post to watchman
|
||||
await sendWatchmanData(objectToSend);
|
||||
|
||||
// reset buffer data
|
||||
amountOfBufferEvents = 0;
|
||||
amountOfBufferTimeInMS = 0;
|
||||
timeAtBuffer = null;
|
||||
}
|
||||
|
||||
let watchmanInterval;
|
||||
// clear watchman interval and mark it as null (when video paused)
|
||||
function stopWatchmanInterval() {
|
||||
console.log('turning off watchman interval');
|
||||
clearInterval(watchmanInterval);
|
||||
watchmanInterval = null;
|
||||
}
|
||||
|
||||
// creates the setInterval that will run send to watchman on recurring basis
|
||||
function startWatchmanIntervalIfNotRunning() {
|
||||
console.log('turning on watchman interval');
|
||||
if (!watchmanInterval) {
|
||||
console.log('watchman interval turned back on');
|
||||
watchmanInterval = setInterval(sendAndResetWatchmanData, 1000 * durationInSeconds);
|
||||
lastSentTime = new Date();
|
||||
|
||||
watchmanInterval = setInterval(sendAndResetWatchmanData, 1000 * SEND_DATA_TO_WATCHMAN_INTERVAL);
|
||||
}
|
||||
}
|
||||
|
||||
// post data to the backend
|
||||
async function sendWatchmanData(body) {
|
||||
try {
|
||||
const response = await fetch('https://watchman.na-backend.odysee.com/reports/playback', {
|
||||
const response = await fetch(WATCHMAN_BACKEND_ENDPOINT, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
|
@ -164,18 +181,16 @@ async function sendWatchmanData(body) {
|
|||
|
||||
return response;
|
||||
} catch (err) {
|
||||
console.log('ERROR FROM WATCHMAN BACKEND');
|
||||
console.log(err);
|
||||
}
|
||||
}
|
||||
|
||||
const analytics: Analytics = {
|
||||
// receive buffer events from tracking plugin and jklj
|
||||
videoBufferEvent: async (claim, data) => {
|
||||
console.log('BUFFERING!');
|
||||
|
||||
amountOfBufferEvents = amountOfBufferEvents + 1;
|
||||
amountOfBufferTimeInMS = amountOfBufferTimeInMS + data.bufferDuration;
|
||||
|
||||
timeAtBuffer = data.timeAtBuffer;
|
||||
},
|
||||
onDispose: () => {
|
||||
stopWatchmanInterval();
|
||||
|
@ -210,10 +225,9 @@ const analytics: Analytics = {
|
|||
} else if (isPlaying && !playerIsSeeking) {
|
||||
startWatchmanIntervalIfNotRunning();
|
||||
}
|
||||
|
||||
},
|
||||
videoStartEvent: (claimId, duration, poweredBy, passedUserId, canonicalUrl, passedPlayer) => {
|
||||
console.log('Video start');
|
||||
// populate values for watchman when video starts
|
||||
userId = passedUserId;
|
||||
claimUrl = canonicalUrl;
|
||||
playerPoweredBy = poweredBy;
|
||||
|
@ -221,9 +235,6 @@ const analytics: Analytics = {
|
|||
videoType = passedPlayer.currentSource().type;
|
||||
videoPlayer = passedPlayer;
|
||||
|
||||
console.log(userId, canonicalUrl, playerPoweredBy);
|
||||
|
||||
// TODO: add claim url , userId
|
||||
sendPromMetric('time_to_start', duration);
|
||||
sendMatomoEvent('Media', 'TimeToStart', claimId, duration);
|
||||
},
|
||||
|
|
|
@ -15,8 +15,7 @@ const select = (state, props) => {
|
|||
const { search } = props.location;
|
||||
const urlParams = new URLSearchParams(search);
|
||||
const autoplay = urlParams.get('autoplay');
|
||||
// get the position that will be used to start the video at, if t variable or saved in state
|
||||
// TODO: save and load this position from the db so can be used in display and
|
||||
// TODO: eventually this should be received from DB and not local state (https://github.com/lbryio/lbry-desktop/issues/6796)
|
||||
const position = urlParams.get('t') !== null ? urlParams.get('t') : makeSelectContentPositionForUri(props.uri)(state);
|
||||
const userId = selectUser(state) && selectUser(state).id;
|
||||
|
||||
|
|
|
@ -134,8 +134,6 @@ function VideoViewer(props: Props) {
|
|||
}
|
||||
|
||||
function doTrackingFirstPlay(e: Event, data: any) {
|
||||
console.log('running here');
|
||||
console.log(userId);
|
||||
|
||||
let timeToStart = data.secondsToLoad;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue
This sort of thing, if tested elsewhere should use a constant, make a new file in constants if necessary.