@vime-js/standard
Version:
Vime Standard Player
1,717 lines (1,539 loc) • 181 kB
JavaScript
// 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_