UNPKG

@vime-js/standard

Version:
1,717 lines (1,539 loc) 181 kB
// Treeshaking safe. const MediaType = function MediaType() {}; MediaType.NONE = 0; MediaType.AUDIO = 1; MediaType.VIDEO = 2; // Treeshaking safe. const PlayerState = function PlayerState() {}; PlayerState.IDLE = 1; PlayerState.CUED = 2; PlayerState.PLAYING = 3; PlayerState.PAUSED = 4; PlayerState.BUFFERING = 5; PlayerState.ENDED = 6; // Treeshaking safe. const VideoQuality = function VideoQuality() {}; VideoQuality.UNKNOWN = 0; VideoQuality.XXS = 144; VideoQuality.XS = 240; VideoQuality.S = 360; VideoQuality.M = 480; VideoQuality.L = 720; VideoQuality.XL = 1080; VideoQuality.XXL = 1440; VideoQuality.MAX = 2160; function noop() { } function assign(tar, src) { // @ts-ignore for (const k in src) tar[k] = src[k]; return tar; } function run(fn) { return fn(); } function blank_object() { return Object.create(null); } function run_all(fns) { fns.forEach(run); } function is_function(thing) { return typeof thing === 'function'; } function safe_not_equal(a, b) { return a != a ? b == b : a !== b || ((a && typeof a === 'object') || typeof a === 'function'); } function not_equal(a, b) { return a != a ? b == b : a !== b; } function subscribe(store, ...callbacks) { if (store == null) { return noop; } const unsub = store.subscribe(...callbacks); return unsub.unsubscribe ? () => unsub.unsubscribe() : unsub; } function get_store_value(store) { let value; subscribe(store, _ => value = _)(); return value; } function component_subscribe(component, store, callback) { component.$$.on_destroy.push(subscribe(store, callback)); } function create_slot(definition, ctx, $$scope, fn) { if (definition) { const slot_ctx = get_slot_context(definition, ctx, $$scope, fn); return definition[0](slot_ctx); } } function get_slot_context(definition, ctx, $$scope, fn) { return definition[1] && fn ? assign($$scope.ctx.slice(), definition[1](fn(ctx))) : $$scope.ctx; } function get_slot_changes(definition, $$scope, dirty, fn) { if (definition[2] && fn) { const lets = definition[2](fn(dirty)); if ($$scope.dirty === undefined) { return lets; } if (typeof lets === 'object') { const merged = []; const len = Math.max($$scope.dirty.length, lets.length); for (let i = 0; i < len; i += 1) { merged[i] = $$scope.dirty[i] | lets[i]; } return merged; } return $$scope.dirty | lets; } return $$scope.dirty; } function update_slot(slot, slot_definition, ctx, $$scope, dirty, get_slot_changes_fn, get_slot_context_fn) { const slot_changes = get_slot_changes(slot_definition, $$scope, dirty, get_slot_changes_fn); if (slot_changes) { const slot_context = get_slot_context(slot_definition, ctx, $$scope, get_slot_context_fn); slot.p(slot_context, slot_changes); } } function exclude_internal_props(props) { const result = {}; for (const k in props) if (k[0] !== '$') result[k] = props[k]; return result; } function set_store_value(store, ret, value = ret) { store.set(value); return ret; } function action_destroyer(action_result) { return action_result && is_function(action_result.destroy) ? action_result.destroy : noop; } const is_client = typeof window !== 'undefined'; let raf = is_client ? cb => requestAnimationFrame(cb) : noop; function append(target, node) { target.appendChild(node); } function insert(target, node, anchor) { target.insertBefore(node, anchor || null); } function detach(node) { node.parentNode.removeChild(node); } function destroy_each(iterations, detaching) { for (let i = 0; i < iterations.length; i += 1) { if (iterations[i]) iterations[i].d(detaching); } } function element(name) { return document.createElement(name); } function text(data) { return document.createTextNode(data); } function empty() { return text(''); } function listen(node, event, handler, options) { node.addEventListener(event, handler, options); return () => node.removeEventListener(event, handler, options); } function attr(node, attribute, value) { if (value == null) node.removeAttribute(attribute); else if (node.getAttribute(attribute) !== value) node.setAttribute(attribute, value); } function children(element) { return Array.from(element.childNodes); } function toggle_class(element, name, toggle) { element.classList[toggle ? 'add' : 'remove'](name); } function custom_event(type, detail) { const e = document.createEvent('CustomEvent'); e.initCustomEvent(type, false, false, detail); return e; } let current_component; function set_current_component(component) { current_component = component; } function get_current_component() { if (!current_component) throw new Error(`Function called outside component initialization`); return current_component; } function onMount(fn) { get_current_component().$$.on_mount.push(fn); } function afterUpdate(fn) { get_current_component().$$.after_update.push(fn); } function onDestroy(fn) { get_current_component().$$.on_destroy.push(fn); } function createEventDispatcher() { const component = get_current_component(); return (type, detail) => { const callbacks = component.$$.callbacks[type]; if (callbacks) { // TODO are there situations where events could be dispatched // in a server (non-DOM) environment? const event = custom_event(type, detail); callbacks.slice().forEach(fn => { fn.call(component, event); }); } }; } // TODO figure out if we still want to support // shorthand events, or if we want to implement // a real bubbling mechanism function bubble(component, event) { const callbacks = component.$$.callbacks[event.type]; if (callbacks) { callbacks.slice().forEach(fn => fn(event)); } } const dirty_components = []; const binding_callbacks = []; const render_callbacks = []; const flush_callbacks = []; const resolved_promise = Promise.resolve(); let update_scheduled = false; function schedule_update() { if (!update_scheduled) { update_scheduled = true; resolved_promise.then(flush); } } function tick() { schedule_update(); return resolved_promise; } function add_render_callback(fn) { render_callbacks.push(fn); } let flushing = false; const seen_callbacks = new Set(); function flush() { if (flushing) return; flushing = true; do { // first, call beforeUpdate functions // and update components for (let i = 0; i < dirty_components.length; i += 1) { const component = dirty_components[i]; set_current_component(component); update(component.$$); } dirty_components.length = 0; while (binding_callbacks.length) binding_callbacks.pop()(); // then, once components are updated, call // afterUpdate functions. This may cause // subsequent updates... for (let i = 0; i < render_callbacks.length; i += 1) { const callback = render_callbacks[i]; if (!seen_callbacks.has(callback)) { // ...so guard against infinite loops seen_callbacks.add(callback); callback(); } } render_callbacks.length = 0; } while (dirty_components.length); while (flush_callbacks.length) { flush_callbacks.pop()(); } update_scheduled = false; flushing = false; seen_callbacks.clear(); } function update($$) { if ($$.fragment !== null) { $$.update(); run_all($$.before_update); const dirty = $$.dirty; $$.dirty = [-1]; $$.fragment && $$.fragment.p($$.ctx, dirty); $$.after_update.forEach(add_render_callback); } } const outroing = new Set(); let outros; function group_outros() { outros = { r: 0, c: [], p: outros // parent group }; } function check_outros() { if (!outros.r) { run_all(outros.c); } outros = outros.p; } function transition_in(block, local) { if (block && block.i) { outroing.delete(block); block.i(local); } } function transition_out(block, local, detach, callback) { if (block && block.o) { if (outroing.has(block)) return; outroing.add(block); outros.c.push(() => { outroing.delete(block); if (callback) { if (detach) block.d(1); callback(); } }); block.o(local); } } const globals = (typeof window !== 'undefined' ? window : typeof globalThis !== 'undefined' ? globalThis : global); function get_spread_update(levels, updates) { const update = {}; const to_null_out = {}; const accounted_for = { $$scope: 1 }; let i = levels.length; while (i--) { const o = levels[i]; const n = updates[i]; if (n) { for (const key in o) { if (!(key in n)) to_null_out[key] = 1; } for (const key in n) { if (!accounted_for[key]) { update[key] = n[key]; accounted_for[key] = 1; } } levels[i] = n; } else { for (const key in o) { accounted_for[key] = 1; } } } for (const key in to_null_out) { if (!(key in update)) update[key] = undefined; } return update; } function get_spread_object(spread_props) { return typeof spread_props === 'object' && spread_props !== null ? spread_props : {}; } function create_component(block) { block && block.c(); } function mount_component(component, target, anchor) { const { fragment, on_mount, on_destroy, after_update } = component.$$; fragment && fragment.m(target, anchor); // onMount happens before the initial afterUpdate add_render_callback(() => { const new_on_destroy = on_mount.map(run).filter(is_function); if (on_destroy) { on_destroy.push(...new_on_destroy); } else { // Edge case - component was destroyed immediately, // most likely as a result of a binding initialising run_all(new_on_destroy); } component.$$.on_mount = []; }); after_update.forEach(add_render_callback); } function destroy_component(component, detaching) { const $$ = component.$$; if ($$.fragment !== null) { run_all($$.on_destroy); $$.fragment && $$.fragment.d(detaching); // TODO null out other refs, including component.$$ (but need to // preserve final state?) $$.on_destroy = $$.fragment = null; $$.ctx = []; } } function make_dirty(component, i) { if (component.$$.dirty[0] === -1) { dirty_components.push(component); schedule_update(); component.$$.dirty.fill(0); } component.$$.dirty[(i / 31) | 0] |= (1 << (i % 31)); } function init(component, options, instance, create_fragment, not_equal, props, dirty = [-1]) { const parent_component = current_component; set_current_component(component); const prop_values = options.props || {}; const $$ = component.$$ = { fragment: null, ctx: null, // state props, update: noop, not_equal, bound: blank_object(), // lifecycle on_mount: [], on_destroy: [], before_update: [], after_update: [], context: new Map(parent_component ? parent_component.$$.context : []), // everything else callbacks: blank_object(), dirty }; let ready = false; $$.ctx = instance ? instance(component, prop_values, (i, ret, ...rest) => { const value = rest.length ? rest[0] : ret; if ($$.ctx && not_equal($$.ctx[i], $$.ctx[i] = value)) { if ($$.bound[i]) $$.bound[i](value); if (ready) make_dirty(component, i); } return ret; }) : []; $$.update(); ready = true; run_all($$.before_update); // `false` as a special case of no DOM component $$.fragment = create_fragment ? create_fragment($$.ctx) : false; if (options.target) { if (options.hydrate) { const nodes = children(options.target); // eslint-disable-next-line @typescript-eslint/no-non-null-assertion $$.fragment && $$.fragment.l(nodes); nodes.forEach(detach); } else { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion $$.fragment && $$.fragment.c(); } if (options.intro) transition_in(component.$$.fragment); mount_component(component, options.target, options.anchor); flush(); } set_current_component(parent_component); } class SvelteComponent { $destroy() { destroy_component(this, 1); this.$destroy = noop; } $on(type, callback) { const callbacks = (this.$$.callbacks[type] || (this.$$.callbacks[type] = [])); callbacks.push(callback); return () => { const index = callbacks.indexOf(callback); if (index !== -1) callbacks.splice(index, 1); }; } $set() { // overridden by instance, if it has props } } const subscriber_queue = []; /** * Creates a `Readable` store that allows reading by subscription. * @param value initial value * @param {StartStopNotifier}start start and stop notifications for subscriptions */ function readable(value, start) { return { subscribe: writable(value, start).subscribe, }; } /** * Create a `Writable` store that allows both updating and reading by subscription. * @param {*=}value initial value * @param {StartStopNotifier=}start start and stop notifications for subscriptions */ function writable(value, start = noop) { let stop; const subscribers = []; function set(new_value) { if (safe_not_equal(value, new_value)) { value = new_value; if (stop) { // store is ready const run_queue = !subscriber_queue.length; for (let i = 0; i < subscribers.length; i += 1) { const s = subscribers[i]; s[1](); subscriber_queue.push(s, value); } if (run_queue) { for (let i = 0; i < subscriber_queue.length; i += 2) { subscriber_queue[i][0](subscriber_queue[i + 1]); } subscriber_queue.length = 0; } } } } function update(fn) { set(fn(value)); } function subscribe(run, invalidate = noop) { const subscriber = [run, invalidate]; subscribers.push(subscriber); if (subscribers.length === 1) { stop = start(set) || noop; } run(value); return () => { const index = subscribers.indexOf(subscriber); if (index !== -1) { subscribers.splice(index, 1); } if (subscribers.length === 0) { stop(); stop = null; } }; } return { set, update, subscribe }; } function derived(stores, fn, initial_value) { const single = !Array.isArray(stores); const stores_array = single ? [stores] : stores; const auto = fn.length < 2; return readable(initial_value, (set) => { let inited = false; const values = []; let pending = 0; let cleanup = noop; const sync = () => { if (pending) { return; } cleanup(); const result = fn(single ? values[0] : values, set); if (auto) { set(result); } else { cleanup = is_function(result) ? result : noop; } }; const unsubscribers = stores_array.map((store, i) => subscribe(store, (value) => { values[i] = value; pending &= ~(1 << i); if (inited) { sync(); } }, () => { pending |= (1 << i); })); inited = true; sync(); return function stop() { run_all(unsubscribers); cleanup(); }; }); } const currentPlayer = writable(null); // eslint-disable-next-line no-param-reassign const set_style = (el, prop, value = null) => { if (el) el.style[prop] = value; }; const get_computed_style = (el) => (el ? window.getComputedStyle(el) : null); const get_computed_width = (el) => (el ? parseFloat(get_computed_style(el).width) : 0); const is_null = (input) => input === null; const is_undefined = (input) => typeof input === 'undefined'; const is_null_or_undefined = (input) => is_null(input) || is_undefined(input); const get_constructor = (input) => ( !is_null_or_undefined(input) ? input.constructor : null ); const is_object = (input) => get_constructor(input) === Object; const is_number = (input) => get_constructor(input) === Number && !Number.isNaN(input); const is_string = (input) => get_constructor(input) === String; const is_boolean = (input) => get_constructor(input) === Boolean; const is_function$1 = (input) => get_constructor(input) === Function; const is_array = (input) => Array.isArray(input); const is_instance_of = (input, constructor) => Boolean( input && constructor && input instanceof constructor, ); function try_parse_json(json, onFail) { try { return JSON.parse(json); } catch (e) { if (onFail) onFail(e); return null; } } const is_json_or_obj = (input) => { if (!input) return false; return is_object(input) || input.startsWith('{'); }; const obj_or_try_parse_json = (input) => { if (is_object(input)) return input; return try_parse_json(input); }; /* eslint-disable max-len */ const IS_CLIENT = typeof window !== 'undefined'; const UA = (IS_CLIENT && window.navigator.userAgent.toLowerCase()); const IS_IE = (UA && /msie|trident/.test(UA)); const IS_IOS = (UA && /iphone|ipad|ipod|ios/.test(UA)); const IS_ANDROID = (UA && /android/.test(UA)); const IS_EDGE = (UA && UA.indexOf('edge/') > 0); const IS_CHROME = (UA && /chrome\/\d+/.test(UA) && !IS_EDGE); const IS_IPHONE = (IS_CLIENT && /(iPhone|iPod)/gi.test(navigator.platform)); const IS_MOBILE = (IS_IOS || IS_ANDROID); // @see https://developer.apple.com/documentation/webkitjs/htmlvideoelement/1633500-webkitenterfullscreen const can_fullscreen_video = () => { if (!IS_CLIENT) return false; const video = element('video'); return is_function$1(video.webkitEnterFullscreen); }; const can_play_hls_natively = () => { if (!IS_CLIENT) return false; const video = element('video'); return video.canPlayType('application/vnd.apple.mpegurl'); }; // Chrome // @see https://developers.google.com/web/updates/2018/10/watch-video-using-picture-in-picture const can_use_pip_in_chrome = () => { if (!IS_CLIENT) return false; const video = element('video'); return !!document.pictureInPictureEnabled && !video.disablePictureInPicture; }; // Safari // iPhone safari appears to "support" PiP through the check, however PiP does not function. // @see https://developer.apple.com/documentation/webkitjs/adding_picture_in_picture_to_your_safari_media_controls const can_use_pip_in_safari = () => { if (!IS_CLIENT) return false; const video = element('video'); return is_function$1(video.webkitSupportsPresentationMode) && is_function$1(video.webkitSetPresentationMode) && !IS_IPHONE; }; const can_use_pip = () => can_use_pip_in_chrome() || can_use_pip_in_safari(); /** * To detect autoplay, we create a video element and call play on it, if it is `paused` after * a `play()` call, autoplay is supported. Although this unintuitive, it works across browsers * and is currently the lightest way to detect autoplay without using a data source. * * @see https://github.com/ampproject/amphtml/blob/9bc8756536956780e249d895f3e1001acdee0bc0/src/utils/video.js#L25 */ const can_autoplay = (muted = true, playsinline = true) => { if (!IS_CLIENT) return false; const video = element('video'); if (muted) { video.setAttribute('muted', ''); video.muted = true; } if (playsinline) { video.setAttribute('playsinline', ''); video.setAttribute('webkit-playsinline', ''); video.playsinline = true; video.webkitPlaysinline = true; } video.setAttribute('height', '0'); video.setAttribute('width', '0'); video.style.position = 'fixed'; video.style.top = 0; video.style.width = 0; video.style.height = 0; video.style.opacity = 0; // Promise wrapped this way to catch both sync throws and async rejections. // More info: https://github.com/tc39/proposal-promise-try new Promise((resolve) => resolve(video.play())).catch(noop); return Promise.resolve(!video.paused); }; const try_decode_uri_component = (component, fallback = '') => { if (!IS_CLIENT) return fallback; try { return window.decodeURIComponent(component); } catch (e) { return fallback; } }; // eslint-disable-next-line max-len // @see https://github.com/ampproject/amphtml/blob/c7c46cec71bac92f5c5da31dcc6366c18577f566/src/url-parse-query-string.js#L31 const QUERY_STRING_REGEX = /(?:^[#?]?|&)([^=&]+)(?:=([^&]*))?/g; const parse_query_string = (qs) => { const params = Object.create(null); if (!qs) return params; let match; // eslint-disable-next-line no-cond-assign while ((match = QUERY_STRING_REGEX.exec(qs))) { const name = try_decode_uri_component(match[1], match[1]).replace('[]', ''); const value = match[2] ? try_decode_uri_component(match[2].replace(/\+/g, ' '), match[2]) : ''; const currValue = params[name]; if (currValue && !is_array(currValue)) params[name] = [currValue]; currValue ? params[name].push(value) : (params[name] = value); } return params; }; const serialize_query_string = (params) => { const qs = []; const appendQueryParam = (param, v) => { qs.push(`${encodeURIComponent(param)}=${encodeURIComponent(v)}`); }; Object.keys(params).forEach((param) => { const value = params[param]; if (is_null_or_undefined(value)) return; if (is_array(value)) { value.forEach((v) => appendQueryParam(param, v)); } else { appendQueryParam(param, value); } }); return qs.join('&'); }; const apppend_querystring_to_url = (url, qs) => { if (!qs) return url; const mainAndQuery = url.split('?', 2); return mainAndQuery[0] + (mainAndQuery[1] ? `?${mainAndQuery[1]}&${qs}` : `?${qs}`); }; const add_params_to_url = ( url, params, ) => apppend_querystring_to_url(url, serialize_query_string(params)); const prefetch = (rel, url, as) => { if (!IS_CLIENT) return false; const link = element('link'); link.rel = rel; link.href = url; if (as) link.as = as; link.crossorigin = true; document.head.append(link); return true; }; const decode_json = (data) => is_json_or_obj(data) && obj_or_try_parse_json(data); const decode_query_string = (data) => is_string(data) && parse_query_string(data); const load_script = (src, onLoad, onError) => { const script = document.createElement('script'); script.src = src; script.onload = onLoad; script.onerror = onError; const firstScriptTag = document.getElementsByTagName('script')[0]; firstScriptTag.parentNode.insertBefore(script, firstScriptTag); }; /** * Load image avoiding xhr/fetch CORS issues. Server status can't be obtained this way * unfortunately, so this uses "naturalWidth" to determine if the image has been loaded. By * default it checks if it is at least 1px. */ const load_image = (src, minWidth = 1) => new Promise((resolve, reject) => { const image = new Image(); const handler = () => { delete image.onload; delete image.onerror; image.naturalWidth >= minWidth ? resolve(image) : reject(image); }; Object.assign(image, { onload: handler, onerror: handler, src }); }); // @see https://github.com/CookPete/react-player/blob/master/src/utils.js#L64 const load_library = (url, global) => { if (window[global]) return Promise.resolve(window[global]); return new Promise((resolve, reject) => { const onLoad = () => { resolve(window[global]); }; const onError = (error) => { reject(error); }; load_script(url, onLoad, onError); }); }; const create_prop = ( object, key, descriptor, ) => Object.defineProperty(object, key, descriptor); const deferred = () => { let resolve; let reject; const promise = new Promise((res, rej) => { resolve = res; reject = rej; }); return { promise, resolve, reject }; }; const is_store = (store) => store && is_function$1(store.subscribe); const safe_get = (v) => (is_store(v) ? get_store_value(v) : v); // Private is "private" to the component who instantiates it, when it is exposed publically // the set method should be removed. The utility `make_private_stores_readonly` does exactly // this. This is also what `map_store_to_component` below uses. const make_store_private = (store) => ({ ...store, private: true, }); const add_condition_to_store = (store, condition) => ({ ...store, set: (value) => { if (safe_get(condition)) store.set(value); }, forceSet: store.set, }); const private_writable = (initialValue) => make_store_private(writable(initialValue)); const writable_if = ( initialValue, condition, ) => add_condition_to_store(writable(initialValue), condition); const private_writable_if = ( initialValue, condition, ) => make_store_private(writable_if(initialValue, condition)); const indexable = (bounds) => { const store = writable(-1); return { ...store, subscribe: derived([store, bounds], ([$value, $bounds]) => { if (!$bounds || $bounds.length === 0) return -1; if ($value >= 0 && $value < $bounds.length) return $value; return -1; }).subscribe, }; }; const rangeable = (initialValue, lowerBound, upperBound) => { const store = writable(initialValue); return { ...store, set: (value) => { store.set(Math.max(safe_get(lowerBound), Math.min(value, safe_get(upperBound)))); }, }; }; const rangeable_if = ( initialValue, lowerBound, upperBound, condition, ) => add_condition_to_store(rangeable(initialValue, lowerBound, upperBound), condition); const selectable = (initialValue, values) => { let newValue; const store = writable(initialValue); return { ...store, subscribe: derived([store, values], ([$value, $values]) => { if (!$values) { newValue = null; } if ($values.includes($value)) { newValue = $value; } return newValue; }).subscribe, }; }; const selectable_if = ( initialValue, values, condition, ) => add_condition_to_store(selectable(initialValue, values), condition); const make_store_readonly = (store) => ({ subscribe: store.subscribe }); const make_private_stores_readonly = (stores) => { const result = {}; Object.keys(stores).forEach((name) => { const store = stores[name]; result[name] = store.private ? make_store_readonly(store) : store; }); return result; }; const map_store_to_component = (comp, stores) => { let canWrite = {}; const component = comp || get_current_component(); create_prop(component, 'getStore', { get: () => () => make_private_stores_readonly(stores), configurable: true, }); component.$$.on_destroy.push(() => { Object.keys(stores).forEach((prop) => { delete component[prop]; }); delete component.getStore; canWrite = {}; }); const onUpdateProp = (prop, newValue, shouldFlush = false) => { if (!canWrite[prop] || !not_equal(get_store_value(stores[prop]), newValue)) return; stores[prop].set(newValue); if (shouldFlush) flush(); }; Object.keys(stores).forEach((prop) => { const store = stores[prop]; canWrite[prop] = !!store.set && !store.private; create_prop(component, prop, { get: () => get_store_value(store), set: canWrite[prop] ? ((v) => { onUpdateProp(prop, v, true); }) : undefined, configurable: true, }); }); // onPropsChange return (props) => Object.keys(props).forEach((prop) => { onUpdateProp(prop, props[prop]); }); }; function vAspectRatio(node, initialAspectRatio) { const update = (newAspectRatio) => { if (!newAspectRatio) { set_style(node, 'paddingBottom'); return; } const [width, height] = newAspectRatio.split(':'); set_style(node, 'paddingBottom', `${(100 / width) * height}%`); }; update(initialAspectRatio); return { update, destroy() { update(null); }, }; } // Player defaults used when the `src` changes or `resetStore` is called. const playerDefaults = () => ({ paused: true, playing: false, seeking: false, rebuilding: false, internalTime: 0, currentTime: 0, title: '', duration: 0, buffered: 0, mediaId: null, currentSrc: null, buffering: false, videoQuality: VideoQuality.UNKNOWN, videoQualities: [], playbackRate: 1, playbackRates: [1], playbackStarted: false, playbackEnded: false, playbackReady: false, isLive: false, nativePoster: null, isControlsActive: true, }); const resetStore = (store) => { const defaults = playerDefaults(); Object.keys(defaults) .forEach((prop) => store[prop] && store[prop].set(defaults[prop])); }; const fillStore = async (store) => { store.canAutoplay.set(await can_autoplay(false)); store.canMutedAutoplay.set(await can_autoplay(true)); }; const buildStandardStore = (player) => { const store = {}; const defaults = playerDefaults(); store.playbackReady = private_writable(defaults.playbackReady); store.rebuilding = private_writable_if(defaults.rebuilding, store.playbackReady); store.canAutoplay = private_writable(false); store.canMutedAutoplay = private_writable(false); store.canInteract = derived( [store.playbackReady, store.rebuilding], ([$playbackReady, $rebuilding]) => $playbackReady && !$rebuilding, ); // -------------------------------------------------------------- // Native // -------------------------------------------------------------- store.useNativeView = writable(true); store.useNativeControls = writable(true); store.useNativeCaptions = writable(true); store.nativePoster = private_writable(defaults.nativePoster); // -------------------------------------------------------------- // Src // -------------------------------------------------------------- store.src = writable(null); store.mediaId = private_writable(defaults.mediaId); store.poster = writable(null); store.provider = private_writable(null); store.providers = writable([]); store.providerConfig = writable({}); store.providerVersion = writable('latest'); store.origin = private_writable(null); store.title = private_writable(defaults.title); store.currentSrc = private_writable(defaults.currentSrc); store.Provider = derived( [store.src, store.providers], ([$src, $providers]) => $providers.find((p) => p.canPlay($src)), ); store.canSetPoster = derived( store.provider, ($provider) => $provider && is_function$1($provider.setPoster), ); // -------------------------------------------------------------- // Metadata // -------------------------------------------------------------- store.mediaType = private_writable(MediaType.NONE); store.isAudio = derived(store.mediaType, ($mediaType) => $mediaType === MediaType.AUDIO); store.isVideo = derived(store.mediaType, ($mediaType) => $mediaType === MediaType.VIDEO); store.isLive = private_writable(false); store.playbackRates = private_writable(defaults.playbackRates); store.videoQualities = private_writable(defaults.videoQualities); store.duration = private_writable(defaults.duration); // Used by @vime-js/complete. // eslint-disable-next-line no-underscore-dangle store._posterPlugin = writable(false); store.isVideoView = derived( // eslint-disable-next-line no-underscore-dangle [store.poster, store.nativePoster, store.canSetPoster, store._posterPlugin, store.isVideo], ([ $poster, $nativePoster, $canSetPoster, $plugin, $isVideo, ]) => !!(($canSetPoster || $plugin) && ($poster || $nativePoster)) || $isVideo, ); store.isVideoReady = derived( [store.playbackReady, store.isVideoView], ([$playbackReady, $isVideoView]) => $playbackReady && $isVideoView, ); // -------------------------------------------------------------- // Playback // -------------------------------------------------------------- store.canSetPlaybackRate = derived( [store.provider, store.playbackRates], ([ $provider, $playbackRates, ]) => $provider && $playbackRates.length > 1 && is_function$1($provider.setPlaybackRate), ); store.canSetVideoQuality = derived( [store.provider, store.isVideo, store.videoQualities], ([$provider, $isVideo, $videoQualities]) => $provider && $isVideo && $videoQualities.length > 0 && is_function$1($provider.setVideoQuality), ); store.paused = writable(defaults.paused); store.playbackRate = selectable_if( defaults.playbackRate, store.playbackRates, store.canSetPlaybackRate, ); store.videoQuality = selectable_if( defaults.videoQuality, store.videoQualities, store.canSetVideoQuality, ); store.currentTime = rangeable(defaults.currentTime, 0, store.duration); store.internalTime = private_writable(defaults.internalTime); store.muted = writable(false); store.volume = rangeable_if(30, 0, 100, !IS_MOBILE); store.buffered = private_writable(defaults.buffered); store.isControlsEnabled = writable(true); store.isControlsActive = private_writable(defaults.isControlsActive); store.progress = derived( [store.currentTime, store.duration, store.buffered], ([$currentTime, $duration, $buffered]) => ({ played: { seconds: $currentTime, percent: ($currentTime / $duration) * 100, }, buffered: { seconds: $buffered, percent: ($buffered / $duration) * 100, }, }), ); // -------------------------------------------------------------- // State // -------------------------------------------------------------- store.playing = private_writable(defaults.playing); store.buffering = private_writable(defaults.buffering); store.playbackEnded = private_writable(defaults.playbackEnded); store.playbackStarted = private_writable(defaults.playbackStarted); store.seeking = private_writable(defaults.seeking); store.isPlayerActive = private_writable(false); store.state = derived( [ store.playbackStarted, store.playbackEnded, store.paused, store.buffering, store.playbackReady, ], ([$playbackStarted, $playbackEnded, $paused, $buffering, $playbackReady]) => { if ($playbackEnded) { return PlayerState.ENDED; } if ($buffering) { return PlayerState.BUFFERING; } if ($playbackStarted && $paused) { return PlayerState.PAUSED; } if ($playbackStarted) { return PlayerState.PLAYING; } if ($playbackReady) { return PlayerState.CUED; } return PlayerState.IDLE; }, ); // -------------------------------------------------------------- // Tracks // -------------------------------------------------------------- store.canSetTracks = derived( store.provider, ($provider) => $provider && is_function$1($provider.setTracks), ); // Don't block writing of `tracks` as it might be stored and used by a provider when possible. store.tracks = writable([]); store.canSetTrack = derived( [store.provider, store.tracks], ([$provider, $tracks]) => $provider && $tracks && $tracks.length > 0 && is_function$1($provider.setTrack), ); // Can't block current track with `canSetTrack` because it'll stop @vime-js/complete from updating // the value when a plugin is managing captions. store.currentTrackIndex = indexable(store.tracks); store.currentTrack = derived( [store.tracks, store.currentTrackIndex], ([$tracks, $index]) => (($index >= 0) ? $tracks[$index] : null), ); store.isCaptionsActive = derived( [store.playbackReady, store.isAudio, store.currentTrackIndex], ([$playbackReady, $isAudio, $currentTrackIndex]) => $playbackReady && !$isAudio && ($currentTrackIndex !== -1), ); // TODO: add cues support (cues, currentCueIndex, currentCue, activeCues). // -------------------------------------------------------------- // Picture in Picture // -------------------------------------------------------------- store.canSetPiP = derived( [store.isVideoReady, store.provider], ([$isVideoReady, $provider]) => $isVideoReady && $provider && $provider.supportsPiP() && is_function$1($provider.setPiP), ); store.isPiPActive = private_writable(false); // -------------------------------------------------------------- // Fullscreen // -------------------------------------------------------------- // Set in the Player. store.canSetFullscreen = private_writable(false); store.isFullscreenActive = private_writable(false); // -------------------------------------------------------------- // Options // -------------------------------------------------------------- store.autopause = writable(true); store.aspectRatio = writable('16:9'); store.playsinline = writable(true); store.autoplay = writable(false); store.loop = writable(false); fillStore(store); return { store, onPropsChange: map_store_to_component(player, store), resetStore: () => resetStore(store), }; }; /* Users/rahim/Desktop/Projects/vime/vime-1.x/packages/vime-lite/src/Embed.svelte generated by Svelte v3.24.0 */ function add_css() { var style = element("style"); style.id = "svelte-7bba2w-style"; style.textContent = "iframe.svelte-7bba2w{position:absolute;top:0;left:0;border:0;-webkit-user-select:none;user-select:none;width:100%;height:100%}"; append(document.head, style); } function create_fragment(ctx) { let iframe_1; let iframe_1_src_value; let mounted; let dispose; return { c() { iframe_1 = element("iframe"); attr(iframe_1, "id", /*id*/ ctx[3]); attr(iframe_1, "title", /*title*/ ctx[0]); if (iframe_1.src !== (iframe_1_src_value = /*srcWithParams*/ ctx[2])) attr(iframe_1, "src", iframe_1_src_value); iframe_1.allowFullscreen = "1"; attr(iframe_1, "allow", "accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"); attr(iframe_1, "class", "svelte-7bba2w"); }, m(target, anchor) { insert(target, iframe_1, anchor); /*iframe_1_binding*/ ctx[15](iframe_1); if (!mounted) { dispose = [ listen(window, "message", /*onMessage*/ ctx[4]), listen(iframe_1, "load", /*load_handler*/ ctx[14]) ]; mounted = true; } }, p(ctx, [dirty]) { if (dirty & /*title*/ 1) { attr(iframe_1, "title", /*title*/ ctx[0]); } if (dirty & /*srcWithParams*/ 4 && iframe_1.src !== (iframe_1_src_value = /*srcWithParams*/ ctx[2])) { attr(iframe_1, "src", iframe_1_src_value); } }, i: noop, o: noop, d(detaching) { if (detaching) detach(iframe_1); /*iframe_1_binding*/ ctx[15](null); mounted = false; run_all(dispose); } }; } let idCount = 0; const PRECONNECTED = []; function instance($$self, $$props, $$invalidate) { let iframe = null; let srcWithParams = null; // eslint-disable-next-line prefer-const idCount += 1; const id = `vime-embed-${idCount}`; const dispatch = createEventDispatcher(); const Event = { SRC_CHANGE: "srcchange", MESSAGE: "message", DATA: "data", REBUILD: "rebuild" }; let { src = null } = $$props; let { title = null } = $$props; let { params = {} } = $$props; let { origin = null } = $$props; let { preconnections = [] } = $$props; let { decoder = null } = $$props; const getId = () => id; const getIframe = () => iframe; const getSrc = () => srcWithParams; const postMessage = (message, target) => { if (!iframe || !iframe.contentWindow) return; iframe.contentWindow.postMessage(JSON.stringify(message), target || origin || "*"); }; const originMatches = e => { if (!iframe || e.source !== iframe.contentWindow) return false; return is_string(origin) && origin === e.origin; }; const onMessage = e => { if (!originMatches(e)) return; dispatch(Event.MESSAGE, e); const data = decoder ? decoder(e.data) : null; if (data) dispatch(Event.DATA, data); }; let hasMounted = false; onMount(() => { $$invalidate(16, hasMounted = true); }); function load_handler(event) { bubble($$self, event); } function iframe_1_binding($$value) { binding_callbacks[$$value ? "unshift" : "push"](() => { iframe = $$value; $$invalidate(1, iframe); }); } $$self.$set = $$props => { if ("src" in $$props) $$invalidate(5, src = $$props.src); if ("title" in $$props) $$invalidate(0, title = $$props.title); if ("params" in $$props) $$invalidate(6, params = $$props.params); if ("origin" in $$props) $$invalidate(7, origin = $$props.origin); if ("preconnections" in $$props) $$invalidate(8, preconnections = $$props.preconnections); if ("decoder" in $$props) $$invalidate(9, decoder = $$props.decoder); }; $$self.$$.update = () => { if ($$self.$$.dirty & /*hasMounted, src, params*/ 65632) { if (hasMounted) $$invalidate(2, srcWithParams = src ? add_params_to_url(src, params) : null); } if ($$self.$$.dirty & /*hasMounted, srcWithParams*/ 65540) { if (hasMounted) dispatch(Event.SRC_CHANGE, srcWithParams); } if ($$self.$$.dirty & /*hasMounted, srcWithParams*/ 65540) { if (hasMounted && srcWithParams) dispatch(Event.REBUILD); } if ($$self.$$.dirty & /*hasMounted, srcWithParams, iframe*/ 65542) { if (hasMounted && srcWithParams && !iframe && !PRECONNECTED.includes(srcWithParams)) { if (prefetch("preconnect", srcWithParams)) PRECONNECTED.push(srcWithParams); } } if ($$self.$$.dirty & /*hasMounted, preconnections*/ 65792) { // TODO: improve preconnections // @see https://github.com/ampproject/amphtml/blob/master/src/preconnect.js if (hasMounted) { preconnections.filter(p => !PRECONNECTED.includes(p)).forEach(url => { if (prefetch("preconnect", url)) PRECONNECTED.push(url); }); } } }; return [ title, iframe, srcWithParams, id, onMessage, src, params, origin, preconnections, decoder, getId, getIframe, getSrc, postMessage, load_handler, iframe_1_binding ]; } class Embed extends SvelteComponent { constructor(options) { super(); if (!document.getElementById("svelte-7bba2w-style")) add_css(); init(this, options, instance, create_fragment, safe_not_equal, { src: 5, title: 0, params: 6, origin: 7, preconnections: 8, decoder: 9, getId: 10, getIframe: 11, getSrc: 12, postMessage: 13 }); } get getId() { return this.$$.ctx[10]; } get getIframe() { return this.$$.ctx[11]; } get getSrc() { return this.$$.ctx[12]; } get postMessage() { return this.$$.ctx[13]; } } /* Users/rahim/Desktop/Projects/vime/vime-1.x/packages/vime-lite/src/Lazy.svelte generated by Svelte v3.24.0 */ function add_css$1() { var style = element("style"); style.id = "svelte-rzesm5-style"; style.textContent = "div.svelte-rzesm5{width:100%}"; append(document.head, style); } const get_default_slot_changes = dirty => ({ intersecting: dirty & /*intersecting*/ 2 }); const get_default_slot_context = ctx => ({ intersecting: /*intersecting*/ ctx[1] }); function create_fragment$1(ctx) { let div; let current; const default_slot_template = /*$$slots*/ ctx[4].default; const default_slot = create_slot(default_slot_template, ctx, /*$$scope*/ ctx[3], get_default_slot_context); return { c() { div = element("div"); if (default_slot) default_slot.c(); attr(div, "class", "svelte-rzesm5"); }, m(target, anchor) { insert(target, div, anchor); if (default_slot) { default_slot.m(div, null); } /*div_binding*/ ctx[5](div); current = true; }, p(ctx, [dirty]) { if (default_slot) { if (default_slot.p && dirty & /*$$scope, intersecting*/ 10) { update_slot(default_slot, default_slot_template, ctx, /*$$scope*/ ctx[3], dirty, get_default_slot_changes, get_default_slot_context); } } }, i(local) { if (current) return; transition_in(default_slot, local); current = true; }, o(local) { transition_out(default_slot, local); current = false; }, d(detaching) { if (detaching) detach(div); if (default_slot) default_slot.d(detaching); /*div_binding*/ ctx[5](null); } }; } function instance$1($$self, $$props, $$invalidate) { let el; let intersecting = false; let { threshold = 0.75 } = $$props; onMount(() => { if (typeof IntersectionObserver !== "undefined") { const observer = new IntersectionObserver(entries => { $$invalidate(1, intersecting = entries[0].isIntersecting); if (intersecting) observer.unobserve(el); }, { threshold }); observer.observe(el); return () => observer.unobserve(el); } function onScroll() { const rect = el.getBoundingClientRect(); $$invalidate(1, intersecting = rect.bottom > 0 && rect.right > 0 && rect.top * (1 + threshold) < window.innerHeight && rect.left < window.innerWidth); if (intersecting) window.removeEventListener("scroll", onScroll); } window.addEventListener("scroll", onScroll); return () => window.removeEventListener("scroll", onScroll); }); let { $$slots = {}, $$scope } = $$props; function div_binding($$value) { binding_callbacks[$$value ? "unshift" : "push"](() => { el = $$value; $$invalidate(0, el); }); } $$self.$set = $$props => { if ("threshold" in $$props) $$invalidate(2, threshold = $$props.threshold); if ("$$scope" in $$props) $$invalidate(3, $$scope = $$props.$$scope); }; return [el, intersecting, threshold, $$scope, $$slots, div_binding]; } class Lazy extends SvelteComponent { constructor(options) { super(); if (!document.getElementById("svelte-rzesm5-style")) add_css$1(); init(this, options, instance$1, create_fragment$1, safe_not_equal, { threshold: 2 }); } } /* Users/rahim/Desktop/Projects/vime/vime-1.x/packages/vime-lite/src/PlayerWrapper.svelte generated by Svelte v3.24.0 */ function add_css$2() { var style = element("style"); style.id = "svelte-y6iyru-style"; style.textContent = "div.svelte-y6iyru{position:relative}.video.svelte-y6iyru{height:0;overflow:hidden;background:#000}"; append(document.head, style); } // (13:0) {:else} function create_else_block(ctx) { let current; const default_slot_template = /*$$slots*/ ctx[3].default; const default_slot = create_slot(default_slot_template, ctx, /*$$scope*/ ctx[5], null); return { c() { if (default_slot) default_slot.c(); }, m(target, anchor) { if (default_slot) { default_slot.m(target, anchor); } current = true; }, p(ctx, dirty) { if (default_slot) { if (default_slot.p && dirty & /*$$scope*/ 32) { update_slot(default_slot, default_slot_template, ctx, /*$$scope*/ ctx[5], dirty, null, null); } } }, i(local) { if (current) return; transition_in(default_slot, local); current = true; }, o(local) { transition_out(default_slot, local); current = false; }, d(detaching) { if (default_slot) default_slot.d(detaching); } }; } // (1:0) {#if isEnabled} function create_if_block(ctx) { let lazy; let current; lazy = new Lazy({ props: { $$slots: { default: [ create_default_slot, ({ intersecting }) => ({ 7: intersecting }), ({ intersecting }) => intersecting ? 128 : 0 ] }, $$scope: { ctx } } }); return { c() { create_component(lazy.$$.fragment); }, m(target, anchor) { mount_component(lazy, target, anchor); current = true; }, p(ctx, dirty) { const lazy_changes = {}; if (dirty & /*$$scope, el, isEnabled, aspectRatio, intersecting*/ 167) { lazy_changes.$$scope = { dirty, ctx }; } lazy.$set(lazy_changes); }, i(local) { if (current) return; transition_in(lazy.$$.fragment, local); current = true; }, o(local) { transition_out(lazy.$$.fragment, local); current = false; }, d(detaching) { destroy_component(lazy, detaching); } }; } // (3:4) {#if intersecting} function create_if_block_1(ctx) { let div; let vAspectRatio_action; let current; let mounted; let dispose; const default_slot_template = /*$$slots*/ ctx[3].default; const default_slot = create_slot(default_slot_template, ctx, /*$$scope*/ ctx[5], null); return { c() { div = element("div"); if (default_slot) default_slot.c(); attr(div, "class", "svelte-y6iyru"); toggle_class(div, "video", !is_null(/*aspectRatio*/ ctx[0])); }, m(target, anchor) { insert(target, div, anchor); if (default_slot) { default_slot.m(div, null); } /*div_binding*/ ctx[4](div); current = true; if (!mounted) { dispose = action_destroyer(vAspectRatio_action = vAspectRatio.call(null, div, /*isEnabled*/ ctx[1] ? /*aspectRatio*/ ctx[0] : null)); mounted = true; } }, p(ctx, dirty) { if (default_