lightgallery
Version:
lightGallery is a feature-rich, modular JavaScript gallery plugin for building beautiful image and video galleries for the web and the mobile
409 lines • 18.3 kB
JavaScript
"use strict";
/**
* Video module for lightGallery
* Supports HTML5, YouTube, Vimeo, wistia videos
*
*
* @ref Wistia
* https://wistia.com/support/integrations/wordpress(How to get url)
* https://wistia.com/support/developers/embed-options#using-embed-options
* https://wistia.com/support/developers/player-api
* https://wistia.com/support/developers/construct-an-embed-code
* http://jsfiddle.net/xvnm7xLm/
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video
* https://wistia.com/support/embed-and-share/sharing-videos
* https://private-sharing.wistia.com/medias/mwhrulrucj
*
* @ref Youtube
* https://developers.google.com/youtube/player_parameters#enablejsapi
* https://developers.google.com/youtube/iframe_api_reference
* https://developer.chrome.com/blog/autoplay/#iframe-delegation
*
* @ref Vimeo
* https://stackoverflow.com/questions/10488943/easy-way-to-get-vimeo-id-from-a-vimeo-url
* https://vimeo.zendesk.com/hc/en-us/articles/360000121668-Starting-playback-at-a-specific-timecode
* https://vimeo.zendesk.com/hc/en-us/articles/360001494447-Using-Player-Parameters
*/
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
Object.defineProperty(exports, "__esModule", { value: true });
var lg_video_settings_1 = require("./lg-video-settings");
var lg_events_1 = require("../../lg-events");
var lg_video_utils_1 = require("./lg-video-utils");
var Video = /** @class */ (function () {
function Video(instance) {
// get lightGallery core plugin instance
this.core = instance;
this.settings = __assign(__assign({}, lg_video_settings_1.videoSettings), this.core.settings);
return this;
}
Video.prototype.init = function () {
var _this = this;
/**
* Event triggered when video url found without poster
* Append video HTML
* Play if autoplayFirstVideo is true
*/
this.core.LGel.on(lg_events_1.lGEvents.hasVideo + ".video", this.onHasVideo.bind(this));
this.core.LGel.on(lg_events_1.lGEvents.posterClick + ".video", function () {
var $el = _this.core.getSlideItem(_this.core.index);
_this.loadVideoOnPosterClick($el);
});
this.core.LGel.on(lg_events_1.lGEvents.slideItemLoad + ".video", this.onSlideItemLoad.bind(this));
// @desc fired immediately before each slide transition.
this.core.LGel.on(lg_events_1.lGEvents.beforeSlide + ".video", this.onBeforeSlide.bind(this));
// @desc fired immediately after each slide transition.
this.core.LGel.on(lg_events_1.lGEvents.afterSlide + ".video", this.onAfterSlide.bind(this));
};
/**
* @desc Event triggered when a slide is completely loaded
*
* @param {Event} event - lightGalley custom event
*/
Video.prototype.onSlideItemLoad = function (event) {
var _this = this;
var _a = event.detail, isFirstSlide = _a.isFirstSlide, index = _a.index;
// Should check the active slide as well as user may have moved to different slide before the first slide is loaded
if (this.settings.autoplayFirstVideo &&
isFirstSlide &&
index === this.core.index) {
// Delay is just for the transition effect on video load
setTimeout(function () {
_this.loadAndPlayVideo(index);
}, 200);
}
// Should not call on first slide. should check only if the slide is active
if (!isFirstSlide &&
this.settings.autoplayVideoOnSlide &&
index === this.core.index) {
this.loadAndPlayVideo(index);
}
};
/**
* @desc Event triggered when video url or poster found
* Append video HTML is poster is not given
* Play if autoplayFirstVideo is true
*
* @param {Event} event - Javascript Event object.
*/
Video.prototype.onHasVideo = function (event) {
var _a = event.detail, index = _a.index, src = _a.src, html5Video = _a.html5Video, hasPoster = _a.hasPoster;
if (!hasPoster) {
// All functions are called separately if poster exist in loadVideoOnPosterClick function
this.appendVideos(this.core.getSlideItem(index), {
src: src,
addClass: 'lg-object',
index: index,
html5Video: html5Video,
});
// Automatically navigate to next slide once video reaches the end.
this.gotoNextSlideOnVideoEnd(src, index);
}
};
/**
* @desc fired immediately before each slide transition.
* Pause the previous video
* Hide the download button if the slide contains YouTube, Vimeo, or Wistia videos.
*
* @param {Event} event - Javascript Event object.
* @param {number} prevIndex - Previous index of the slide.
* @param {number} index - Current index of the slide
*/
Video.prototype.onBeforeSlide = function (event) {
if (this.core.lGalleryOn) {
var prevIndex = event.detail.prevIndex;
this.pauseVideo(prevIndex);
}
};
/**
* @desc fired immediately after each slide transition.
* Play video if autoplayVideoOnSlide option is enabled.
*
* @param {Event} event - Javascript Event object.
* @param {number} prevIndex - Previous index of the slide.
* @param {number} index - Current index of the slide
* @todo should check on onSlideLoad as well if video is not loaded on after slide
*/
Video.prototype.onAfterSlide = function (event) {
var _this = this;
var _a = event.detail, index = _a.index, prevIndex = _a.prevIndex;
// Do not call on first slide
var $slide = this.core.getSlideItem(index);
if (this.settings.autoplayVideoOnSlide && index !== prevIndex) {
if ($slide.hasClass('lg-complete')) {
setTimeout(function () {
_this.loadAndPlayVideo(index);
}, 100);
}
}
};
Video.prototype.loadAndPlayVideo = function (index) {
var $slide = this.core.getSlideItem(index);
var currentGalleryItem = this.core.galleryItems[index];
if (currentGalleryItem.poster) {
this.loadVideoOnPosterClick($slide, true);
}
else {
this.playVideo(index);
}
};
/**
* Play HTML5, Youtube, Vimeo or Wistia videos in a particular slide.
* @param {number} index - Index of the slide
*/
Video.prototype.playVideo = function (index) {
this.controlVideo(index, 'play');
};
/**
* Pause HTML5, Youtube, Vimeo or Wistia videos in a particular slide.
* @param {number} index - Index of the slide
*/
Video.prototype.pauseVideo = function (index) {
this.controlVideo(index, 'pause');
};
Video.prototype.getVideoHtml = function (src, addClass, index, html5Video) {
var video = '';
var videoInfo = this.core.galleryItems[index]
.__slideVideoInfo || {};
var currentGalleryItem = this.core.galleryItems[index];
var videoTitle = currentGalleryItem.title || currentGalleryItem.alt;
videoTitle = videoTitle ? 'title="' + videoTitle + '"' : '';
var commonIframeProps = "allowtransparency=\"true\"\n frameborder=\"0\"\n scrolling=\"no\"\n allowfullscreen\n mozallowfullscreen\n webkitallowfullscreen\n oallowfullscreen\n msallowfullscreen";
if (videoInfo.youtube) {
var videoId = 'lg-youtube' + index;
var youTubeParams = lg_video_utils_1.getYouTubeParams(videoInfo, this.settings.youTubePlayerParams);
var isYouTubeNoCookieURL = lg_video_utils_1.isYouTubeNoCookie(src);
var youtubeURL = isYouTubeNoCookieURL
? '//www.youtube-nocookie.com/'
: '//www.youtube.com/';
video = "<iframe allow=\"autoplay\" id=" + videoId + " class=\"lg-video-object lg-youtube " + addClass + "\" " + videoTitle + " src=\"" + youtubeURL + "embed/" + (videoInfo.youtube[1] + youTubeParams) + "\" " + commonIframeProps + "></iframe>";
}
else if (videoInfo.vimeo) {
var videoId = 'lg-vimeo' + index;
var playerParams = lg_video_utils_1.getVimeoURLParams(this.settings.vimeoPlayerParams, videoInfo);
video = "<iframe allow=\"autoplay\" id=" + videoId + " class=\"lg-video-object lg-vimeo " + addClass + "\" " + videoTitle + " src=\"//player.vimeo.com/video/" + (videoInfo.vimeo[1] + playerParams) + "\" " + commonIframeProps + "></iframe>";
}
else if (videoInfo.wistia) {
var wistiaId = 'lg-wistia' + index;
var playerParams = lg_video_utils_1.param(this.settings.wistiaPlayerParams);
playerParams = playerParams ? '?' + playerParams : '';
video = "<iframe allow=\"autoplay\" id=\"" + wistiaId + "\" src=\"//fast.wistia.net/embed/iframe/" + (videoInfo.wistia[4] + playerParams) + "\" " + videoTitle + " class=\"wistia_embed lg-video-object lg-wistia " + addClass + "\" name=\"wistia_embed\" " + commonIframeProps + "></iframe>";
}
else if (videoInfo.html5) {
var html5VideoMarkup = '';
for (var i = 0; i < html5Video.source.length; i++) {
html5VideoMarkup += "<source src=\"" + html5Video.source[i].src + "\" type=\"" + html5Video.source[i].type + "\">";
}
if (html5Video.tracks) {
var _loop_1 = function (i) {
var trackAttributes = '';
var track = html5Video.tracks[i];
Object.keys(track || {}).forEach(function (key) {
trackAttributes += key + "=\"" + track[key] + "\" ";
});
html5VideoMarkup += "<track " + trackAttributes + ">";
};
for (var i = 0; i < html5Video.tracks.length; i++) {
_loop_1(i);
}
}
var html5VideoAttrs_1 = '';
var videoAttributes_1 = html5Video.attributes || {};
Object.keys(videoAttributes_1 || {}).forEach(function (key) {
html5VideoAttrs_1 += key + "=\"" + videoAttributes_1[key] + "\" ";
});
video = "<video class=\"lg-video-object lg-html5 " + (this.settings.videojs && this.settings.videojsTheme
? this.settings.videojsTheme + ' '
: '') + " " + (this.settings.videojs ? ' video-js' : '') + "\" " + html5VideoAttrs_1 + ">\n " + html5VideoMarkup + "\n Your browser does not support HTML5 video.\n </video>";
}
return video;
};
/**
* @desc - Append videos to the slide
*
* @param {HTMLElement} el - slide element
* @param {Object} videoParams - Video parameters, Contains src, class, index, htmlVideo
*/
Video.prototype.appendVideos = function (el, videoParams) {
var _a;
var videoHtml = this.getVideoHtml(videoParams.src, videoParams.addClass, videoParams.index, videoParams.html5Video);
el.find('.lg-video-cont').append(videoHtml);
var $videoElement = el.find('.lg-video-object').first();
if (videoParams.html5Video) {
$videoElement.on('mousedown.lg.video', function (e) {
e.stopPropagation();
});
}
if (this.settings.videojs && ((_a = this.core.galleryItems[videoParams.index].__slideVideoInfo) === null || _a === void 0 ? void 0 : _a.html5)) {
try {
return videojs($videoElement.get(), this.settings.videojsOptions);
}
catch (e) {
console.error('lightGallery:- Make sure you have included videojs');
}
}
};
Video.prototype.gotoNextSlideOnVideoEnd = function (src, index) {
var _this = this;
var $videoElement = this.core
.getSlideItem(index)
.find('.lg-video-object')
.first();
var videoInfo = this.core.galleryItems[index].__slideVideoInfo || {};
if (this.settings.gotoNextSlideOnVideoEnd) {
if (videoInfo.html5) {
$videoElement.on('ended', function () {
_this.core.goToNextSlide();
});
}
else if (videoInfo.vimeo) {
try {
// https://github.com/vimeo/player.js/#ended
new Vimeo.Player($videoElement.get()).on('ended', function () {
_this.core.goToNextSlide();
});
}
catch (e) {
console.error('lightGallery:- Make sure you have included //github.com/vimeo/player.js');
}
}
else if (videoInfo.wistia) {
try {
window._wq = window._wq || [];
// @todo Event is gettign triggered multiple times
window._wq.push({
id: $videoElement.attr('id'),
onReady: function (video) {
video.bind('end', function () {
_this.core.goToNextSlide();
});
},
});
}
catch (e) {
console.error('lightGallery:- Make sure you have included //fast.wistia.com/assets/external/E-v1.js');
}
}
}
};
Video.prototype.controlVideo = function (index, action) {
var $videoElement = this.core
.getSlideItem(index)
.find('.lg-video-object')
.first();
var videoInfo = this.core.galleryItems[index].__slideVideoInfo || {};
if (!$videoElement.get())
return;
if (videoInfo.youtube) {
try {
$videoElement.get().contentWindow.postMessage("{\"event\":\"command\",\"func\":\"" + action + "Video\",\"args\":\"\"}", '*');
}
catch (e) {
console.error("lightGallery:- " + e);
}
}
else if (videoInfo.vimeo) {
try {
new Vimeo.Player($videoElement.get())[action]();
}
catch (e) {
console.error('lightGallery:- Make sure you have included //github.com/vimeo/player.js');
}
}
else if (videoInfo.html5) {
if (this.settings.videojs) {
try {
videojs($videoElement.get())[action]();
}
catch (e) {
console.error('lightGallery:- Make sure you have included videojs');
}
}
else {
$videoElement.get()[action]();
}
}
else if (videoInfo.wistia) {
try {
window._wq = window._wq || [];
// @todo Find a way to destroy wistia player instance
window._wq.push({
id: $videoElement.attr('id'),
onReady: function (video) {
video[action]();
},
});
}
catch (e) {
console.error('lightGallery:- Make sure you have included //fast.wistia.com/assets/external/E-v1.js');
}
}
};
Video.prototype.loadVideoOnPosterClick = function ($el, forcePlay) {
var _this = this;
// check slide has poster
if (!$el.hasClass('lg-video-loaded')) {
// check already video element present
if (!$el.hasClass('lg-has-video')) {
$el.addClass('lg-has-video');
var _html = void 0;
var _src = this.core.galleryItems[this.core.index].src;
var video = this.core.galleryItems[this.core.index].video;
if (video) {
_html =
typeof video === 'string' ? JSON.parse(video) : video;
}
var videoJsPlayer_1 = this.appendVideos($el, {
src: _src,
addClass: '',
index: this.core.index,
html5Video: _html,
});
this.gotoNextSlideOnVideoEnd(_src, this.core.index);
var $tempImg = $el.find('.lg-object').first().get();
// @todo make sure it is working
$el.find('.lg-video-cont').first().append($tempImg);
$el.addClass('lg-video-loading');
videoJsPlayer_1 &&
videoJsPlayer_1.ready(function () {
videoJsPlayer_1.on('loadedmetadata', function () {
_this.onVideoLoadAfterPosterClick($el, _this.core.index);
});
});
$el.find('.lg-video-object')
.first()
.on('load.lg error.lg loadedmetadata.lg', function () {
setTimeout(function () {
_this.onVideoLoadAfterPosterClick($el, _this.core.index);
}, 50);
});
}
else {
this.playVideo(this.core.index);
}
}
else if (forcePlay) {
this.playVideo(this.core.index);
}
};
Video.prototype.onVideoLoadAfterPosterClick = function ($el, index) {
$el.addClass('lg-video-loaded');
this.playVideo(index);
};
Video.prototype.destroy = function () {
this.core.LGel.off('.lg.video');
this.core.LGel.off('.video');
};
return Video;
}());
exports.default = Video;
//# sourceMappingURL=lg-video.js.map