UNPKG

videojs-playlist

Version:
401 lines (341 loc) 10.8 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>JSDoc: Source: playlist-maker.js</title> <script src="scripts/prettify/prettify.js"> </script> <script src="scripts/prettify/lang-css.js"> </script> <!--[if lt IE 9]> <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> </head> <body> <div id="main"> <h1 class="page-title">Source: playlist-maker.js</h1> <section> <article> <pre class="prettyprint source linenums"><code>import videojs from 'video.js'; import window from 'global/window'; import playItem from './play-item'; import * as autoadvance from './auto-advance'; // Lightweight Object.assign alternative. const assign = (target, source) => { for (const key in source) { if (source.hasOwnProperty(key)) { target[key] = source[key]; } } }; /** * Given two sources, check to see whether the two sources are equal. * If both source urls have a protocol, the protocols must match, otherwise, protocols * are ignored. * * @private * @param {string|Object} source1 * The first source * * @param {string|Object} source2 * The second source * * @return {boolean} * The result */ const sourceEquals = (source1, source2) => { let src1 = source1; let src2 = source2; if (typeof source1 === 'object') { src1 = source1.src; } if (typeof source2 === 'object') { src2 = source2.src; } if (/^\/\//.test(src1)) { src2 = src2.slice(src2.indexOf('//')); } if (/^\/\//.test(src2)) { src1 = src1.slice(src1.indexOf('//')); } return src1 === src2; }; /** * Look through an array of playlist items for a specific `source`; * checking both the value of elements and the value of their `src` * property. * * @private * @param {Array} arr * An array of playlist items to look through * * @param {string} src * The source to look for * * @return {number} * The index of that source or -1 */ const indexInSources = (arr, src) => { for (let i = 0; i &lt; arr.length; i++) { const sources = arr[i].sources; if (Array.isArray(sources)) { for (let j = 0; j &lt; sources.length; j++) { const source = sources[j]; if (source &amp;&amp; sourceEquals(source, src)) { return i; } } } } return -1; }; /** * Factory function for creating new playlist implementation on the given player. * * API summary: * * playlist(['a', 'b', 'c']) // setter * playlist() // getter * playlist.currentItem() // getter, 0 * playlist.currentItem(1) // setter, 1 * playlist.next() // 'c' * playlist.previous() // 'b' * playlist.first() // 'a' * playlist.last() // 'c' * playlist.autoadvance(5) // 5 second delay * playlist.autoadvance() // cancel autoadvance * * @param {Player} player * The current player * * @param {Array=} initialList * If given, an initial list of sources with which to populate * the playlist. * * @param {number=} initialIndex * If given, the index of the item in the list that should * be loaded first. If -1, no video is loaded. If omitted, The * the first video is loaded. * * @return {Function} * Returns the playlist function specific to the given player. */ const factory = (player, initialList, initialIndex = 0) => { let list = Array.isArray(initialList) ? initialList.slice() : []; /** * Get/set the playlist for a player. * * This function is added as an own property of the player and has its * own methods which can be called to manipulate the internal state. * * @param {Array} [newList] * If given, a new list of sources with which to populate the * playlist. Without this, the function acts as a getter. * * @param {number} [newIndex] * If given, the index of the item in the list that should * be loaded first. If -1, no video is loaded. If omitted, The * the first video is loaded. * * @return {Array} * The playlist */ const playlist = player.playlist = function(newList, newIndex = 0) { if (Array.isArray(newList)) { list = newList.slice(); if (newIndex !== -1) { playlist.currentItem(newIndex); } playlist.changeTimeout_ = window.setTimeout(() => { player.trigger('playlistchange'); }, 0); } // Always return a shallow clone of the playlist list. return list.slice(); }; player.on('loadstart', () => { if (playlist.currentItem() === -1) { autoadvance.reset(player); } }); player.on('dispose', () => { window.clearTimeout(playlist.changeTimeout_); }); assign(playlist, { currentIndex_: -1, player_: player, autoadvance_: {}, repeat_: false, /** * Get or set the current item in the playlist. * * @param {number} [index] * If given as a valid value, plays the playlist item at that index. * * @return {number} * The current item index. */ currentItem(index) { if ( typeof index === 'number' &amp;&amp; playlist.currentIndex_ !== index &amp;&amp; index >= 0 &amp;&amp; index &lt; list.length ) { playlist.currentIndex_ = index; playItem( playlist.player_, playlist.autoadvance_.delay, list[playlist.currentIndex_] ); } else { playlist.currentIndex_ = playlist.indexOf(playlist.player_.currentSrc() || ''); } return playlist.currentIndex_; }, /** * Checks if the playlist contains a value. * * @param {string|Object|Array} value * The value to check * * @return {boolean} * The result */ contains(value) { return playlist.indexOf(value) !== -1; }, /** * Gets the index of a value in the playlist or -1 if not found. * * @param {string|Object|Array} value * The value to find the index of * * @return {number} * The index or -1 */ indexOf(value) { if (typeof value === 'string') { return indexInSources(list, value); } const sources = Array.isArray(value) ? value : value.sources; for (let i = 0; i &lt; sources.length; i++) { const source = sources[i]; if (typeof source === 'string') { return indexInSources(list, source); } else if (source.src) { return indexInSources(list, source.src); } } return -1; }, /** * Plays the first item in the playlist. * * @return {Object|undefined} * Returns undefined and has no side effects if the list is empty. */ first() { if (list.length) { return list[playlist.currentItem(0)]; } playlist.currentIndex_ = -1; }, /** * Plays the last item in the playlist. * * @return {Object|undefined} * Returns undefined and has no side effects if the list is empty. */ last() { if (list.length) { return list[playlist.currentItem(list.length - 1)]; } playlist.currentIndex_ = -1; }, /** * Plays the next item in the playlist. * * @return {Object|undefined} * Returns undefined and has no side effects if on last item. */ next() { let nextIndex; // Repeat if (playlist.repeat_) { nextIndex = playlist.currentIndex_ + 1; if (nextIndex > list.length - 1) { nextIndex = 0; } // Don't go past the end of the playlist. } else { nextIndex = Math.min(playlist.currentIndex_ + 1, list.length - 1); } // Make the change if (nextIndex !== playlist.currentIndex_) { return list[playlist.currentItem(nextIndex)]; } }, /** * Plays the previous item in the playlist. * * @return {Object|undefined} * Returns undefined and has no side effects if on first item. */ previous() { // Make sure we don't go past the start of the playlist. const index = Math.max(playlist.currentIndex_ - 1, 0); if (index !== playlist.currentIndex_) { return list[playlist.currentItem(index)]; } }, /** * Sets up auto-advance on the playlist. * * @param {number} delay * The number of seconds to wait before each auto-advance. */ autoadvance(delay) { playlist.autoadvance_.delay = delay; autoadvance.setup(playlist.player_, delay); }, /** * Sets `repeat` option, which makes the "next" video of the last video in the * playlist be the first video in the playlist. * * @param {boolean=} val * The value to set repeat to * * @return {boolean} * The current value of repeat */ repeat(val) { if (val !== undefined) { if (typeof val !== 'boolean') { videojs.log.error('Invalid value for repeat', val); } else { playlist.repeat_ = val; } } return playlist.repeat_; } }); playlist.currentItem(initialIndex); return playlist; }; export default factory; </code></pre> </article> </section> </div> <nav> <h2><a href="index.html">Home</a></h2><h3>Global</h3><ul><li><a href="global.html#autoadvance">autoadvance</a></li><li><a href="global.html#clearTracks">clearTracks</a></li><li><a href="global.html#contains">contains</a></li><li><a href="global.html#currentItem">currentItem</a></li><li><a href="global.html#factory">factory</a></li><li><a href="global.html#first">first</a></li><li><a href="global.html#indexOf">indexOf</a></li><li><a href="global.html#last">last</a></li><li><a href="global.html#next">next</a></li><li><a href="global.html#playItem">playItem</a></li><li><a href="global.html#plugin">plugin</a></li><li><a href="global.html#previous">previous</a></li><li><a href="global.html#repeat">repeat</a></li><li><a href="global.html#reset">reset</a></li><li><a href="global.html#setReset_">setReset_</a></li><li><a href="global.html#setup">setup</a></li></ul> </nav> <br class="clear"> <footer> Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Mon Nov 13 2017 16:41:55 GMT-0500 (EST) </footer> <script> prettyPrint(); </script> <script src="scripts/linenumber.js"> </script> </body> </html>