rizzo-next
Version:
The next generation of Lonely Planet's style guide and pattern library.
506 lines (434 loc) • 16.2 kB
JavaScript
"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 _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
var _video_player = require("./video_player");
var _video_player2 = _interopRequireDefault(_video_player);
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; } /* global videojs */
var Brightcove = function (_VideoPlayer) {
_inherits(Brightcove, _VideoPlayer);
function Brightcove() {
_classCallCheck(this, Brightcove);
return _possibleConstructorReturn(this, (Brightcove.__proto__ || Object.getPrototypeOf(Brightcove)).apply(this, arguments));
}
_createClass(Brightcove, [{
key: "initialize",
value: function initialize(options) {
_get(Brightcove.prototype.__proto__ || Object.getPrototypeOf(Brightcove.prototype), "initialize", this).call(this, options);
this.videos = [];
this.currentVideoIndex = null;
this.events["click .video-js"] = "onClickVideo";
}
}, {
key: "onClickVideo",
value: function onClickVideo(event) {
// Prevent event from bubbling into the UI
// when the user interacts with the video.
event.stopPropagation();
}
}, {
key: "play",
value: function play() {
_get(Brightcove.prototype.__proto__ || Object.getPrototypeOf(Brightcove.prototype), "play", this).call(this);
this.autoplay = true;
var promise = this.player.play();
// Catch any errors thrown within play promise (only applicable on some browsers)
if (promise) {
promise.catch(function (reason) {
return console.log("VIDEOJS:", reason);
}).then(function () {});
}
}
}, {
key: "pause",
value: function pause() {
_get(Brightcove.prototype.__proto__ || Object.getPrototypeOf(Brightcove.prototype), "pause", this).call(this);
this.autoplay = false;
this.player.pause();
}
}, {
key: "start",
value: function start() {
this.currentVideoIndex = null;
this.autoplay = true;
this.loadNextVideo();
}
}, {
key: "setup",
value: function setup() {
if (!this.videoId) {
this.trigger("ready");
} else if (!this.videoEl) {
// Insert brightcove player html
var html = "<video ";
if (this.videoId) {
html += "data-video-id='" + this.videoId + "' ";
}
html += "data-account='5104226627001' ";
html += "data-player='default' ";
html += "data-embed='default' ";
html += "data-application-id ";
html += "class='video-js' ";
html += "></video>";
this.el.innerHTML = html;
// Insert script to initialize brightcove player
var scriptId = this.getPlayerScriptId();
var scriptSrc = "https://players.brightcove.net/5104226627001/default_default/index.min.js";
var script = document.createElement("script");
script.id = scriptId;
script.src = scriptSrc;
script.onload = this.onLoadSetupScript.bind(this);
document.body.appendChild(script);
} else if (!this.player) {
this.player = videojs(this.videoEl);
// We don't show the controls until the player is instantiated
// or else the controls show briefly without the brightcove theme applied.
this.player.controls(true);
this.player.on("loadstart", this.onPlayerLoadStart.bind(this));
this.player.on("playing", this.onPlayerPlaying.bind(this));
this.player.on("ended", this.onPlayerEnded.bind(this));
this.player.on("ads-ad-started", this.onAdStarted.bind(this));
this.player.on("ads-ad-ended", this.onAdEnded.bind(this));
this.player.ready(this.onPlayerReady.bind(this));
}
}
}, {
key: "dispose",
value: function dispose() {
var scriptId = this.getPlayerScriptId();
var script = document.getElementById(scriptId);
if (script) {
script.remove();
}
if (this.player) {
this.player.dispose();
this.player = null;
}
this.trigger("disposed", this);
}
}, {
key: "getPlayerScriptId",
value: function getPlayerScriptId() {
return "video__initialize-" + this.playerId;
}
}, {
key: "onLoadSetupScript",
value: function onLoadSetupScript() {
this.setup();
}
}, {
key: "onPlayerReady",
value: function onPlayerReady() {
this.currentVideoIndex = null;
this.loadNextVideo();
this.trigger("ready");
}
}, {
key: "onPlayerCueChange",
value: function onPlayerCueChange() {
var tt = this.player.textTracks()[0];
var activeCue = tt.activeCues[0];
if (!activeCue || activeCue.text !== "CODE") {
return;
}
var cue = activeCue.originalCuePoint;
var overlayElementId = "ad-lowerthird-" + this.playerId + "-" + cue.id;
var element = document.getElementById(overlayElementId);
if (!element) {
return;
}
var cueIndex = null;
this.getCues().forEach(function (c, i) {
if (c.originalCuePoint.id === cue.id) {
cueIndex = i;
}
});
if (cueIndex === null) {
return;
}
window.lp.analytics.dfp.video.lowerThird(cueIndex + 1, overlayElementId);
}
}, {
key: "onPlayerLoadStart",
value: function onPlayerLoadStart() {
var tt = this.player.textTracks()[0];
if (tt) {
tt.oncuechange = this.onPlayerCueChange.bind(this);
}
this.renderSEOMarkup();
this.updateDataLayer();
this.configureOverlays();
this.trigger("loadstart");
if (this.autoplay) {
this.play();
}
}
}, {
key: "onPlayerPlaying",
value: function onPlayerPlaying() {
this.updateDataLayer();
this.disableAdOverlay();
}
}, {
key: "onPlayerEnded",
value: function onPlayerEnded() {
if (this.currentVideoIndex >= this.videos.length - 1) {
this.trigger("ended");
} else {
this.loadNextVideo();
}
}
}, {
key: "onAdStarted",
value: function onAdStarted() {
this.enableAdOverlay();
}
}, {
key: "onAdEnded",
value: function onAdEnded() {
this.disableAdOverlay();
}
}, {
key: "enableAdOverlay",
value: function enableAdOverlay() {
var adOverlay = this.$el.find("#" + this.getAdOverlayId());
adOverlay.css("display", "inline-block");
}
}, {
key: "disableAdOverlay",
value: function disableAdOverlay() {
var adOverlay = this.$el.find("#" + this.getAdOverlayId());
adOverlay.css("display", "none");
}
}, {
key: "fetchVideos",
value: function fetchVideos() {
var _this2 = this;
var query = null;
try {
query = "dest_" + window.lp.place.atlasId;
} catch (e) {
return Promise.resolve(false);
}
var apiURL = "https://www.lonelyplanet.com/video/api/";
return new Promise(function (resolve) {
$.ajax({
url: apiURL + "playlists.json?reference_id=" + query
}).done(function (data, status, response) {
if (response.status === 200 && data && data.length) {
_this2.videos = data[0].playlistitems.map(function (item) {
return item.video;
});
}
if (_this2.videos.length) {
_this2.loadNextVideo();
resolve(true);
} else {
$.ajax({
url: apiURL + "video.json?reference_id=" + query
}).done(function (data, status, response) {
if (response.status === 200 && data && data.length) {
_this2.videos = data;
}
if (_this2.videos.length) {
_this2.loadNextVideo();
resolve(true);
} else {
resolve(false);
}
});
}
});
});
}
}, {
key: "loadNextVideo",
value: function loadNextVideo() {
var _this3 = this;
if (!this.videos.length) {
return;
}
this.currentVideoIndex = this.currentVideoIndex === null ? 0 : this.currentVideoIndex + 1;
this.currentVideoIndex = this.currentVideoIndex > this.videos.length - 1 ? 0 : this.currentVideoIndex;
var video = this.videos[this.currentVideoIndex];
if (!this.player) {
this.videoId = video.provider_id;
this.setup();
} else if (!this.player.mediainfo || this.player.mediainfo.id !== video.provider_id) {
// Do not load a video that is already loaded
// (brightcove's engagement score metrics will break)
this.player.catalog.getVideo(video.provider_id, function (error, video) {
if (!error) {
_this3.player.catalog.load(video);
}
});
} else if (this.autoplay) {
this.play();
}
}
/**
* Gets the ideal dimensions of the video, considering it's aspect ratio.
* @param {number} maxw - (required) Maximum width to return (pixels)
* @param {number} maxh - (optional) Maximum height to return (pixels)
* @return {Object} object with 'width' and 'height' attributes
*/
}, {
key: "getIdealDimensions",
value: function getIdealDimensions(maxw, maxh) {
var ratio = this.defaultAspectRatio;
// If we have video data, use the aspect ratio of the
// video as the width-height ratio value
try {
var source = this.player.mediainfo.rawSources[0];
ratio = source.width / source.height;
} catch (e) {}
var width = maxw;
var height = maxw / ratio;
if (typeof maxh != "undefined" && height > maxh) {
height = maxh;
width = height * ratio;
}
return { width: width, height: height };
}
}, {
key: "getAdOverlayId",
value: function getAdOverlayId() {
return "ad-overlay-" + this.playerId;
}
}, {
key: "getCues",
value: function getCues() {
if (!this.player) {
return [];
}
var tt = this.player.textTracks()[0];
if (!tt) {
return [];
}
var index = 0;
var cues = [];
while (index < tt.cues.length) {
var cue = tt.cues[index];
if (cue.text === "CODE") {
cues.push(cue);
}
index += 1;
}
return cues;
}
}, {
key: "configureOverlays",
value: function configureOverlays() {
var _this4 = this;
if (!this.player) {
return;
}
var overlays = this.getCues().map(function (c) {
var cue = c.originalCuePoint;
var defaultEnd = cue.startTime + 15;
var end = defaultEnd < cue.endTime ? defaultEnd : cue.endTime;
var cueElementId = "ad-lowerthird-" + _this4.playerId + "-" + cue.id;
return {
content: "<div id=\"" + cueElementId + "\" class=\"video__lowerthird-overlay\" />",
align: "bottom",
start: cue.startTime,
end: end
};
});
overlays.push({
content: "<div id=\"" + this.getAdOverlayId() + "\" class=\"video__ad-overlay\">Advertisement</div>",
align: "top-left",
start: "ads-ad-started",
end: "playing"
});
this.player.overlay({
content: "",
overlays: overlays,
showBackground: false,
attachToControlBar: true,
debug: false
});
}
/**
* Retrieves metadata from the currently loaded video
* @param {string} name - The metadata attribute to retrieve a value for
* @returns The metadata value, or undefined if unable to retrieve the value
*/
}, {
key: "getVideoProperty",
value: function getVideoProperty(name) {
if (!this.player || !this.player.mediainfo) {
return;
}
return this.player.mediainfo[name];
}
}, {
key: "updateDataLayer",
value: function updateDataLayer() {
Object.assign(window.lp.analytics.dataLayer[0], {
brightcoveID: this.getVideoProperty("id"),
brightcoveTitle: this.getVideoProperty("name"),
brightcoveDescription: this.getVideoProperty("description")
});
}
/**
* Uses the currently loaded video data to build a block of
* LD-JSON Schema.org markup and appends it to the "head" tag
*
* This is run automatically when any video is loaded.
*/
}, {
key: "renderSEOMarkup",
value: function renderSEOMarkup() {
if (!this.player || !this.player.mediainfo) {
return;
}
var videoId = this.getVideoProperty("id");
var scriptId = "ldjson-video-" + videoId;
var script = document.getElementById(scriptId);
if (script) {
return;
}
var defaultDescription = "";
try {
defaultDescription = window.lp.place.name;
} catch (e) {}
// Duration must be in ISO 8601 format
// https://en.wikipedia.org/wiki/ISO_8601#Durations
// Brightcove returns the number of seconds (ex. 161.685)
var seconds = Math.ceil(this.getVideoProperty("duration"));
var duration = "PT" + seconds + "S";
var embedUrl = "https://players.brightcove.net/5104226627001/default_default/index.html?videoId=" + videoId;
var data = {
"@context": "http://schema.org",
"@type": "VideoObject",
"name": this.getVideoProperty("name") || defaultDescription,
"description": this.getVideoProperty("description") || defaultDescription,
"thumbnailURL": this.getVideoProperty("poster"),
"embedURL": embedUrl,
"duration": duration,
"uploadDate": this.getVideoProperty("createdAt")
};
script = document.createElement("script");
script.id = scriptId;
script.type = "application/ld+json";
script.innerHTML = JSON.stringify(data);
document.getElementsByTagName("head")[0].appendChild(script);
}
}, {
key: "videoEl",
get: function get() {
if (this.$el.hasClass("video-js")) {
return this.el;
}
return this.$el.find(".video-js")[0];
}
}]);
return Brightcove;
}(_video_player2.default);
exports.default = Brightcove;