send events when video buffers
This commit is contained in:
parent
9aab2092e6
commit
75410392d8
5 changed files with 127 additions and 5 deletions
|
@ -51,7 +51,8 @@
|
|||
"electron-updater": "^4.1.2",
|
||||
"express": "^4.17.1",
|
||||
"if-env": "^1.0.4",
|
||||
"keytar": "^4.4.1"
|
||||
"keytar": "^4.4.1",
|
||||
"videojs-event-tracking": "^1.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.0.0",
|
||||
|
|
|
@ -28,6 +28,8 @@ type Analytics = {
|
|||
apiLogView: (string, string, string, ?number, ?() => void) => Promise<any>,
|
||||
apiLogPublish: (ChannelClaim | StreamClaim) => void,
|
||||
tagFollowEvent: (string, boolean, string) => void,
|
||||
videoStartEvent: (string, number) => void,
|
||||
videoBufferEvent: (string, number) => void,
|
||||
emailProvidedEvent: () => void,
|
||||
emailVerifiedEvent: () => void,
|
||||
rewardEligibleEvent: () => void,
|
||||
|
@ -127,6 +129,12 @@ const analytics: Analytics = {
|
|||
Lbryio.call('feedback', 'search', { query, vote });
|
||||
}
|
||||
},
|
||||
videoStartEvent: (claimId, duration) => {
|
||||
sendGaEvent('Media', 'StartDelay', claimId, duration);
|
||||
},
|
||||
videoBufferEvent: (claimId, currentTime) => {
|
||||
sendGaEvent('Media', 'BufferTimestamp', claimId, currentTime);
|
||||
},
|
||||
tagFollowEvent: (tag, following, location) => {
|
||||
sendGaEvent(following ? 'Tag-Follow' : 'Tag-Unfollow', tag);
|
||||
},
|
||||
|
@ -154,13 +162,14 @@ const analytics: Analytics = {
|
|||
},
|
||||
};
|
||||
|
||||
function sendGaEvent(category, action, label) {
|
||||
function sendGaEvent(category, action, label, value) {
|
||||
if (analyticsEnabled && isProduction) {
|
||||
ReactGA.event(
|
||||
{
|
||||
category,
|
||||
action,
|
||||
...(label ? { label } : {}),
|
||||
...(value ? { value } : {}),
|
||||
},
|
||||
[SECOND_TRACKER_NAME]
|
||||
);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { connect } from 'react-redux';
|
||||
import { makeSelectFileInfoForUri, makeSelectThumbnailForUri } from 'lbry-redux';
|
||||
import { makeSelectClaimForUri, makeSelectFileInfoForUri, makeSelectThumbnailForUri } from 'lbry-redux';
|
||||
import { doChangeVolume, doChangeMute } from 'redux/actions/app';
|
||||
import { selectVolume, selectMute } from 'redux/selectors/app';
|
||||
import { savePosition, doSetPlayingUri } from 'redux/actions/content';
|
||||
|
@ -12,6 +12,7 @@ const select = (state, props) => ({
|
|||
muted: selectMute(state),
|
||||
hasFileInfo: Boolean(makeSelectFileInfoForUri(props.uri)(state)),
|
||||
thumbnail: makeSelectThumbnailForUri(props.uri)(state),
|
||||
claim: makeSelectClaimForUri(props.uri)(state),
|
||||
});
|
||||
|
||||
const perform = dispatch => ({
|
||||
|
|
|
@ -3,7 +3,9 @@ import React, { useRef, useEffect, useState } from 'react';
|
|||
import { stopContextMenu } from 'util/context-menu';
|
||||
import videojs from 'video.js/dist/alt/video.core.novtt.min.js';
|
||||
import 'video.js/dist/alt/video-js-cdn.min.css';
|
||||
import eventTracking from 'videojs-event-tracking';
|
||||
import isUserTyping from 'util/detect-typing';
|
||||
import analytics from 'analytics';
|
||||
|
||||
const F11_KEYCODE = 122;
|
||||
const SPACE_BAR_KEYCODE = 32;
|
||||
|
@ -42,10 +44,23 @@ type Props = {
|
|||
thumbnail: string,
|
||||
hasFileInfo: boolean,
|
||||
onEndedCB: any,
|
||||
claim: Claim,
|
||||
};
|
||||
|
||||
function VideoViewer(props: Props) {
|
||||
const { contentType, source, setPlayingUri, onEndedCB, changeVolume, changeMute, volume, muted, thumbnail } = props;
|
||||
const {
|
||||
contentType,
|
||||
source,
|
||||
setPlayingUri,
|
||||
onEndedCB,
|
||||
changeVolume,
|
||||
changeMute,
|
||||
volume,
|
||||
muted,
|
||||
thumbnail,
|
||||
claim,
|
||||
} = props;
|
||||
const claimId = claim && claim.claim_id;
|
||||
const videoRef = useRef();
|
||||
const isAudio = contentType.includes('audio');
|
||||
let forceTypes = [
|
||||
|
@ -65,6 +80,10 @@ function VideoViewer(props: Props) {
|
|||
useEffect(() => {
|
||||
const currentVideo: HTMLVideoElement | null = document.querySelector('video');
|
||||
|
||||
if (!Object.keys(videojs.getPlugins()).includes('eventTracking')) {
|
||||
videojs.registerPlugin('eventTracking', eventTracking);
|
||||
}
|
||||
|
||||
function doEnded() {
|
||||
// clear position
|
||||
setPlayingUri(null);
|
||||
|
@ -105,6 +124,7 @@ function VideoViewer(props: Props) {
|
|||
type: forceMp4 ? 'video/mp4' : contentType,
|
||||
},
|
||||
],
|
||||
plugins: { eventTracking: true },
|
||||
};
|
||||
|
||||
if (isAudio) {
|
||||
|
@ -185,6 +205,30 @@ function VideoViewer(props: Props) {
|
|||
// include requireRedraw here so the event listener is re-added when we need to manually remove/add the video player
|
||||
}, [videoRef, requireRedraw]);
|
||||
|
||||
// player analytics
|
||||
useEffect(() => {
|
||||
function doTrackingBuffered(e: Event, data: any) {
|
||||
analytics.videoBufferEvent(claimId, data.currentTime);
|
||||
}
|
||||
function doTrackingFirstPlay(e: Event, data: any) {
|
||||
analytics.videoStartEvent(claimId, data.secondsToLoad);
|
||||
}
|
||||
function doError(e: Event) {
|
||||
console.log('ERROR', e);
|
||||
}
|
||||
if (player) {
|
||||
player.on('tracking:buffered', (e, d) => doTrackingBuffered(e, d));
|
||||
player.on('tracking:firstplay', (e, d) => doTrackingFirstPlay(e, d));
|
||||
player.on('error', e => doError(e));
|
||||
}
|
||||
return () => {
|
||||
if (player) {
|
||||
player.off();
|
||||
}
|
||||
};
|
||||
// include requireRedraw here so the event listener is re-added when we need to manually remove/add the video player
|
||||
}, [player]);
|
||||
|
||||
return (
|
||||
<div className="file-render__viewer" onContextMenu={stopContextMenu}>
|
||||
{!requireRedraw && (
|
||||
|
|
69
yarn.lock
69
yarn.lock
|
@ -909,6 +909,13 @@
|
|||
dependencies:
|
||||
regenerator-runtime "^0.13.2"
|
||||
|
||||
"@babel/runtime@^7.4.5":
|
||||
version "7.8.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.8.3.tgz#0811944f73a6c926bb2ad35e918dcc1bfab279f1"
|
||||
integrity sha512-fVHx1rzEmwB130VTkLnxR+HmxcTjGzH12LYQcFFoBwakMd3aOMD4OsRN7tGG/UOYE2ektgFrS8uACAoRk1CY0w==
|
||||
dependencies:
|
||||
regenerator-runtime "^0.13.2"
|
||||
|
||||
"@babel/runtime@^7.6.3":
|
||||
version "7.7.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.7.4.tgz#b23a856751e4bf099262f867767889c0e3fe175b"
|
||||
|
@ -1214,6 +1221,19 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.14.1.tgz#0d8a53f308f017c53a5ddc3d07f4d6fa76b790d7"
|
||||
integrity sha512-0Ki9jAAhKDSuLDXOIMADg54Hu60SuBTEsWaJGGy5cV+SSUQ63J2a+RrYYGrErzz39fXzTibhKrAQJAb8M7PNcA==
|
||||
|
||||
"@videojs/http-streaming@1.10.6":
|
||||
version "1.10.6"
|
||||
resolved "https://registry.yarnpkg.com/@videojs/http-streaming/-/http-streaming-1.10.6.tgz#a9119b1828b354c5cc17b42ea051cc7bcce2dca0"
|
||||
integrity sha512-uPBuunHnxWeFRYxRX0j6h1IIWv3+QKvSkZGmW9TvqxWBqeNGSrQymR6tm1nVjQ2HhMVxVphQTUhUTTPDVWqmQg==
|
||||
dependencies:
|
||||
aes-decrypter "3.0.0"
|
||||
global "^4.3.0"
|
||||
m3u8-parser "4.4.0"
|
||||
mpd-parser "0.8.1"
|
||||
mux.js "5.2.1"
|
||||
url-toolkit "^2.1.3"
|
||||
video.js "^6.8.0 || ^7.0.0"
|
||||
|
||||
"@videojs/http-streaming@1.9.3":
|
||||
version "1.9.3"
|
||||
resolved "https://registry.yarnpkg.com/@videojs/http-streaming/-/http-streaming-1.9.3.tgz#c971050495fb58d2b4c6ee0246bb03cc750635b1"
|
||||
|
@ -7472,6 +7492,13 @@ m3u8-parser@4.3.0:
|
|||
dependencies:
|
||||
global "^4.3.2"
|
||||
|
||||
m3u8-parser@4.4.0:
|
||||
version "4.4.0"
|
||||
resolved "https://registry.yarnpkg.com/m3u8-parser/-/m3u8-parser-4.4.0.tgz#adf606c0af6d97f6750095a42006c2ae03dde177"
|
||||
integrity sha512-iH2AygTFILtato+XAgnoPYzLHM4R3DjATj7Ozbk7EHdB2XoLF2oyOUguM7Kc4UVHbQHHL/QPaw98r7PbWzG0gg==
|
||||
dependencies:
|
||||
global "^4.3.2"
|
||||
|
||||
macos-release@^2.2.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/macos-release/-/macos-release-2.2.0.tgz#ab58d55dd4714f0a05ad4b0e90f4370fef5cdea8"
|
||||
|
@ -7909,6 +7936,14 @@ mpd-parser@0.7.0:
|
|||
global "^4.3.2"
|
||||
url-toolkit "^2.1.1"
|
||||
|
||||
mpd-parser@0.8.1:
|
||||
version "0.8.1"
|
||||
resolved "https://registry.yarnpkg.com/mpd-parser/-/mpd-parser-0.8.1.tgz#db299dbec337999fbbbace989d227c7b03dc8ea7"
|
||||
integrity sha512-WBTJ1bKk8OLUIxBh6s1ju1e2yz/5CzhPbgi6P3F3kJHKhGy1Z+ElvEnuzEbtC/dnbRcJtMXazE3f93N5LLdp9Q==
|
||||
dependencies:
|
||||
global "^4.3.2"
|
||||
url-toolkit "^2.1.1"
|
||||
|
||||
ms@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
|
||||
|
@ -7947,6 +7982,11 @@ mux.js@5.1.1:
|
|||
resolved "https://registry.yarnpkg.com/mux.js/-/mux.js-5.1.1.tgz#0e95f048b4ac51d413c9ddc2d78e4cefad8d06de"
|
||||
integrity sha512-Mf/UYmh5b8jvUP+jmrTbETnyFZprMdbT0RxKm/lJ/4d2Q3xdc5GaHaRPI1zVV5D3+6uxArVPm78QEb1RsrmaQw==
|
||||
|
||||
mux.js@5.2.1:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/mux.js/-/mux.js-5.2.1.tgz#6698761fc88da5acecea0758ac25f11d3a08bee8"
|
||||
integrity sha512-1t2payD3Y8izfZRq7tfUQlhL2fKzjeLr9v1/2qNCTkEQnd9Abtn1JgzsBgGZubEXh6lM5L8B0iLGoWQiukjtbQ==
|
||||
|
||||
nan@2.13.2:
|
||||
version "2.13.2"
|
||||
resolved "https://registry.yarnpkg.com/nan/-/nan-2.13.2.tgz#f51dc7ae66ba7d5d55e1e6d4d8092e802c9aefe7"
|
||||
|
@ -12641,12 +12681,39 @@ vfile@^2.0.0:
|
|||
videojs-vtt.js "0.14.1"
|
||||
xhr "2.4.0"
|
||||
|
||||
video.js@^7.0.0:
|
||||
version "7.6.6"
|
||||
resolved "https://registry.yarnpkg.com/video.js/-/video.js-7.6.6.tgz#e7c9163d53f9b0e05ccb5ac0f79d02fa49b4d3ac"
|
||||
integrity sha512-AXzHwymhvMpS7c7rF29u0j0/3tSs+v2gIk5UY8OkiDHSEHL7T0+t3hid4JHW7aGvTruUUgwyf4C74cX2RDL1Pw==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.4.5"
|
||||
"@videojs/http-streaming" "1.10.6"
|
||||
global "4.3.2"
|
||||
keycode "^2.2.0"
|
||||
safe-json-parse "4.0.0"
|
||||
videojs-font "3.2.0"
|
||||
videojs-vtt.js "^0.14.1"
|
||||
xhr "2.4.0"
|
||||
|
||||
videojs-event-tracking@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/videojs-event-tracking/-/videojs-event-tracking-1.0.1.tgz#382e8b1293d32021f3bac65c4310ee454a659bcf"
|
||||
integrity sha512-SdL4utk5U3S8PNTXFiJtlZeR4L4DbJxjK+1fv7ugLMw7v20NZbp1S0ag+9fHJCKSQrkc2QkXUqSZHXpqwkw/3Q==
|
||||
dependencies:
|
||||
global "^4.3.2"
|
||||
video.js "^7.0.0"
|
||||
|
||||
videojs-font@3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/videojs-font/-/videojs-font-3.1.0.tgz#ac33be9b517fe19299f61cccd2b3c7d75a1c6960"
|
||||
integrity sha512-rxB68SVgbHD+kSwoNWNCHicKJuR2ga3bGfvGxmB+8fupsiLbnyCwTBVtrZUq4bZnD64mrKP1DxHiutxwrs59pQ==
|
||||
|
||||
videojs-vtt.js@0.14.1:
|
||||
videojs-font@3.2.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/videojs-font/-/videojs-font-3.2.0.tgz#212c9d3f4e4ec3fa7345167d64316add35e92232"
|
||||
integrity sha512-g8vHMKK2/JGorSfqAZQUmYYNnXmfec4MLhwtEFS+mMs2IDY398GLysy6BH6K+aS1KMNu/xWZ8Sue/X/mdQPliA==
|
||||
|
||||
videojs-vtt.js@0.14.1, videojs-vtt.js@^0.14.1:
|
||||
version "0.14.1"
|
||||
resolved "https://registry.yarnpkg.com/videojs-vtt.js/-/videojs-vtt.js-0.14.1.tgz#da583eb1fc9c81c826a9432b706040e8dea49911"
|
||||
integrity sha512-YxOiywx6N9t3J5nqsE5WN2Sw4CSqVe3zV+AZm2T4syOc2buNJaD6ZoexSdeszx2sHLU/RRo2r4BJAXFDQ7Qo2Q==
|
||||
|
|
Loading…
Add table
Reference in a new issue