cloudinary-video-player
Version:
Cloudinary Video Player
37 lines (30 loc) • 10.5 kB
JavaScript
/*!
* Cloudinary Video Player v3.6.3
* Built on 2026-01-04T09:24:08.226Z
* https://github.com/cloudinary/cloudinary-video-player
*/
"use strict";
/*
* ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
(self["cloudinaryVideoPlayerChunkLoading"] = self["cloudinaryVideoPlayerChunkLoading"] || []).push([["chapters"],{
/***/ "./plugins/chapters/chapters.js":
/*!**************************************!*\
!*** ./plugins/chapters/chapters.js ***!
\**************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var video_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! video.js */ \"../node_modules/video.js/dist/alt/video.core-exposed.js\");\n/* harmony import */ var video_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(video_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _chapters_scss__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./chapters.scss */ \"./plugins/chapters/chapters.scss\");\n/* harmony import */ var _cloudinary_common__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../cloudinary/common */ \"./plugins/cloudinary/common.js\");\n/* harmony import */ var _utils_utf8Base64__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../utils/utf8Base64 */ \"./utils/utf8Base64.js\");\n\n\n\n\n\n/**\n * Chapters plugin.\n *\n * @function chapters\n * @param {Object} [options={}]\n * An object of options left to the plugin author to define.\n * @param {Player} player\n * A Video.js player object.\n */\nconst chapters = function chapters(options, player) {\n player.addClass('vjs-chapters');\n player.chapters = new ChaptersPlugin(player, options);\n};\n\n/**\n * Chapters\n */\nconst ChaptersPlugin = function () {\n /**\n * Plugin class constructor, called by videojs on\n * ready event.\n *\n * @function constructor\n * @param {Player} player\n * A Video.js player object.\n *\n * @param {Object} [options={}]\n * A plain object containing options for the plugin.\n */\n function ChaptersPlugin(player, options) {\n this.player = player;\n this.options = options;\n this.player.one('loadedmetadata', this.initializeChapters.bind(this));\n return this;\n }\n ChaptersPlugin.prototype.src = function src(options) {\n this.resetPlugin();\n this.options = options;\n this.player.one('loadedmetadata', this.initializeChapters.bind(this));\n };\n ChaptersPlugin.prototype.detach = function detach() {\n this.resetPlugin();\n };\n ChaptersPlugin.prototype.resetPlugin = function resetPlugin() {\n if (this.chaptersTrack) {\n this.player.$('.vjs-control-bar-chapter-display').remove();\n this.player.$('.vjs-chapter-display').remove();\n this.player.$$('.vjs-chapter-marker').forEach(el => el.remove());\n this.player.removeRemoteTextTrack(this.chaptersTrack);\n delete this.chaptersTrack;\n }\n };\n ChaptersPlugin.prototype.getChaptersFileUrlByName = function getChaptersFileUrlByName() {\n const currentPublicId = this.player.cloudinary.currentPublicId();\n if (!currentPublicId) {\n return null;\n }\n const {\n type: deliveryType\n } = this.player.cloudinary.source().resourceConfig();\n const urlPrefix = (0,_cloudinary_common__WEBPACK_IMPORTED_MODULE_2__.getCloudinaryUrlPrefix)(this.player.cloudinary.cloudinaryConfig());\n const fullUrl = `${urlPrefix}/_applet_/video_service/chapters/${deliveryType}/${(0,_utils_utf8Base64__WEBPACK_IMPORTED_MODULE_3__.utf8ToBase64)(currentPublicId)}.vtt`;\n return `${fullUrl}?t=${Date.now()}`;\n };\n\n /**\n * Bootstrap the plugin.\n */\n ChaptersPlugin.prototype.initializeChapters = async function initializeChapters() {\n const chaptersUrl = this.options === true ? this.getChaptersFileUrlByName() : this.options.url;\n if (chaptersUrl) {\n // Fetch chapters VTT from URL\n const chaptersTrack = {\n kind: 'chapters',\n src: chaptersUrl,\n default: true\n };\n const textTrack = this.player.addRemoteTextTrack(chaptersTrack);\n textTrack.addEventListener('load', () => {\n this.chaptersTrack = textTrack.track;\n this.setupChaptersDisplays();\n });\n } else if (Object.entries(this.options).length) {\n // Setup chapters from options\n const textTrack = this.player.addRemoteTextTrack({\n kind: 'chapters',\n default: true\n });\n const end = this.player.duration();\n Object.entries(this.options).forEach((entry, index, arr) => {\n const cue = new VTTCue(parseFloat(entry[0]), parseFloat(arr[index + 1] ? arr[index + 1][0] : end), entry[1]);\n textTrack.track.addCue(cue);\n });\n this.chaptersTrack = textTrack.track;\n this.setupChaptersDisplays();\n if (this.player.controlBar.chaptersButton) {\n this.player.controlBar.chaptersButton.update();\n }\n }\n };\n\n /**\n * Setup chapter displays.\n */\n ChaptersPlugin.prototype.setupChaptersDisplays = function initializeChapters() {\n this.setupProgressBarMarkers();\n this.setupProgressBarChapter();\n this.setupControlBarChapter();\n };\n\n /**\n * Setup the controlbar chapter display.\n */\n ChaptersPlugin.prototype.setupControlBarChapter = function setupControlBarChapter() {\n const controlBarChapterHolder = this.player.$('.vjs-control-bar-chapter-display') || document.createElement('div');\n controlBarChapterHolder.setAttribute('class', 'vjs-control-bar-chapter-display');\n const wrapper = this.player.$('.vjs-control-bar .vjs-spacer');\n wrapper.innerHTML = '';\n wrapper.classList.add('vjs-control-bar-chapter-wrapper');\n wrapper.appendChild(controlBarChapterHolder);\n this.chaptersTrack.addEventListener('cuechange', () => {\n const activeCues = Array.from(this.chaptersTrack.activeCues); // Safari needs Array.from()\n controlBarChapterHolder.innerText = activeCues.length > 0 ? activeCues[0].text : '';\n });\n };\n\n /**\n * Setup the progress bar markers.\n */\n ChaptersPlugin.prototype.setupProgressBarMarkers = function setupProgressBarMarkers() {\n const total = this.player.duration();\n const {\n seekBar\n } = this.player.controlBar.progressControl;\n Array.from(this.chaptersTrack.cues).forEach(marker => {\n // Safari needs Array.from()\n if (marker.startTime !== 0) {\n const markerTime = marker.startTime;\n const left = markerTime / total * 100 + '%';\n const markerEl = video_js__WEBPACK_IMPORTED_MODULE_0___default().dom.createEl('div', undefined, {\n class: 'vjs-chapter-marker',\n style: `left: ${left}`\n });\n seekBar.el().append(markerEl);\n }\n });\n };\n\n /**\n * Setup the progrees bar on-hover chapter display.\n */\n ChaptersPlugin.prototype.setupProgressBarChapter = function setupProgressBarChapter() {\n const chapterEl = video_js__WEBPACK_IMPORTED_MODULE_0___default().dom.createEl('div', undefined, {\n class: 'vjs-chapter-display',\n style: `max-width: ${this.player.$('.vjs-vtt-thumbnail-display') ? this.player.$('.vjs-vtt-thumbnail-display').style.width : '160px'}`\n });\n const mouseTimeDisplay = this.player.getDescendant(['controlBar', 'progressControl', 'seekBar', 'mouseTimeDisplay']);\n const timeTooltip = mouseTimeDisplay.getDescendant(['timeTooltip']);\n timeTooltip.el().parentElement.prepend(chapterEl);\n const getChapterFromPoint = point => {\n const total = this.player.duration();\n const seekBarTime = point * total;\n const chapter = Array.from(this.chaptersTrack?.cues || []).find(marker => {\n return seekBarTime >= marker.startTime && seekBarTime <= marker.endTime;\n });\n return chapter ? chapter.text : '';\n };\n timeTooltip.update = function (seekBarRect, seekBarPoint, content) {\n const originalUpdateFn = Object.getPrototypeOf(this).update;\n originalUpdateFn.call(this, seekBarRect, seekBarPoint, content);\n chapterEl.innerText = getChapterFromPoint(seekBarPoint);\n };\n\n // Handle case of no seek-thumbnails\n if (typeof this.player.vttThumbnails !== 'object') {\n mouseTimeDisplay.update = function (seekBarRect, seekBarPoint) {\n const time = seekBarPoint * this.player_.duration();\n const width = seekBarRect.width;\n const size = chapterEl.clientWidth / 2;\n timeTooltip.updateTime(seekBarRect, seekBarPoint, time, () => {\n // Make sure it doesn't exit the player\n if (seekBarRect.width * seekBarPoint < size) {\n this.el_.style.left = `${size}px`;\n } else if (seekBarRect.width * seekBarPoint + size > width) {\n this.el_.style.left = `${seekBarRect.width - size}px`;\n } else {\n this.el_.style.left = `${seekBarRect.width * seekBarPoint}px`;\n }\n });\n timeTooltip.write(video_js__WEBPACK_IMPORTED_MODULE_0___default().time.formatTime(time));\n };\n }\n };\n return ChaptersPlugin;\n}();\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (chapters);\n\n//# sourceURL=webpack://cloudinary-video-player/./plugins/chapters/chapters.js?");
/***/ }),
/***/ "./plugins/chapters/chapters.scss":
/*!****************************************!*\
!*** ./plugins/chapters/chapters.scss ***!
\****************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
eval("__webpack_require__.r(__webpack_exports__);\n// extracted by mini-css-extract-plugin\n\n\n//# sourceURL=webpack://cloudinary-video-player/./plugins/chapters/chapters.scss?");
/***/ })
}]);