lg-video.es5.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  1. /*!
  2. * lightgallery | 2.4.0-beta.0 | December 12th 2021
  3. * http://www.lightgalleryjs.com/
  4. * Copyright (c) 2020 Sachin Neravath;
  5. * @license GPLv3
  6. */
  7. /*! *****************************************************************************
  8. Copyright (c) Microsoft Corporation.
  9. Permission to use, copy, modify, and/or distribute this software for any
  10. purpose with or without fee is hereby granted.
  11. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
  12. REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  13. AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
  14. INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  15. LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  16. OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  17. PERFORMANCE OF THIS SOFTWARE.
  18. ***************************************************************************** */
  19. var __assign = function() {
  20. __assign = Object.assign || function __assign(t) {
  21. for (var s, i = 1, n = arguments.length; i < n; i++) {
  22. s = arguments[i];
  23. for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
  24. }
  25. return t;
  26. };
  27. return __assign.apply(this, arguments);
  28. };
  29. var videoSettings = {
  30. autoplayFirstVideo: true,
  31. youTubePlayerParams: false,
  32. vimeoPlayerParams: false,
  33. wistiaPlayerParams: false,
  34. gotoNextSlideOnVideoEnd: true,
  35. autoplayVideoOnSlide: false,
  36. videojs: false,
  37. videojsOptions: {},
  38. };
  39. /**
  40. * List of lightGallery events
  41. * All events should be documented here
  42. * Below interfaces are used to build the website documentations
  43. * */
  44. var lGEvents = {
  45. afterAppendSlide: 'lgAfterAppendSlide',
  46. init: 'lgInit',
  47. hasVideo: 'lgHasVideo',
  48. containerResize: 'lgContainerResize',
  49. updateSlides: 'lgUpdateSlides',
  50. afterAppendSubHtml: 'lgAfterAppendSubHtml',
  51. beforeOpen: 'lgBeforeOpen',
  52. afterOpen: 'lgAfterOpen',
  53. slideItemLoad: 'lgSlideItemLoad',
  54. beforeSlide: 'lgBeforeSlide',
  55. afterSlide: 'lgAfterSlide',
  56. posterClick: 'lgPosterClick',
  57. dragStart: 'lgDragStart',
  58. dragMove: 'lgDragMove',
  59. dragEnd: 'lgDragEnd',
  60. beforeNextSlide: 'lgBeforeNextSlide',
  61. beforePrevSlide: 'lgBeforePrevSlide',
  62. beforeClose: 'lgBeforeClose',
  63. afterClose: 'lgAfterClose',
  64. rotateLeft: 'lgRotateLeft',
  65. rotateRight: 'lgRotateRight',
  66. flipHorizontal: 'lgFlipHorizontal',
  67. flipVertical: 'lgFlipVertical',
  68. autoplay: 'lgAutoplay',
  69. autoplayStart: 'lgAutoplayStart',
  70. autoplayStop: 'lgAutoplayStop',
  71. };
  72. var param = function (obj) {
  73. return Object.keys(obj)
  74. .map(function (k) {
  75. return encodeURIComponent(k) + '=' + encodeURIComponent(obj[k]);
  76. })
  77. .join('&');
  78. };
  79. var getVimeoURLParams = function (defaultParams, videoInfo) {
  80. if (!videoInfo || !videoInfo.vimeo)
  81. return '';
  82. var urlParams = videoInfo.vimeo[2] || '';
  83. urlParams =
  84. urlParams[0] == '?' ? '&' + urlParams.slice(1) : urlParams || '';
  85. var defaultPlayerParams = defaultParams
  86. ? '&' + param(defaultParams)
  87. : '';
  88. // For vimeo last parms gets priority if duplicates found
  89. var vimeoPlayerParams = "?autoplay=0&muted=1" + defaultPlayerParams + urlParams;
  90. return vimeoPlayerParams;
  91. };
  92. /**
  93. * Video module for lightGallery
  94. * Supports HTML5, YouTube, Vimeo, wistia videos
  95. *
  96. *
  97. * @ref Wistia
  98. * https://wistia.com/support/integrations/wordpress(How to get url)
  99. * https://wistia.com/support/developers/embed-options#using-embed-options
  100. * https://wistia.com/support/developers/player-api
  101. * https://wistia.com/support/developers/construct-an-embed-code
  102. * http://jsfiddle.net/xvnm7xLm/
  103. * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video
  104. * https://wistia.com/support/embed-and-share/sharing-videos
  105. * https://private-sharing.wistia.com/medias/mwhrulrucj
  106. *
  107. * @ref Youtube
  108. * https://developers.google.com/youtube/player_parameters#enablejsapi
  109. * https://developers.google.com/youtube/iframe_api_reference
  110. * https://developer.chrome.com/blog/autoplay/#iframe-delegation
  111. *
  112. * @ref Vimeo
  113. * https://stackoverflow.com/questions/10488943/easy-way-to-get-vimeo-id-from-a-vimeo-url
  114. * https://vimeo.zendesk.com/hc/en-us/articles/360000121668-Starting-playback-at-a-specific-timecode
  115. * https://vimeo.zendesk.com/hc/en-us/articles/360001494447-Using-Player-Parameters
  116. */
  117. var Video = /** @class */ (function () {
  118. function Video(instance) {
  119. // get lightGallery core plugin instance
  120. this.core = instance;
  121. this.settings = __assign(__assign({}, videoSettings), this.core.settings);
  122. return this;
  123. }
  124. Video.prototype.init = function () {
  125. var _this = this;
  126. /**
  127. * Event triggered when video url found without poster
  128. * Append video HTML
  129. * Play if autoplayFirstVideo is true
  130. */
  131. this.core.LGel.on(lGEvents.hasVideo + ".video", this.onHasVideo.bind(this));
  132. this.core.LGel.on(lGEvents.posterClick + ".video", function () {
  133. var $el = _this.core.getSlideItem(_this.core.index);
  134. _this.loadVideoOnPosterClick($el);
  135. });
  136. this.core.LGel.on(lGEvents.slideItemLoad + ".video", this.onSlideItemLoad.bind(this));
  137. // @desc fired immediately before each slide transition.
  138. this.core.LGel.on(lGEvents.beforeSlide + ".video", this.onBeforeSlide.bind(this));
  139. // @desc fired immediately after each slide transition.
  140. this.core.LGel.on(lGEvents.afterSlide + ".video", this.onAfterSlide.bind(this));
  141. };
  142. /**
  143. * @desc Event triggered when a slide is completely loaded
  144. *
  145. * @param {Event} event - lightGalley custom event
  146. */
  147. Video.prototype.onSlideItemLoad = function (event) {
  148. var _this = this;
  149. var _a = event.detail, isFirstSlide = _a.isFirstSlide, index = _a.index;
  150. // Should check the active slide as well as user may have moved to different slide before the first slide is loaded
  151. if (this.settings.autoplayFirstVideo &&
  152. isFirstSlide &&
  153. index === this.core.index) {
  154. // Delay is just for the transition effect on video load
  155. setTimeout(function () {
  156. _this.loadAndPlayVideo(index);
  157. }, 200);
  158. }
  159. // Should not call on first slide. should check only if the slide is active
  160. if (!isFirstSlide &&
  161. this.settings.autoplayVideoOnSlide &&
  162. index === this.core.index) {
  163. this.loadAndPlayVideo(index);
  164. }
  165. };
  166. /**
  167. * @desc Event triggered when video url or poster found
  168. * Append video HTML is poster is not given
  169. * Play if autoplayFirstVideo is true
  170. *
  171. * @param {Event} event - Javascript Event object.
  172. */
  173. Video.prototype.onHasVideo = function (event) {
  174. var _a = event.detail, index = _a.index, src = _a.src, html5Video = _a.html5Video, hasPoster = _a.hasPoster;
  175. if (!hasPoster) {
  176. // All functions are called separately if poster exist in loadVideoOnPosterClick function
  177. this.appendVideos(this.core.getSlideItem(index), {
  178. src: src,
  179. addClass: 'lg-object',
  180. index: index,
  181. html5Video: html5Video,
  182. });
  183. // Automatically navigate to next slide once video reaches the end.
  184. this.gotoNextSlideOnVideoEnd(src, index);
  185. }
  186. };
  187. /**
  188. * @desc fired immediately before each slide transition.
  189. * Pause the previous video
  190. * Hide the download button if the slide contains YouTube, Vimeo, or Wistia videos.
  191. *
  192. * @param {Event} event - Javascript Event object.
  193. * @param {number} prevIndex - Previous index of the slide.
  194. * @param {number} index - Current index of the slide
  195. */
  196. Video.prototype.onBeforeSlide = function (event) {
  197. if (this.core.lGalleryOn) {
  198. var prevIndex = event.detail.prevIndex;
  199. this.pauseVideo(prevIndex);
  200. }
  201. };
  202. /**
  203. * @desc fired immediately after each slide transition.
  204. * Play video if autoplayVideoOnSlide option is enabled.
  205. *
  206. * @param {Event} event - Javascript Event object.
  207. * @param {number} prevIndex - Previous index of the slide.
  208. * @param {number} index - Current index of the slide
  209. * @todo should check on onSlideLoad as well if video is not loaded on after slide
  210. */
  211. Video.prototype.onAfterSlide = function (event) {
  212. var _this = this;
  213. var _a = event.detail, index = _a.index, prevIndex = _a.prevIndex;
  214. // Do not call on first slide
  215. var $slide = this.core.getSlideItem(index);
  216. if (this.settings.autoplayVideoOnSlide && index !== prevIndex) {
  217. if ($slide.hasClass('lg-complete')) {
  218. setTimeout(function () {
  219. _this.loadAndPlayVideo(index);
  220. }, 100);
  221. }
  222. }
  223. };
  224. Video.prototype.loadAndPlayVideo = function (index) {
  225. var $slide = this.core.getSlideItem(index);
  226. var currentGalleryItem = this.core.galleryItems[index];
  227. if (currentGalleryItem.poster) {
  228. this.loadVideoOnPosterClick($slide, true);
  229. }
  230. else {
  231. this.playVideo(index);
  232. }
  233. };
  234. /**
  235. * Play HTML5, Youtube, Vimeo or Wistia videos in a particular slide.
  236. * @param {number} index - Index of the slide
  237. */
  238. Video.prototype.playVideo = function (index) {
  239. this.controlVideo(index, 'play');
  240. };
  241. /**
  242. * Pause HTML5, Youtube, Vimeo or Wistia videos in a particular slide.
  243. * @param {number} index - Index of the slide
  244. */
  245. Video.prototype.pauseVideo = function (index) {
  246. this.controlVideo(index, 'pause');
  247. };
  248. Video.prototype.getVideoHtml = function (src, addClass, index, html5Video) {
  249. var video = '';
  250. var videoInfo = this.core.galleryItems[index]
  251. .__slideVideoInfo || {};
  252. var currentGalleryItem = this.core.galleryItems[index];
  253. var videoTitle = currentGalleryItem.title || currentGalleryItem.alt;
  254. videoTitle = videoTitle ? 'title="' + videoTitle + '"' : '';
  255. var commonIframeProps = "allowtransparency=\"true\"\n frameborder=\"0\"\n scrolling=\"no\"\n allowfullscreen\n mozallowfullscreen\n webkitallowfullscreen\n oallowfullscreen\n msallowfullscreen";
  256. if (videoInfo.youtube) {
  257. var videoId = 'lg-youtube' + index;
  258. var slideUrlParams = videoInfo.youtube[2]
  259. ? videoInfo.youtube[2] + '&'
  260. : '';
  261. // For youtube first parms gets priority if duplicates found
  262. var youTubePlayerParams = "?" + slideUrlParams + "wmode=opaque&autoplay=0&mute=1&enablejsapi=1";
  263. var playerParams = youTubePlayerParams +
  264. (this.settings.youTubePlayerParams
  265. ? '&' + param(this.settings.youTubePlayerParams)
  266. : '');
  267. video = "<iframe allow=\"autoplay\" id=" + videoId + " class=\"lg-video-object lg-youtube " + addClass + "\" " + videoTitle + " src=\"//www.youtube.com/embed/" + (videoInfo.youtube[1] + playerParams) + "\" " + commonIframeProps + "></iframe>";
  268. }
  269. else if (videoInfo.vimeo) {
  270. var videoId = 'lg-vimeo' + index;
  271. var playerParams = getVimeoURLParams(this.settings.vimeoPlayerParams, videoInfo);
  272. 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>";
  273. }
  274. else if (videoInfo.wistia) {
  275. var wistiaId = 'lg-wistia' + index;
  276. var playerParams = param(this.settings.wistiaPlayerParams);
  277. playerParams = playerParams ? '?' + playerParams : '';
  278. 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>";
  279. }
  280. else if (videoInfo.html5) {
  281. var html5VideoMarkup = '';
  282. for (var i = 0; i < html5Video.source.length; i++) {
  283. html5VideoMarkup += "<source src=\"" + html5Video.source[i].src + "\" type=\"" + html5Video.source[i].type + "\">";
  284. }
  285. if (html5Video.tracks) {
  286. var _loop_1 = function (i) {
  287. var trackAttributes = '';
  288. var track = html5Video.tracks[i];
  289. Object.keys(track || {}).forEach(function (key) {
  290. trackAttributes += key + "=\"" + track[key] + "\" ";
  291. });
  292. html5VideoMarkup += "<track " + trackAttributes + ">";
  293. };
  294. for (var i = 0; i < html5Video.tracks.length; i++) {
  295. _loop_1(i);
  296. }
  297. }
  298. var html5VideoAttrs_1 = '';
  299. var videoAttributes_1 = html5Video.attributes || {};
  300. Object.keys(videoAttributes_1 || {}).forEach(function (key) {
  301. html5VideoAttrs_1 += key + "=\"" + videoAttributes_1[key] + "\" ";
  302. });
  303. video = "<video class=\"lg-video-object lg-html5 " + (this.settings.videojs ? 'video-js' : '') + "\" " + html5VideoAttrs_1 + ">\n " + html5VideoMarkup + "\n Your browser does not support HTML5 video.\n </video>";
  304. }
  305. return video;
  306. };
  307. /**
  308. * @desc - Append videos to the slide
  309. *
  310. * @param {HTMLElement} el - slide element
  311. * @param {Object} videoParams - Video parameters, Contains src, class, index, htmlVideo
  312. */
  313. Video.prototype.appendVideos = function (el, videoParams) {
  314. var _a;
  315. var videoHtml = this.getVideoHtml(videoParams.src, videoParams.addClass, videoParams.index, videoParams.html5Video);
  316. el.find('.lg-video-cont').append(videoHtml);
  317. var $videoElement = el.find('.lg-video-object').first();
  318. if (videoParams.html5Video) {
  319. $videoElement.on('mousedown.lg.video', function (e) {
  320. e.stopPropagation();
  321. });
  322. }
  323. if (this.settings.videojs && ((_a = this.core.galleryItems[videoParams.index].__slideVideoInfo) === null || _a === void 0 ? void 0 : _a.html5)) {
  324. try {
  325. return videojs($videoElement.get(), this.settings.videojsOptions);
  326. }
  327. catch (e) {
  328. console.error('lightGallery:- Make sure you have included videojs');
  329. }
  330. }
  331. };
  332. Video.prototype.gotoNextSlideOnVideoEnd = function (src, index) {
  333. var _this = this;
  334. var $videoElement = this.core
  335. .getSlideItem(index)
  336. .find('.lg-video-object')
  337. .first();
  338. var videoInfo = this.core.galleryItems[index].__slideVideoInfo || {};
  339. if (this.settings.gotoNextSlideOnVideoEnd) {
  340. if (videoInfo.html5) {
  341. $videoElement.on('ended', function () {
  342. _this.core.goToNextSlide();
  343. });
  344. }
  345. else if (videoInfo.vimeo) {
  346. try {
  347. // https://github.com/vimeo/player.js/#ended
  348. new Vimeo.Player($videoElement.get()).on('ended', function () {
  349. _this.core.goToNextSlide();
  350. });
  351. }
  352. catch (e) {
  353. console.error('lightGallery:- Make sure you have included //github.com/vimeo/player.js');
  354. }
  355. }
  356. else if (videoInfo.wistia) {
  357. try {
  358. window._wq = window._wq || [];
  359. // @todo Event is gettign triggered multiple times
  360. window._wq.push({
  361. id: $videoElement.attr('id'),
  362. onReady: function (video) {
  363. video.bind('end', function () {
  364. _this.core.goToNextSlide();
  365. });
  366. },
  367. });
  368. }
  369. catch (e) {
  370. console.error('lightGallery:- Make sure you have included //fast.wistia.com/assets/external/E-v1.js');
  371. }
  372. }
  373. }
  374. };
  375. Video.prototype.controlVideo = function (index, action) {
  376. var $videoElement = this.core
  377. .getSlideItem(index)
  378. .find('.lg-video-object')
  379. .first();
  380. var videoInfo = this.core.galleryItems[index].__slideVideoInfo || {};
  381. if (!$videoElement.get())
  382. return;
  383. if (videoInfo.youtube) {
  384. try {
  385. $videoElement.get().contentWindow.postMessage("{\"event\":\"command\",\"func\":\"" + action + "Video\",\"args\":\"\"}", '*');
  386. }
  387. catch (e) {
  388. console.error("lightGallery:- " + e);
  389. }
  390. }
  391. else if (videoInfo.vimeo) {
  392. try {
  393. new Vimeo.Player($videoElement.get())[action]();
  394. }
  395. catch (e) {
  396. console.error('lightGallery:- Make sure you have included //github.com/vimeo/player.js');
  397. }
  398. }
  399. else if (videoInfo.html5) {
  400. if (this.settings.videojs) {
  401. try {
  402. videojs($videoElement.get())[action]();
  403. }
  404. catch (e) {
  405. console.error('lightGallery:- Make sure you have included videojs');
  406. }
  407. }
  408. else {
  409. $videoElement.get()[action]();
  410. }
  411. }
  412. else if (videoInfo.wistia) {
  413. try {
  414. window._wq = window._wq || [];
  415. // @todo Find a way to destroy wistia player instance
  416. window._wq.push({
  417. id: $videoElement.attr('id'),
  418. onReady: function (video) {
  419. video[action]();
  420. },
  421. });
  422. }
  423. catch (e) {
  424. console.error('lightGallery:- Make sure you have included //fast.wistia.com/assets/external/E-v1.js');
  425. }
  426. }
  427. };
  428. Video.prototype.loadVideoOnPosterClick = function ($el, forcePlay) {
  429. var _this = this;
  430. // check slide has poster
  431. if (!$el.hasClass('lg-video-loaded')) {
  432. // check already video element present
  433. if (!$el.hasClass('lg-has-video')) {
  434. $el.addClass('lg-has-video');
  435. var _html = void 0;
  436. var _src = this.core.galleryItems[this.core.index].src;
  437. var video = this.core.galleryItems[this.core.index].video;
  438. if (video) {
  439. _html =
  440. typeof video === 'string' ? JSON.parse(video) : video;
  441. }
  442. var videoJsPlayer_1 = this.appendVideos($el, {
  443. src: _src,
  444. addClass: '',
  445. index: this.core.index,
  446. html5Video: _html,
  447. });
  448. this.gotoNextSlideOnVideoEnd(_src, this.core.index);
  449. var $tempImg = $el.find('.lg-object').first().get();
  450. // @todo make sure it is working
  451. $el.find('.lg-video-cont').first().append($tempImg);
  452. $el.addClass('lg-video-loading');
  453. videoJsPlayer_1 &&
  454. videoJsPlayer_1.ready(function () {
  455. videoJsPlayer_1.on('loadedmetadata', function () {
  456. _this.onVideoLoadAfterPosterClick($el, _this.core.index);
  457. });
  458. });
  459. $el.find('.lg-video-object')
  460. .first()
  461. .on('load.lg error.lg loadedmetadata.lg', function () {
  462. setTimeout(function () {
  463. _this.onVideoLoadAfterPosterClick($el, _this.core.index);
  464. }, 50);
  465. });
  466. }
  467. else {
  468. this.playVideo(this.core.index);
  469. }
  470. }
  471. else if (forcePlay) {
  472. this.playVideo(this.core.index);
  473. }
  474. };
  475. Video.prototype.onVideoLoadAfterPosterClick = function ($el, index) {
  476. $el.addClass('lg-video-loaded');
  477. this.playVideo(index);
  478. };
  479. Video.prototype.destroy = function () {
  480. this.core.LGel.off('.lg.video');
  481. this.core.LGel.off('.video');
  482. };
  483. return Video;
  484. }());
  485. export default Video;
  486. //# sourceMappingURL=lg-video.es5.js.map