UNPKG

react-player

Version:

A React component for playing a variety of URLs, including file paths, YouTube, Facebook, Twitch, SoundCloud, Streamable, Vimeo, Wistia and DailyMotion

164 lines (148 loc) 4.84 kB
import loadScript from 'load-script' import merge from 'deepmerge' const MATCH_START_QUERY = /[?&#](?:start|t)=([0-9hms]+)/ const MATCH_END_QUERY = /[?&#]end=([0-9hms]+)/ const MATCH_START_STAMP = /(\d+)(h|m|s)/g const MATCH_NUMERIC = /^\d+$/ // Parse YouTube URL for a start time param, ie ?t=1h14m30s // and return the start time in seconds function parseTimeParam (url, pattern) { if (url instanceof Array) { return undefined } const match = url.match(pattern) if (match) { const stamp = match[1] if (stamp.match(MATCH_START_STAMP)) { return parseTimeString(stamp) } if (MATCH_NUMERIC.test(stamp)) { return parseInt(stamp) } } return undefined } function parseTimeString (stamp) { let seconds = 0 let array = MATCH_START_STAMP.exec(stamp) while (array !== null) { const [, count, period] = array if (period === 'h') seconds += parseInt(count, 10) * 60 * 60 if (period === 'm') seconds += parseInt(count, 10) * 60 if (period === 's') seconds += parseInt(count, 10) array = MATCH_START_STAMP.exec(stamp) } return seconds } export function parseStartTime (url) { return parseTimeParam(url, MATCH_START_QUERY) } export function parseEndTime (url) { return parseTimeParam(url, MATCH_END_QUERY) } // http://stackoverflow.com/a/38622545 export function randomString () { return Math.random().toString(36).substr(2, 5) } export function queryString (object) { return Object .keys(object) .map(key => `${key}=${object[key]}`) .join('&') } function getGlobal (key) { if (window[key]) { return window[key] } if (window.exports && window.exports[key]) { return window.exports[key] } if (window.module && window.module.exports && window.module.exports[key]) { return window.module.exports[key] } return null } // Util function to load an external SDK // or return the SDK if it is already loaded const requests = {} export function getSDK (url, sdkGlobal, sdkReady = null, isLoaded = () => true, fetchScript = loadScript) { const existingGlobal = getGlobal(sdkGlobal) if (existingGlobal && isLoaded(existingGlobal)) { return Promise.resolve(existingGlobal) } return new Promise((resolve, reject) => { // If we are already loading the SDK, add the resolve and reject // functions to the existing array of requests if (requests[url]) { requests[url].push({ resolve, reject }) return } requests[url] = [{ resolve, reject }] const onLoaded = sdk => { // When loaded, resolve all pending request promises requests[url].forEach(request => request.resolve(sdk)) } if (sdkReady) { const previousOnReady = window[sdkReady] window[sdkReady] = function () { if (previousOnReady) previousOnReady() onLoaded(getGlobal(sdkGlobal)) } } fetchScript(url, err => { if (err) { // Loading the SDK failed – reject all requests and // reset the array of requests for this SDK requests[url].forEach(request => request.reject(err)) requests[url] = null } else if (!sdkReady) { onLoaded(getGlobal(sdkGlobal)) } }) }) } export function getConfig (props, defaultProps) { return merge(defaultProps.config, props.config) } export function omit (object, ...arrays) { const omitKeys = [].concat(...arrays) const output = {} const keys = Object.keys(object) for (const key of keys) { if (omitKeys.indexOf(key) === -1) { output[key] = object[key] } } return output } export function callPlayer (method, ...args) { // Util method for calling a method on this.player // but guard against errors and console.warn instead if (!this.player || !this.player[method]) { let message = `ReactPlayer: ${this.constructor.displayName} player could not call %c${method}%c – ` if (!this.player) { message += 'The player was not available' } else if (!this.player[method]) { message += 'The method was not available' } console.warn(message, 'font-weight: bold', '') return null } return this.player[method](...args) } export function isMediaStream (url) { return ( typeof window !== 'undefined' && typeof window.MediaStream !== 'undefined' && url instanceof window.MediaStream ) } export function isBlobUrl (url) { return /^blob:/.test(url) } export function supportsWebKitPresentationMode (video = document.createElement('video')) { // Check if Safari supports PiP, and is not on mobile (other than iPad) // iPhone safari appears to "support" PiP through the check, however PiP does not function const notMobile = /iPhone|iPod/.test(navigator.userAgent) === false return video.webkitSupportsPresentationMode && typeof video.webkitSetPresentationMode === 'function' && notMobile }