diff options
Diffstat (limited to 'src/js/source.js')
-rw-r--r-- | src/js/source.js | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/src/js/source.js b/src/js/source.js new file mode 100644 index 00000000..d2d5f61a --- /dev/null +++ b/src/js/source.js @@ -0,0 +1,162 @@ +// ========================================================================== +// Plyr source update +// ========================================================================== + +import types from './types'; +import utils from './utils'; +import media from './media'; +import ui from './ui'; +import support from './support'; + +const source = { + // Add elements to HTML5 media (source, tracks, etc) + insertElements(type, attributes) { + if (utils.is.string(attributes)) { + utils.insertElement(type, this.media, { + src: attributes, + }); + } else if (utils.is.array(attributes)) { + this.warn(attributes); + + attributes.forEach(attribute => { + utils.insertElement(type, this.media, attribute); + }); + } + }, + + // Update source + // Sources are not checked for support so be careful + change(input) { + if (!utils.is.object(input) || !('sources' in input) || !input.sources.length) { + this.warn('Invalid source format'); + return; + } + + // Cancel current network requests + media.cancelRequests.call(this); + + // Destroy instance and re-setup + this.destroy.call( + this, + () => { + // TODO: Reset menus here + + // Remove elements + utils.removeElement(this.media); + this.media = null; + + // Reset class name + if (utils.is.htmlElement(this.elements.container)) { + this.elements.container.removeAttribute('class'); + } + + // Set the type + if ('type' in input) { + this.type = input.type; + + // Get child type for video (it might be an embed) + if (this.type === 'video') { + const firstSource = input.sources[0]; + + if ('type' in firstSource && types.embed.includes(firstSource.type)) { + this.type = firstSource.type; + } + } + } + + // Check for support + this.supported = support.check(this.type, this.config.inline); + + // Create new markup + switch (this.type) { + case 'video': + this.media = utils.createElement('video'); + break; + + case 'audio': + this.media = utils.createElement('audio'); + break; + + case 'youtube': + case 'vimeo': + this.media = utils.createElement('div'); + this.embedId = input.sources[0].src; + break; + + default: + break; + } + + // Inject the new element + this.elements.container.appendChild(this.media); + + // Autoplay the new source? + if (utils.is.boolean(input.autoplay)) { + this.config.autoplay = input.autoplay; + } + + // Set attributes for audio and video + if (this.isHTML5) { + if (this.config.crossorigin) { + this.media.setAttribute('crossorigin', ''); + } + if (this.config.autoplay) { + this.media.setAttribute('autoplay', ''); + } + if ('poster' in input) { + this.media.setAttribute('poster', input.poster); + } + if (this.config.loop.active) { + this.media.setAttribute('loop', ''); + } + if (this.config.muted) { + this.media.setAttribute('muted', ''); + } + if (this.config.inline) { + this.media.setAttribute('playsinline', ''); + } + } + + // Restore class hooks + utils.toggleClass( + this.elements.container, + this.config.classNames.captions.active, + this.supported.ui && this.captions.enabled + ); + + ui.addStyleHook.call(this); + + // Set new sources for html5 + if (this.isHTML5) { + source.insertElements.call(this, 'source', input.sources); + } + + // Set video title + this.config.title = input.title; + + // Set up from scratch + media.setup.call(this); + + // HTML5 stuff + if (this.isHTML5) { + // Setup captions + if ('tracks' in input) { + source.insertElements.call(this, 'track', input.tracks); + } + + // Load HTML5 sources + this.media.load(); + } + + // If HTML5 or embed but not fully supported, setupInterface and call ready now + if (this.isHTML5 || (this.isEmbed && !this.supported.ui)) { + // Setup interface + ui.build.call(this); + } + }, + true + ); + }, +}; + +export default source; |