New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@segment/analytics.js-video-plugins

Package Overview
Dependencies
Maintainers
128
Versions
18
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@segment/analytics.js-video-plugins - npm Package Compare versions

Comparing version

to
0.2.1

712

dist/index.umd.js

@@ -1,711 +0,1 @@

(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else if(typeof exports === 'object')
exports["analyticsVideoPlugins"] = factory();
else
root["analyticsVideoPlugins"] = factory();
})(window, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ }
/******/ };
/******/
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function(exports) {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/
/******/ // create a fake namespace object
/******/ // mode & 1: value is a module id, require it
/******/ // mode & 2: merge all properties of value into the ns
/******/ // mode & 4: return value when already ns object
/******/ // mode & 8|1: behave like require
/******/ __webpack_require__.t = function(value, mode) {
/******/ if(mode & 1) value = __webpack_require__(value);
/******/ if(mode & 8) return value;
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ var ns = Object.create(null);
/******/ __webpack_require__.r(ns);
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ return ns;
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 2);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
var index = typeof fetch=='function' ? fetch.bind() : function(url, options) {
options = options || {};
return new Promise( function (resolve, reject) {
var request = new XMLHttpRequest();
request.open(options.method || 'get', url, true);
for (var i in options.headers) {
request.setRequestHeader(i, options.headers[i]);
}
request.withCredentials = options.credentials=='include';
request.onload = function () {
resolve(response());
};
request.onerror = reject;
request.send(options.body);
function response() {
var keys = [],
all = [],
headers = {},
header;
request.getAllResponseHeaders().replace(/^(.*?):[^\S\n]*([\s\S]*?)$/gm, function (m, key, value) {
keys.push(key = key.toLowerCase());
all.push([key, value]);
header = headers[key];
headers[key] = header ? (header + "," + value) : value;
});
return {
ok: (request.status/100|0) == 2, // 200-299
status: request.status,
statusText: request.statusText,
url: request.responseURL,
clone: response,
text: function () { return Promise.resolve(request.responseText); },
json: function () { return Promise.resolve(request.responseText).then(JSON.parse); },
blob: function () { return Promise.resolve(new Blob([request.response])); },
headers: {
keys: function () { return keys; },
entries: function () { return all; },
get: function (n) { return headers[n.toLowerCase()]; },
has: function (n) { return n.toLowerCase() in headers; }
}
};
}
});
};
/* harmony default export */ __webpack_exports__["default"] = (index);
//# sourceMappingURL=unfetch.es.js.map
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var VideoPlugin = function () {
function VideoPlugin(name, version) {
_classCallCheck(this, VideoPlugin);
this.pluginName = name;
}
_createClass(VideoPlugin, [{
key: "track",
value: function track(event, properties) {
window.analytics.track(event, properties, {
integration: {
name: this.pluginName
}
});
}
}]);
return VideoPlugin;
}();
exports.default = VideoPlugin;
/***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.YouTubeAnalytics = exports.VimeoAnalytics = undefined;
var _vimeo = __webpack_require__(3);
var _vimeo2 = _interopRequireDefault(_vimeo);
var _youtube = __webpack_require__(4);
var _youtube2 = _interopRequireDefault(_youtube);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
exports.VimeoAnalytics = _vimeo2.default;
exports.YouTubeAnalytics = _youtube2.default;
/***/ }),
/* 3 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _unfetch = __webpack_require__(0);
var _unfetch2 = _interopRequireDefault(_unfetch);
var _plugin = __webpack_require__(1);
var _plugin2 = _interopRequireDefault(_plugin);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var VimeoAnalytics = function (_Plugin) {
_inherits(VimeoAnalytics, _Plugin);
function VimeoAnalytics(player, authToken) {
_classCallCheck(this, VimeoAnalytics);
var _this = _possibleConstructorReturn(this, (VimeoAnalytics.__proto__ || Object.getPrototypeOf(VimeoAnalytics)).call(this, "VimeoAnalytics"));
_this.authToken = authToken;
_this.player = player;
_this.metadata = {
content: {},
playback: { videoPlayer: "Vimeo" }
};
_this.mostRecentHeartbeat = 0;
_this.isPaused = false;
return _this;
}
_createClass(VimeoAnalytics, [{
key: "initialize",
value: function initialize() {
var _this2 = this;
var events = {
loaded: this.retrieveMetadata,
play: this.trackPlay,
pause: this.trackPause,
ended: this.trackEnded,
timeupdate: this.trackHeartbeat
};
for (var event in events) {
this.registerHandler(event, events[event]);
}
this.player.getVideoId().then(function (id) {
_this2.retrieveMetadata({ id: id });
}).catch(console.error);
}
// This is a helper function used to facilitate easier testing.
}, {
key: "registerHandler",
value: function registerHandler(event, handler) {
var _this3 = this;
this.player.on(event, function (data) {
_this3.updateMetadata(data);
handler.call(_this3, data);
});
}
}, {
key: "trackPlay",
value: function trackPlay() {
if (this.isPaused) {
this.track("Video Playback Resumed", this.metadata.playback);
this.isPaused = false;
} else {
this.track("Video Playback Started", this.metadata.playback);
this.track("Video Content Started", this.metadata.content);
}
}
}, {
key: "trackEnded",
value: function trackEnded() {
this.track("Video Playback Completed", this.metadata.playback);
this.track("Video Content Completed", this.metadata.content);
}
// Vimeo provides time updates every 250ms while Segment documents sending heartbeats every 10s.
// Therefore, we need to do some math to ensure we are not sending 4 heartbeat events when we reach
// 10 second intervals.
}, {
key: "trackHeartbeat",
value: function trackHeartbeat() {
var mostRecentHeartbeat = this.mostRecentHeartbeat;
var currentPosition = this.metadata.playback.position;
if (currentPosition !== mostRecentHeartbeat && currentPosition - mostRecentHeartbeat >= 10) {
this.track("Video Content Playing", this.metadata.content);
this.mostRecentHeartbeat = Math.floor(currentPosition);
}
}
}, {
key: "trackPause",
value: function trackPause() {
this.isPaused = true;
this.track("Video Playback Paused", this.metadata.playback);
}
// retrieve static video metadata from vimeo API
}, {
key: "retrieveMetadata",
value: function retrieveMetadata(data) {
var _this4 = this;
return new Promise(function (resolve, reject) {
var videoId = data.id;
(0, _unfetch2.default)("https://api.vimeo.com/videos/" + videoId, {
headers: {
Authorization: "Bearer " + _this4.authToken
}
}).then(function (res) {
if (res.ok) {
return res.json();
}
return reject(res);
}).then(function (json) {
_this4.metadata.content.title = json.name;
_this4.metadata.content.description = json.description;
_this4.metadata.content.publisher = json.user.name;
_this4.metadata.playback.position = 0;
_this4.metadata.playback.totalLength = json.duration;
}).catch(function (err) {
console.error("Request to Vimeo API Failed with: ", err);
return reject(err);
});
});
}
// update dynamic video information
}, {
key: "updateMetadata",
value: function updateMetadata(data) {
var _this5 = this;
return new Promise(function (resolve, reject) {
_this5.player.getVolume().then(function (volume) {
if (volume) _this5.metadata.playback.sound = volume * 100;
_this5.metadata.playback.position = data.seconds;
resolve();
}).catch(reject);
});
}
}]);
return VimeoAnalytics;
}(_plugin2.default);
exports.default = VimeoAnalytics;
/***/ }),
/* 4 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _unfetch = __webpack_require__(0);
var _unfetch2 = _interopRequireDefault(_unfetch);
var _plugin = __webpack_require__(1);
var _plugin2 = _interopRequireDefault(_plugin);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var SEEK_THRESHOLD = 2000;
var YouTubeAnalytics = function (_VideoPlugin) {
_inherits(YouTubeAnalytics, _VideoPlugin);
/**
* Creates a YouTube video plugin to track events directly from the player.
*
* @param {YT.Player} player YouTube IFrame Player (docs: https://developers.google.com/youtube/iframe_api_reference#Loading_a_Video_Player).
* @param {String} apiKey Youtube Data API key (docs: https://developers.google.com/youtube/registering_an_application).
*/
function YouTubeAnalytics(player, apiKey) {
_classCallCheck(this, YouTubeAnalytics);
var _this = _possibleConstructorReturn(this, (YouTubeAnalytics.__proto__ || Object.getPrototypeOf(YouTubeAnalytics)).call(this, "YoutubeAnalytics"));
_this.player = player;
_this.apiKey = apiKey;
_this.playerLoaded = false;
_this.playbackStarted = false;
_this.contentStarted = false;
_this.isPaused = false;
_this.isBuffering = false;
_this.isSeeking = false;
_this.lastRecordedTime = {
// updated every event
timeReported: Date.now(),
timeElapsed: 0.0
};
_this.metadata = [{ playback: { video_player: "youtube" }, content: {} }];
_this.playlistIndex = 0;
return _this;
}
_createClass(YouTubeAnalytics, [{
key: "initialize",
value: function initialize() {
// Youtube API requires listeners to exist as top-level props on window object
window.segmentYoutubeOnStateChange = this.onPlayerStateChange.bind(this);
window.segmentYoutubeOnReady = this.onPlayerReady.bind(this);
this.player.addEventListener("onReady", "segmentYoutubeOnReady");
this.player.addEventListener("onStateChange", "segmentYoutubeOnStateChange");
}
}, {
key: "onPlayerReady",
value: function onPlayerReady(event) {
// this fires when the player html element loads
this.retrieveMetadata();
}
// yt reports events via state changes in the player rather than explicitly EVENTS like 'play', 'pause', etc
}, {
key: "onPlayerStateChange",
value: function onPlayerStateChange(event) {
var currentTime = this.player.getCurrentTime();
if (this.metadata[this.playlistIndex]) {
this.metadata[this.playlistIndex].playback.position = this.metadata[this.playlistIndex].content.position = currentTime;
this.metadata[this.playlistIndex].playback.quality = this.player.getPlaybackQuality();
this.metadata[this.playlistIndex].playback.sound = this.player.isMuted() ? 0 : this.player.getVolume();
}
switch (event.data) {
case -1:
// this fires when a video or playlist has loaded
if (this.playerLoaded) break;
this.retrieveMetadata();
this.playerLoaded = true;
break;
case YT.PlayerState.BUFFERING:
this.handleBuffer();
break;
case YT.PlayerState.PLAYING:
this.handlePlay();
break;
case YT.PlayerState.PAUSED:
this.handlePause();
break;
case YT.PlayerState.ENDED:
this.handleEnd();
break;
}
this.lastRecordedTime = {
timeReported: Date.now(),
timeElapsed: this.player.getCurrentTime() * 1000.0
};
}
/**
* Retrieves the video metadata from Youtube Data API using user's API Key
* docs: https://developers.google.com/youtube/v3/docs/videos/list
*
* @returns {Promise} A promise that resolves in a metadata object from the video
* contained in the player.
*/
}, {
key: "retrieveMetadata",
value: function retrieveMetadata() {
var _this2 = this;
return new Promise(function (resolve, reject) {
var videoData = _this2.player.getVideoData();
var playlist = _this2.player.getPlaylist() || [videoData.video_id];
var videoIds = playlist.join();
(0, _unfetch2.default)("https://www.googleapis.com/youtube/v3/videos?id=" + videoIds + "&part=snippet,contentDetails&key=" + _this2.apiKey).then(function (res) {
if (!res.ok) {
var err = new Error("Segment request to Youtube API failed (likely due to a bad API Key. Events will still be sent but will not contain video metadata)");
err.response = res;
throw err;
}
return res.json();
}).then(function (json) {
_this2.metadata = [];
var total_length = 0;
for (var i = 0; i < playlist.length; i++) {
var videoInfo = json.items[i];
_this2.metadata.push({
content: {
title: videoInfo.snippet.title,
description: videoInfo.snippet.description,
keywords: videoInfo.snippet.tags,
channel: videoInfo.snippet.channelTitle,
airdate: videoInfo.snippet.publishedAt
}
});
total_length += YTDurationToSeconds(videoInfo.contentDetails.duration);
}
for (var i = 0; i < playlist.length; i++) {
_this2.metadata[i].playback = {
total_length: total_length,
video_player: "youtube"
};
}
resolve();
}).catch(function (err) {
_this2.metadata = playlist.map(function (item) {
return { playback: { video_player: "youtube" }, content: {} };
});
reject(err);
});
});
}
}, {
key: "handleBuffer",
value: function handleBuffer() {
var seekDetected = this.determineSeek();
if (!this.playbackStarted) {
this.playbackStarted = true;
this.track("Video Playback Started", this.metadata[this.playlistIndex].playback);
}
// user used keyboard to seek or seeked while video was paused
if (seekDetected && !this.isSeeking) {
this.isSeeking = true;
this.track("Video Playback Seek Started", this.metadata[this.playlistIndex].playback);
}
// state changing to BUFFERING denotes seeking has completed
if (this.isSeeking) {
this.track("Video Playback Seek Completed", this.metadata[this.playlistIndex].playback);
this.isSeeking = false;
}
// user clicked next video button (not possible in single video playback)
var playlist = this.player.getPlaylist();
if (playlist && this.player.getCurrentTime() === 0 && this.player.getPlaylistIndex() !== this.playlistIndex) {
this.contentStarted = false;
if (this.playlistIndex === playlist.length - 1 && this.player.getPlaylistIndex() === 0) {
// user skipped to end of last video in playlist
this.track("Video Playback Completed", this.metadata[this.player.getPlaylistIndex()].playback);
this.track("Video Playback Started", this.metadata[this.player.getPlaylistIndex()].playback); // playlist automatically starts from beginning
}
}
this.track("Video Playback Buffer Started", this.metadata[this.playlistIndex].playback);
this.isBuffering = true;
}
}, {
key: "handlePlay",
value: function handlePlay() {
if (!this.contentStarted) {
this.playlistIndex = this.player.getPlaylistIndex(); // will return -1 if the player has a singular video instead of a playlist
if (this.playlistIndex === -1) this.playlistIndex = 0;
this.track("Video Content Started", this.metadata[this.playlistIndex].content);
this.contentStarted = true;
}
if (this.isBuffering) {
this.track("Video Playback Buffer Completed", this.metadata[this.playlistIndex].playback);
this.isBuffering = false;
}
if (this.isPaused) {
this.track("Video Playback Resumed", this.metadata[this.playlistIndex].playback);
this.isPaused = false;
}
}
}, {
key: "handlePause",
value: function handlePause() {
var seekDetected = this.determineSeek();
// user seeked while video was paused, it buffered, and then finished buffering
if (this.isBuffering) {
this.track("Video Playback Buffer Completed", this.metadata[this.playlistIndex].playback);
this.isBuffering = false;
}
if (!this.isPaused) {
// user seeked while video was playing
if (seekDetected) {
this.track("Video Playback Seek Started", this.metadata[this.playlistIndex].playback);
this.isSeeking = true;
}
// user clicked pause while video was playing
else {
this.track("Video Playback Paused", this.metadata[this.playlistIndex].playback);
this.isPaused = true;
}
}
}
}, {
key: "handleEnd",
value: function handleEnd() {
this.track("Video Content Completed", this.metadata[this.playlistIndex].content);
this.contentStarted = false;
var playlistIndex = this.player.getPlaylistIndex();
var playlist = this.player.getPlaylist();
if (playlist && playlistIndex === playlist.length - 1 || playlistIndex === -1) {
this.track("Video Playback Completed", this.metadata[this.playlistIndex].playback);
this.playbackStarted = false;
}
}
// yt doesn't natively track seeking so we have to manually calculate whether a seek has occurred based on expected vs actual event timestamps
}, {
key: "determineSeek",
value: function determineSeek() {
var expectedTimeElapsed = this.isPaused || this.isBuffering ? 0 : Date.now() - this.lastRecordedTime.timeReported;
var actualTimeElapsed = this.player.getCurrentTime() * 1000.0 - this.lastRecordedTime.timeElapsed;
return Math.abs(expectedTimeElapsed - actualTimeElapsed) > SEEK_THRESHOLD; // if the diff btwn the 2 is > the threshold we can reasonably assume a seek has occurred
}
}]);
return YouTubeAnalytics;
}(_plugin2.default);
// convert from ISO 8601 to seconds
exports.default = YouTubeAnalytics;
function YTDurationToSeconds(duration) {
var match = duration.match(/PT(\d+H)?(\d+M)?(\d+S)?/);
match = match.slice(1).map(function (x) {
if (x != null) {
return x.replace(/\D/, "");
}
});
var hours = parseInt(match[0]) || 0;
var minutes = parseInt(match[1]) || 0;
var seconds = parseInt(match[2]) || 0;
return hours * 3600 + minutes * 60 + seconds;
}
/***/ })
/******/ ]);
});
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.analyticsVideoPlugins=t():e.analyticsVideoPlugins=t()}(window,(function(){return function(e){var t={};function a(n){if(t[n])return t[n].exports;var i=t[n]={i:n,l:!1,exports:{}};return e[n].call(i.exports,i,i.exports,a),i.l=!0,i.exports}return a.m=e,a.c=t,a.d=function(e,t,n){a.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.t=function(e,t){if(1&t&&(e=a(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(a.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)a.d(n,i,function(t){return e[t]}.bind(null,i));return n},a.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(t,"a",t),t},a.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},a.p="",a(a.s=2)}([function(e,t,a){"use strict";a.r(t);var n="function"==typeof fetch?fetch.bind():function(e,t){return t=t||{},new Promise((function(a,n){var i=new XMLHttpRequest;for(var r in i.open(t.method||"get",e,!0),t.headers)i.setRequestHeader(r,t.headers[r]);function o(){var e,t=[],a=[],n={};return i.getAllResponseHeaders().replace(/^(.*?):[^\S\n]*([\s\S]*?)$/gm,(function(i,r,o){t.push(r=r.toLowerCase()),a.push([r,o]),e=n[r],n[r]=e?e+","+o:o})),{ok:2==(i.status/100|0),status:i.status,statusText:i.statusText,url:i.responseURL,clone:o,text:function(){return Promise.resolve(i.responseText)},json:function(){return Promise.resolve(i.responseText).then(JSON.parse)},blob:function(){return Promise.resolve(new Blob([i.response]))},headers:{keys:function(){return t},entries:function(){return a},get:function(e){return n[e.toLowerCase()]},has:function(e){return e.toLowerCase()in n}}}}i.withCredentials="include"==t.credentials,i.onload=function(){a(o())},i.onerror=n,i.send(t.body)}))};t.default=n},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=function(){function e(e,t){for(var a=0;a<t.length;a++){var n=t[a];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}return function(t,a,n){return a&&e(t.prototype,a),n&&e(t,n),t}}();var i=function(){function e(t,a){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.pluginName=t}return n(e,[{key:"track",value:function(e,t){window.analytics.track(e,t,{integration:{name:this.pluginName}})}}]),e}();t.default=i},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.YouTubeAnalytics=t.VimeoAnalytics=void 0;var n=r(a(3)),i=r(a(4));function r(e){return e&&e.__esModule?e:{default:e}}t.VimeoAnalytics=n.default,t.YouTubeAnalytics=i.default},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=function(){function e(e,t){for(var a=0;a<t.length;a++){var n=t[a];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}return function(t,a,n){return a&&e(t.prototype,a),n&&e(t,n),t}}(),i=r(a(0));function r(e){return e&&e.__esModule?e:{default:e}}var o=function(e){function t(e,a){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t);var n=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,"VimeoAnalytics"));return n.authToken=a,n.player=e,n.metadata={content:{},playback:{videoPlayer:"Vimeo"}},n.mostRecentHeartbeat=0,n.isPaused=!1,n}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,e),n(t,[{key:"initialize",value:function(){var e=this,t={loaded:this.retrieveMetadata,play:this.trackPlay,pause:this.trackPause,ended:this.trackEnded,timeupdate:this.trackHeartbeat};for(var a in t)this.registerHandler(a,t[a]);this.player.getVideoId().then((function(t){e.retrieveMetadata({id:t})})).catch(console.error)}},{key:"registerHandler",value:function(e,t){var a=this;this.player.on(e,(function(e){a.updateMetadata(e),t.call(a,e)}))}},{key:"trackPlay",value:function(){this.isPaused?(this.track("Video Playback Resumed",this.metadata.playback),this.isPaused=!1):(this.track("Video Playback Started",this.metadata.playback),this.track("Video Content Started",this.metadata.content))}},{key:"trackEnded",value:function(){this.track("Video Playback Completed",this.metadata.playback),this.track("Video Content Completed",this.metadata.content)}},{key:"trackHeartbeat",value:function(){var e=this.mostRecentHeartbeat,t=this.metadata.playback.position;t!==e&&t-e>=10&&(this.track("Video Content Playing",this.metadata.content),this.mostRecentHeartbeat=Math.floor(t))}},{key:"trackPause",value:function(){this.isPaused=!0,this.track("Video Playback Paused",this.metadata.playback)}},{key:"retrieveMetadata",value:function(e){var t=this;return new Promise((function(a,n){var r=e.id;(0,i.default)("https://api.vimeo.com/videos/"+r,{headers:{Authorization:"Bearer "+t.authToken}}).then((function(e){return e.ok?e.json():n(e)})).then((function(e){t.metadata.content.title=e.name,t.metadata.content.description=e.description,t.metadata.content.publisher=e.user.name,t.metadata.playback.position=0,t.metadata.playback.totalLength=e.duration})).catch((function(e){return console.error("Request to Vimeo API Failed with: ",e),n(e)}))}))}},{key:"updateMetadata",value:function(e){var t=this;return new Promise((function(a,n){t.player.getVolume().then((function(n){n&&(t.metadata.playback.sound=100*n),t.metadata.playback.position=e.seconds,a()})).catch(n)}))}}]),t}(r(a(1)).default);t.default=o},function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=function(){function e(e,t){for(var a=0;a<t.length;a++){var n=t[a];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}return function(t,a,n){return a&&e(t.prototype,a),n&&e(t,n),t}}(),i=o(a(0)),r=o(a(1));function o(e){return e&&e.__esModule?e:{default:e}}var s=function(e){function t(e,a){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t);var n=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,"YoutubeAnalytics"));return n.player=e,n.apiKey=a,n.playerLoaded=!1,n.playbackStarted=!1,n.contentStarted=!1,n.isPaused=!1,n.isBuffering=!1,n.isSeeking=!1,n.lastRecordedTime={timeReported:Date.now(),timeElapsed:0},n.metadata=[{playback:{video_player:"youtube"},content:{}}],n.playlistIndex=0,n}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,e),n(t,[{key:"initialize",value:function(){window.segmentYoutubeOnStateChange=this.onPlayerStateChange.bind(this),window.segmentYoutubeOnReady=this.onPlayerReady.bind(this),this.player.addEventListener("onReady","segmentYoutubeOnReady"),this.player.addEventListener("onStateChange","segmentYoutubeOnStateChange")}},{key:"onPlayerReady",value:function(e){this.retrieveMetadata()}},{key:"onPlayerStateChange",value:function(e){var t=this.player.getCurrentTime();switch(this.metadata[this.playlistIndex]&&(this.metadata[this.playlistIndex].playback.position=this.metadata[this.playlistIndex].content.position=t,this.metadata[this.playlistIndex].playback.quality=this.player.getPlaybackQuality(),this.metadata[this.playlistIndex].playback.sound=this.player.isMuted()?0:this.player.getVolume()),e.data){case-1:if(this.playerLoaded)break;this.retrieveMetadata(),this.playerLoaded=!0;break;case YT.PlayerState.BUFFERING:this.handleBuffer();break;case YT.PlayerState.PLAYING:this.handlePlay();break;case YT.PlayerState.PAUSED:this.handlePause();break;case YT.PlayerState.ENDED:this.handleEnd()}this.lastRecordedTime={timeReported:Date.now(),timeElapsed:1e3*this.player.getCurrentTime()}}},{key:"retrieveMetadata",value:function(){var e=this;return new Promise((function(t,a){var n=e.player.getVideoData(),r=e.player.getPlaylist()||[n.video_id],o=r.join();(0,i.default)("https://www.googleapis.com/youtube/v3/videos?id="+o+"&part=snippet,contentDetails&key="+e.apiKey).then((function(e){if(!e.ok){var t=new Error("Segment request to Youtube API failed (likely due to a bad API Key. Events will still be sent but will not contain video metadata)");throw t.response=e,t}return e.json()})).then((function(a){e.metadata=[];for(var n=0,i=0;i<r.length;i++){var o=a.items[i];e.metadata.push({content:{title:o.snippet.title,description:o.snippet.description,keywords:o.snippet.tags,channel:o.snippet.channelTitle,airdate:o.snippet.publishedAt}}),n+=l(o.contentDetails.duration)}for(i=0;i<r.length;i++)e.metadata[i].playback={total_length:n,video_player:"youtube"};t()})).catch((function(t){e.metadata=r.map((function(e){return{playback:{video_player:"youtube"},content:{}}})),a(t)}))}))}},{key:"handleBuffer",value:function(){var e=this.determineSeek();this.playbackStarted||(this.playbackStarted=!0,this.track("Video Playback Started",this.metadata[this.playlistIndex].playback)),e&&!this.isSeeking&&(this.isSeeking=!0,this.track("Video Playback Seek Started",this.metadata[this.playlistIndex].playback)),this.isSeeking&&(this.track("Video Playback Seek Completed",this.metadata[this.playlistIndex].playback),this.isSeeking=!1);var t=this.player.getPlaylist();t&&0===this.player.getCurrentTime()&&this.player.getPlaylistIndex()!==this.playlistIndex&&(this.contentStarted=!1,this.playlistIndex===t.length-1&&0===this.player.getPlaylistIndex()&&(this.track("Video Playback Completed",this.metadata[this.player.getPlaylistIndex()].playback),this.track("Video Playback Started",this.metadata[this.player.getPlaylistIndex()].playback))),this.track("Video Playback Buffer Started",this.metadata[this.playlistIndex].playback),this.isBuffering=!0}},{key:"handlePlay",value:function(){this.contentStarted||(this.playlistIndex=this.player.getPlaylistIndex(),-1===this.playlistIndex&&(this.playlistIndex=0),this.track("Video Content Started",this.metadata[this.playlistIndex].content),this.contentStarted=!0),this.isBuffering&&(this.track("Video Playback Buffer Completed",this.metadata[this.playlistIndex].playback),this.isBuffering=!1),this.isPaused&&(this.track("Video Playback Resumed",this.metadata[this.playlistIndex].playback),this.isPaused=!1)}},{key:"handlePause",value:function(){var e=this.determineSeek();this.isBuffering&&(this.track("Video Playback Buffer Completed",this.metadata[this.playlistIndex].playback),this.isBuffering=!1),this.isPaused||(e?(this.track("Video Playback Seek Started",this.metadata[this.playlistIndex].playback),this.isSeeking=!0):(this.track("Video Playback Paused",this.metadata[this.playlistIndex].playback),this.isPaused=!0))}},{key:"handleEnd",value:function(){this.track("Video Content Completed",this.metadata[this.playlistIndex].content),this.contentStarted=!1;var e=this.player.getPlaylistIndex(),t=this.player.getPlaylist();(t&&e===t.length-1||-1===e)&&(this.track("Video Playback Completed",this.metadata[this.playlistIndex].playback),this.playbackStarted=!1)}},{key:"determineSeek",value:function(){var e=this.isPaused||this.isBuffering?0:Date.now()-this.lastRecordedTime.timeReported,t=1e3*this.player.getCurrentTime()-this.lastRecordedTime.timeElapsed;return Math.abs(e-t)>2e3}}]),t}(r.default);function l(e){var t=e.match(/PT(\d+H)?(\d+M)?(\d+S)?/);return t=t.slice(1).map((function(e){if(null!=e)return e.replace(/\D/,"")})),3600*(parseInt(t[0])||0)+60*(parseInt(t[1])||0)+(parseInt(t[2])||0)}t.default=s}])}));

2

package.json
{
"name": "@segment/analytics.js-video-plugins",
"version": "0.2.0",
"version": "0.2.1",
"description": "",

@@ -5,0 +5,0 @@ "scripts": {

@@ -11,3 +11,3 @@ module.exports = {

optimization: {
minimize: false
minimize: true
},

@@ -14,0 +14,0 @@ module: {